From e5ec5ffa8b5d68c50ebab70654e3b44bee40729e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 29 Dec 2021 18:23:59 +0100 Subject: [PATCH] wanpipe-3.3.14.tgz --- .Makefile.swp | Bin 0 -> 16384 bytes ChangeLog.beta | 45 + Makefile | 5 +- Setup | 491 ++- api/Makefile | 16 +- api/adccp/Makefile | 6 +- api/aft/Makefile | 8 +- api/asyhdlc/Makefile | 3 +- api/bisync/Makefile | 4 +- api/bisync_strm/Makefile | 4 +- api/bitstrm/Makefile | 4 +- api/bitstrm/datascope/Makefile | 4 +- api/bitstrm/te1/Makefile | 3 +- api/chdlc/Makefile | 3 +- api/fr/Makefile | 3 +- api/libsangoma/.svn/all-wcprops | 78 +- api/libsangoma/.svn/entries | 297 +- .../.svn/text-base/Makefile.am.svn-base | 12 +- .../.svn/text-base/Makefile.in.svn-base | 39 +- .../.svn/text-base/Makefile.svn-base | 679 ---- .../.svn/text-base/doxygen.config.svn-base | 1252 +++++++ .../.svn/text-base/libhpsangoma.c.svn-base | 442 +++ .../.svn/text-base/libhpsangoma.h.svn-base | 324 ++ .../text-base/libhpsangoma_priv.c.svn-base | 403 +++ .../text-base/libhpsangoma_priv.h.svn-base | 118 + .../.svn/text-base/libsangoma.c.svn-base | 13 +- .../.svn/text-base/svn-commit.2.tmp.svn-base | 5 - .../.svn/text-base/svn-commit.tmp.svn-base | 5 - api/libsangoma/.svn/tmp/tempfile.7.tmp | 1261 +++++++ .../tmp/tempfile.8.tmp} | 53 +- api/libsangoma/Makefile.am | 12 +- api/libsangoma/Makefile.in | 39 +- api/libsangoma/Makefile.r11 | 679 ---- api/libsangoma/Makefile.r9 | 679 ---- api/libsangoma/docs/.svn/all-wcprops | 5 + api/libsangoma/docs/.svn/entries | 31 + api/libsangoma/docs/.svn/format | 1 + api/libsangoma/docs/doxygen/.svn/all-wcprops | 5 + api/libsangoma/docs/doxygen/.svn/entries | 31 + api/libsangoma/docs/doxygen/.svn/format | 1 + .../docs/doxygen/html/.svn/all-wcprops | 239 ++ api/libsangoma/docs/doxygen/html/.svn/entries | 504 +++ api/libsangoma/docs/doxygen/html/.svn/format | 1 + .../html/.svn/prop-base/doxygen.png.svn-base} | 0 .../.svn/prop-base/graph_legend.png.svn-base | 5 + ...oma__hptdm__chan__coll__graph.png.svn-base | 5 + ...hptdm__chan__map__coll__graph.png.svn-base | 5 + ...oma__hptdm__span__coll__graph.png.svn-base | 5 + .../html/.svn/prop-base/tab_b.gif.svn-base | 5 + .../html/.svn/prop-base/tab_l.gif.svn-base | 5 + .../html/.svn/prop-base/tab_r.gif.svn-base | 5 + .../.svn/text-base/annotated.html.svn-base | 31 + .../html/.svn/text-base/doxygen.css.svn-base | 358 ++ .../html/.svn/text-base/doxygen.png.svn-base | Bin 0 -> 1281 bytes .../html/.svn/text-base/files.html.svn-base | 24 + .../.svn/text-base/functions.html.svn-base | 120 + .../text-base/functions_vars.html.svn-base | 120 + .../.svn/text-base/graph_legend.dot.svn-base | 22 + .../.svn/text-base/graph_legend.html.svn-base | 80 + .../.svn/text-base/graph_legend.png.svn-base | Bin 0 -> 21232 bytes .../html/.svn/text-base/index.html.svn-base | 20 + .../libhpsangoma_8c-source.html.svn-base | 412 +++ .../libhpsangoma_8h-source.html.svn-base | 223 ++ ...libhpsangoma__priv_8c-source.html.svn-base | 362 ++ ...libhpsangoma__priv_8h-source.html.svn-base | 77 + ...structhp__tdm__chunk-members.html.svn-base | 28 + .../structhp__tdm__chunk.html.svn-base | 116 + ...sangoma__hptdm__chan-members.html.svn-base | 34 + .../structsangoma__hptdm__chan.html.svn-base | 233 ++ ...oma__hptdm__chan__coll__graph.map.svn-base | 3 + ...oma__hptdm__chan__coll__graph.md5.svn-base | 1 + ...oma__hptdm__chan__coll__graph.png.svn-base | Bin 0 -> 8480 bytes ...ma__hptdm__chan__map-members.html.svn-base | 26 + ...uctsangoma__hptdm__chan__map.html.svn-base | 86 + ...hptdm__chan__map__coll__graph.map.svn-base | 4 + ...hptdm__chan__map__coll__graph.md5.svn-base | 1 + ...hptdm__chan__map__coll__graph.png.svn-base | Bin 0 -> 11233 bytes ...ma__hptdm__chan__reg-members.html.svn-base | 27 + ...uctsangoma__hptdm__chan__reg.html.svn-base | 93 + ...sangoma__hptdm__span-members.html.svn-base | 49 + .../structsangoma__hptdm__span.html.svn-base | 570 ++++ ...oma__hptdm__span__coll__graph.map.svn-base | 6 + ...oma__hptdm__span__coll__graph.md5.svn-base | 1 + ...oma__hptdm__span__coll__graph.png.svn-base | Bin 0 -> 17583 bytes ...ma__hptdm__span__reg-members.html.svn-base | 27 + ...uctsangoma__hptdm__span__reg.html.svn-base | 93 + .../html/.svn/text-base/tab_b.gif.svn-base | Bin 0 -> 35 bytes .../html/.svn/text-base/tab_l.gif.svn-base | Bin 0 -> 706 bytes .../html/.svn/text-base/tab_r.gif.svn-base | Bin 0 -> 2585 bytes .../html/.svn/text-base/tabs.css.svn-base | 102 + .../docs/doxygen/html/annotated.html | 31 + api/libsangoma/docs/doxygen/html/doxygen.css | 358 ++ api/libsangoma/docs/doxygen/html/doxygen.png | Bin 0 -> 1281 bytes api/libsangoma/docs/doxygen/html/files.html | 24 + .../docs/doxygen/html/functions.html | 120 + .../docs/doxygen/html/functions_vars.html | 120 + .../docs/doxygen/html/graph_legend.dot | 22 + .../docs/doxygen/html/graph_legend.html | 80 + .../docs/doxygen/html/graph_legend.png | Bin 0 -> 21232 bytes api/libsangoma/docs/doxygen/html/index.html | 20 + .../doxygen/html/libhpsangoma_8c-source.html | 412 +++ .../doxygen/html/libhpsangoma_8h-source.html | 223 ++ .../html/libhpsangoma__priv_8c-source.html | 362 ++ .../html/libhpsangoma__priv_8h-source.html | 77 + .../html/structhp__tdm__chunk-members.html | 28 + .../doxygen/html/structhp__tdm__chunk.html | 116 + .../structsangoma__hptdm__chan-members.html | 34 + .../html/structsangoma__hptdm__chan.html | 233 ++ ...tructsangoma__hptdm__chan__coll__graph.map | 3 + ...tructsangoma__hptdm__chan__coll__graph.md5 | 1 + ...tructsangoma__hptdm__chan__coll__graph.png | Bin 0 -> 8480 bytes ...ructsangoma__hptdm__chan__map-members.html | 26 + .../html/structsangoma__hptdm__chan__map.html | 86 + ...sangoma__hptdm__chan__map__coll__graph.map | 4 + ...sangoma__hptdm__chan__map__coll__graph.md5 | 1 + ...sangoma__hptdm__chan__map__coll__graph.png | Bin 0 -> 11233 bytes ...ructsangoma__hptdm__chan__reg-members.html | 27 + .../html/structsangoma__hptdm__chan__reg.html | 93 + .../structsangoma__hptdm__span-members.html | 49 + .../html/structsangoma__hptdm__span.html | 570 ++++ ...tructsangoma__hptdm__span__coll__graph.map | 6 + ...tructsangoma__hptdm__span__coll__graph.md5 | 1 + ...tructsangoma__hptdm__span__coll__graph.png | Bin 0 -> 17583 bytes ...ructsangoma__hptdm__span__reg-members.html | 27 + .../html/structsangoma__hptdm__span__reg.html | 93 + api/libsangoma/docs/doxygen/html/tab_b.gif | Bin 0 -> 35 bytes api/libsangoma/docs/doxygen/html/tab_l.gif | Bin 0 -> 706 bytes api/libsangoma/docs/doxygen/html/tab_r.gif | Bin 0 -> 2585 bytes api/libsangoma/docs/doxygen/html/tabs.css | 102 + api/libsangoma/doxygen.config | 1252 +++++++ api/libsangoma/examples/.svn/all-wcprops | 34 +- api/libsangoma/examples/.svn/entries | 71 +- .../examples/hptdm_api/.svn/all-wcprops | 35 + .../examples/hptdm_api/.svn/entries | 92 + api/libsangoma/examples/hptdm_api/.svn/format | 1 + .../.svn/prop-base/rebuild.sh.svn-base | 5 + .../.svn/text-base/Makefile.svn-base | 34 + .../.svn/text-base/aft_tdm_hp.c.svn-base | 484 +++ .../.svn/text-base/aft_tdm_hp.h.svn-base | 127 + .../.svn/text-base/doxygen.config.svn-base | 1252 +++++++ .../.svn/text-base/rebuild.sh.svn-base | 13 + api/libsangoma/examples/hptdm_api/Makefile | 34 + .../examples/hptdm_api/aft_tdm_hp.c | 484 +++ .../examples/hptdm_api/aft_tdm_hp.c~ | 468 +++ .../examples/hptdm_api/aft_tdm_hp.h | 127 + .../examples/hptdm_api/docs/.svn/all-wcprops | 5 + .../examples/hptdm_api/docs/.svn/entries | 31 + .../examples/hptdm_api/docs/.svn/format | 1 + .../hptdm_api/docs/doxygen/.svn/all-wcprops | 5 + .../hptdm_api/docs/doxygen/.svn/entries | 31 + .../hptdm_api/docs/doxygen/.svn/format | 1 + .../docs/doxygen/html/.svn/all-wcprops | 125 + .../hptdm_api/docs/doxygen/html/.svn/entries | 273 ++ .../hptdm_api/docs/doxygen/html/.svn/format | 1 + .../html/.svn/prop-base/doxygen.png.svn-base | 5 + .../.svn/prop-base/graph_legend.png.svn-base | 5 + .../html/.svn/prop-base/tab_b.gif.svn-base | 5 + .../html/.svn/prop-base/tab_l.gif.svn-base | 5 + .../html/.svn/prop-base/tab_r.gif.svn-base | 5 + .../aft__tdm__hp_8c-source.html.svn-base | 457 +++ .../aft__tdm__hp_8h-source.html.svn-base | 118 + .../.svn/text-base/annotated.html.svn-base | 27 + .../html/.svn/text-base/doxygen.css.svn-base | 358 ++ .../html/.svn/text-base/doxygen.png.svn-base | Bin 0 -> 1281 bytes .../html/.svn/text-base/files.html.svn-base | 22 + .../.svn/text-base/functions.html.svn-base | 39 + .../text-base/functions_vars.html.svn-base | 39 + .../.svn/text-base/graph_legend.dot.svn-base | 22 + .../.svn/text-base/graph_legend.html.svn-base | 80 + .../.svn/text-base/graph_legend.png.svn-base | Bin 0 -> 21232 bytes .../html/.svn/text-base/index.html.svn-base | 20 + .../structchan__idx-members.html.svn-base | 29 + .../text-base/structchan__idx.html.svn-base | 132 + .../structspan__idx-members.html.svn-base | 28 + .../text-base/structspan__idx.html.svn-base | 113 + .../html/.svn/text-base/tab_b.gif.svn-base | Bin 0 -> 35 bytes .../html/.svn/text-base/tab_l.gif.svn-base | Bin 0 -> 706 bytes .../html/.svn/text-base/tab_r.gif.svn-base | Bin 0 -> 2585 bytes .../html/.svn/text-base/tabs.css.svn-base | 102 + .../doxygen/html/aft__tdm__hp_8c-source.html | 457 +++ .../doxygen/html/aft__tdm__hp_8h-source.html | 118 + .../docs/doxygen/html/annotated.html | 27 + .../hptdm_api/docs/doxygen/html/doxygen.css | 358 ++ .../hptdm_api/docs/doxygen/html/doxygen.png | Bin 0 -> 1281 bytes .../hptdm_api/docs/doxygen/html/files.html | 22 + .../docs/doxygen/html/functions.html | 39 + .../docs/doxygen/html/functions_vars.html | 39 + .../docs/doxygen/html/graph_legend.dot | 22 + .../docs/doxygen/html/graph_legend.html | 80 + .../docs/doxygen/html/graph_legend.png | Bin 0 -> 21232 bytes .../hptdm_api/docs/doxygen/html/index.html | 20 + .../doxygen/html/structchan__idx-members.html | 29 + .../docs/doxygen/html/structchan__idx.html | 132 + .../doxygen/html/structspan__idx-members.html | 28 + .../docs/doxygen/html/structspan__idx.html | 113 + .../hptdm_api/docs/doxygen/html/tab_b.gif | Bin 0 -> 35 bytes .../hptdm_api/docs/doxygen/html/tab_l.gif | Bin 0 -> 706 bytes .../hptdm_api/docs/doxygen/html/tab_r.gif | Bin 0 -> 2585 bytes .../hptdm_api/docs/doxygen/html/tabs.css | 102 + .../examples/hptdm_api/doxygen.config | 1252 +++++++ api/libsangoma/examples/hptdm_api/rebuild.sh | 13 + .../examples/priserver/.svn/all-wcprops | 35 + .../examples/priserver/.svn/entries | 89 + api/libsangoma/examples/priserver/.svn/format | 1 + .../.svn/prop-base/sound.raw.svn-base | 5 + .../.svn/text-base/Makefile.svn-base | 0 .../.svn/text-base/README.svn-base | 0 .../.svn/text-base/librc.svn-base | 0 .../.svn/text-base/priserver.c.svn-base | 0 .../.svn/text-base/sound.raw.svn-base | Bin .../examples/{ => priserver}/Makefile | 0 .../examples/{ => priserver}/README | 0 api/libsangoma/examples/{ => priserver}/librc | 0 .../examples/{ => priserver}/priserver.c | 0 .../examples/{ => priserver}/sound.raw | Bin api/libsangoma/libhpsangoma.c | 442 +++ api/libsangoma/libhpsangoma.h | 324 ++ api/libsangoma/libhpsangoma_priv.c | 403 +++ api/libsangoma/libhpsangoma_priv.h | 118 + api/libsangoma/libsangoma.c | 9 +- api/libsangoma/svn-commit.2.tmp | 5 - api/libsangoma/svn-commit.tmp | 5 - api/mpapi/x25/Makefile | 4 +- api/pos/Makefile | 4 +- api/sdlc/Makefile | 4 +- api/tdmapi/Makefile | 6 - api/x25/Makefile | 8 +- api/x25/pthread/Makefile | 3 +- api/xdlc/Makefile | 4 +- deb_control/wanpipe.deb | 2 +- patches/kdrivers/diff | 1013 ------ patches/kdrivers/include/sdla_adsl.h | 6 +- patches/kdrivers/include/sdla_aft_te1.h | 17 +- patches/kdrivers/include/sdla_aft_te1.h~ | 1792 ++++++++++ patches/kdrivers/include/sdla_aft_te3.h | 14 +- patches/kdrivers/include/sdla_bscstrm.h | 7 +- patches/kdrivers/include/sdla_front_end.h | 8 + patches/kdrivers/include/sdla_remora.h | 1 + patches/kdrivers/include/sdla_sdlc.h | 5 +- patches/kdrivers/include/sdla_te1.h | 36 +- patches/kdrivers/include/sdla_te1_pmc.h | 2 +- patches/kdrivers/include/sdla_te3.h | 12 +- patches/kdrivers/include/sdladrv.h | 15 +- patches/kdrivers/include/sdlapci.h | 2 +- .../kdrivers/include/wanpipe_abstr_types.h | 1 + patches/kdrivers/include/wanpipe_cfg.h | 465 +-- patches/kdrivers/include/wanpipe_cfg_adsl.h | 76 + patches/kdrivers/include/wanpipe_cfg_atm.h | 63 + patches/kdrivers/include/wanpipe_cfg_def.h | 220 ++ patches/kdrivers/include/wanpipe_cfg_fr.h | 70 + patches/kdrivers/include/wanpipe_cfg_hdlc.h | 25 + patches/kdrivers/include/wanpipe_cfg_lip.h | 49 + patches/kdrivers/include/wanpipe_cfg_sppp.h | 52 + patches/kdrivers/include/wanpipe_common.h | 101 +- patches/kdrivers/include/wanpipe_defines.h | 21 +- .../kdrivers/include/wanpipe_lip_atm_iface.h | 2 +- patches/kdrivers/include/wanpipe_version.h | 2 +- patches/kdrivers/include/zapcompat.h | 147 + patches/kdrivers/include/zapcompat_user.h | 79 + .../src/lip/lip_hdlc/wanpipe_hdlc_eng.c | 4 +- .../src/lip/lip_hdlc/wanpipe_hdlc_iface.c | 6 +- .../src/lip/lip_hdlc/wanpipe_lip_hdlc.h | 4 +- patches/kdrivers/src/lip/wanpipe_lip_bh.c | 5 +- patches/kdrivers/src/lip/wanpipe_lip_iface.c | 155 + patches/kdrivers/src/lip/wanpipe_lip_netdev.c | 7 +- patches/kdrivers/src/net/.aft_a104.c.swp | Bin 0 -> 16384 bytes patches/kdrivers/src/net/.sdla_aft_te1.c.swp | Bin 0 -> 16384 bytes .../kdrivers/src/net/.sdla_remora_tdmv.c.swp | Bin 0 -> 16384 bytes patches/kdrivers/src/net/Makefile | 2 +- patches/kdrivers/src/net/Module.symvers | 56 - patches/kdrivers/src/net/aft_analog.c | 7 +- patches/kdrivers/src/net/diff | 1688 +--------- patches/kdrivers/src/net/sdla_56k.c | 37 +- patches/kdrivers/src/net/sdla_8te1.c | 105 +- patches/kdrivers/src/net/sdla_aft_te1.c | 258 +- patches/kdrivers/src/net/sdla_aft_te3.c | 256 +- patches/kdrivers/src/net/sdla_asyhdlc.c | 8 +- patches/kdrivers/src/net/sdla_atm.c | 2 +- patches/kdrivers/src/net/sdla_bitstrm.c | 2 +- patches/kdrivers/src/net/sdla_bri_tdmv.c | 32 +- patches/kdrivers/src/net/sdla_fr.c | 2 +- patches/kdrivers/src/net/sdla_mp_fr.c | 2 +- patches/kdrivers/src/net/sdla_ppp.c | 2 +- patches/kdrivers/src/net/sdla_remora.c | 90 +- patches/kdrivers/src/net/sdla_remora_tdmv.c | 110 +- .../kdrivers/src/net/sdla_remora_tdmv.c.orig | 1960 +++++++++++ patches/kdrivers/src/net/sdla_tdmv.c | 78 +- patches/kdrivers/src/net/sdla_tdmv_dummy.c | 13 +- patches/kdrivers/src/net/sdla_te1.c | 73 +- patches/kdrivers/src/net/sdla_te3.c | 300 +- patches/kdrivers/src/net/sdla_xilinx.c | 6 +- patches/kdrivers/src/net/sdladrv.c | 53 +- patches/kdrivers/src/net/sdladrv_utils.c | 168 +- patches/kdrivers/src/net/wanpipe_abstr.c | 5 +- .../kdrivers/src/net/wanpipe_linux_iface.c | 3 +- patches/kdrivers/src/net/wanpipe_multppp.c | 6 +- patches/kdrivers/src/net/wanpipe_syncppp.c | 4 +- patches/kdrivers/src/net/wanpipe_utils.c | 2 +- patches/kdrivers/src/sangoma_xmtp2km.tgz | Bin 71235 -> 0 bytes patches/kdrivers/src/wan_aften/wan_aften.c | 3 + .../kdrivers/src/wan_aften/wan_aften_src.o | Bin 225364 -> 225604 bytes .../src/wan_aften/wanpipe_linux_iface.o | Bin 136156 -> 136156 bytes .../src/wanrouter/af_wanpipe_datascope.o | Bin 170916 -> 170892 bytes .../kdrivers/src/wanrouter/af_wanpipe_src.o | Bin 188344 -> 188532 bytes patches/kdrivers/src/wanrouter/waniface.o | Bin 148463 -> 148531 bytes patches/kdrivers/src/wanrouter/wanmain.o | Bin 242651 -> 243645 bytes patches/kdrivers/src/wanrouter/wanproc.o | Bin 225072 -> 225508 bytes patches/kdrivers/wanec/Module.symvers | 0 .../wanec/OCT612x-01.01.01/include/octtype.h | 11 +- .../oct6100api/oct6100_api/oct6100_user.c | 4 +- patches/kdrivers/wanec/wanec.mod.c | 6 +- patches/kdrivers/wanec/wanec_cmd.c | 35 +- patches/kdrivers/wanec/wanec_iface.c | 181 + patches/kdrivers/wanec/wanec_iface.h | 6 +- patches/kdrivers/wanec/wanec_iface_api.h | 64 +- rpmspec/wanpipe-mod.spec | 47 +- rpmspec/wanpipe-util.spec | 47 +- rpmspec/wanpipe.spec | 47 +- samples/diff | 279 -- samples/wanpipe1.serial_lip_hdlc_mark | 58 + samples/wanrouter | 2 +- scripts/Compile.sh | 2 +- ssmg/sangoma_mgd.trunk/.svn/all-wcprops | 46 +- ssmg/sangoma_mgd.trunk/.svn/entries | 104 +- .../.svn/text-base/Makefile.svn-base | 2 +- ssmg/sangoma_mgd.trunk/Makefile | 2 +- .../chan_woomera.trunk/.svn/all-wcprops | 4 +- .../chan_woomera.trunk/.svn/entries | 18 +- .../.svn/text-base/chan_woomera.c.svn-base | 18 +- .../chan_woomera.trunk/chan_woomera.c | 18 +- .../sangoma_mgd.trunk/chan_woomera.trunk/diff | 171 - util/wan_aftup/A108dm_0100_V33.BIN | Bin 402936 -> 0 bytes util/wan_aftup/A108dm_0100_V35.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A301_0040_V11.BIN | Bin 0 -> 212392 bytes util/wan_aftup/Makefile | 9 +- util/wan_plxctrl/Makefile | 9 +- util/wan_plxctrl/wan_plxctrl.c | 86 +- util/wancfg/Makefile.Linux | 11 +- util/wancfg/conf_file_writer.h | 2 +- util/wancfg/list_element_sangoma_card.h | 2 +- util/wancfg/wancfg.h | 2 + util/wancfg/zapcompat_user.h | 78 + util/wancfg/zaptel_conf_file_reader.cpp | 2 +- util/wancfg_zaptel/.svn/all-wcprops | 101 + util/wancfg_zaptel/.svn/entries | 232 ++ util/wancfg_zaptel/.svn/format | 1 + .../.svn/prop-base/clean.sh.svn-base | 5 + .../.svn/prop-base/install.sh.svn-base | 5 + .../.svn/prop-base/setup-sangoma.svn-base | 5 + .../.svn/prop-base/uninstall.sh.svn-base | 5 + .../.svn/prop-base/wancfg_dahdi.svn-base | 5 + .../.svn/prop-base/wancfg_hp_tdmapi.svn-base | 5 + .../.svn/prop-base/wancfg_tdmapi.svn-base | 5 + .../.svn/prop-base/wancfg_zaptel.pl.svn-base | 5 + .../.svn/prop-base/wancfg_zaptel.svn-base | 5 + .../.svn/text-base/A10u.pm.svn-base | 559 ++++ .../.svn/text-base/A10x.pm.svn-base | 665 ++++ .../.svn/text-base/A20x.pm.svn-base | 204 ++ .../.svn/text-base/A50x.pm.svn-base | 194 ++ .../.svn/text-base/Card.pm.svn-base | 117 + .../.svn/text-base/Makefile.svn-base | 25 + .../.svn/text-base/clean.sh.svn-base | 4 + .../.svn/text-base/install.sh.svn-base | 38 + .../.svn/text-base/setup-sangoma.svn-base | 5 + .../.svn/text-base/uninstall.sh.svn-base | 13 + .../.svn/text-base/wancfg_dahdi.svn-base | 51 + .../.svn/text-base/wancfg_hp_tdmapi.svn-base | 52 + .../.svn/text-base/wancfg_smg.svn-base | 51 + .../.svn/text-base/wancfg_tdmapi.svn-base | 52 + .../.svn/text-base/wancfg_zaptel.pl.svn-base | 2931 +++++++++++++++++ .../.svn/text-base/wancfg_zaptel.svn-base | 51 + util/wancfg_zaptel/A10u.pm | 93 +- util/wancfg_zaptel/A10x.pm | 167 +- util/wancfg_zaptel/A20x.pm | 39 +- util/wancfg_zaptel/Card.pm | 16 +- util/wancfg_zaptel/install.sh | 2 + util/wancfg_zaptel/templates/.svn/all-wcprops | 125 + util/wancfg_zaptel/templates/.svn/entries | 278 ++ util/wancfg_zaptel/templates/.svn/format | 1 + .../prop-base/wanpipe.tdm_api.a500.svn-base | 5 + .../.svn/text-base/dahdi_cfg_script.svn-base | 29 + .../rc_init_template_freebsd.svn-base | 4 + .../.svn/text-base/smg_bri.conf.svn-base | 148 + .../text-base/smgbri_start_script.svn-base | 24 + .../smgbri_start_script_addon.svn-base | 24 + .../text-base/smgbri_stop_script.svn-base | 2 + .../.svn/text-base/wanpipe.tdm.a100.svn-base | 51 + .../.svn/text-base/wanpipe.tdm.a10u.svn-base | 50 + .../.svn/text-base/wanpipe.tdm.a200.svn-base | 47 + .../text-base/wanpipe.tdm_api.a100.svn-base | 52 + .../text-base/wanpipe.tdm_api.a500.svn-base | 45 + .../wanrouter.rc.template.FreeBSD.svn-base | 34 + .../text-base/wanrouter.rc.template.svn-base | 41 + .../.svn/text-base/woomera.conf.svn-base | 12 + .../.svn/text-base/zapata-auto.conf.svn-base | 7 + .../.svn/text-base/zapata.conf.svn-base | 28 + .../.svn/text-base/zaptel.conf.svn-base | 6 + .../.svn/text-base/zaptel.conf_test.svn-base | 1 + .../zaptel_cfg_script.FreeBSD.svn-base | 6 + .../.svn/text-base/zaptel_cfg_script.svn-base | 29 + util/wancfg_zaptel/templates/dahdi_cfg_script | 29 + .../templates/hp_a100/.svn/all-wcprops | 41 + .../templates/hp_a100/.svn/entries | 100 + .../templates/hp_a100/.svn/format | 1 + .../.svn/text-base/wanpipe.hp.1.svn-base | 20 + .../.svn/text-base/wanpipe.hp.2.svn-base | 1 + .../.svn/text-base/wanpipe.hp.3.svn-base | 1 + .../.svn/text-base/wanpipe.hp.4.svn-base | 23 + .../.svn/text-base/wanpipe.hp.5.svn-base | 7 + .../.svn/text-base/wanpipe.hp.6.svn-base | 4 + .../templates/hp_a100/wanpipe.hp.1 | 20 + .../templates/hp_a100/wanpipe.hp.2 | 1 + .../templates/hp_a100/wanpipe.hp.3 | 1 + .../templates/hp_a100/wanpipe.hp.4 | 23 + .../templates/hp_a100/wanpipe.hp.5 | 7 + .../templates/hp_a100/wanpipe.hp.6 | 4 + .../templates/ss7_a100/.svn/all-wcprops | 47 + .../templates/ss7_a100/.svn/entries | 112 + .../templates/ss7_a100/.svn/format | 1 + .../.svn/text-base/wanpipe.ss7.1.svn-base | 20 + .../.svn/text-base/wanpipe.ss7.2.svn-base | 3 + .../.svn/text-base/wanpipe.ss7.3.svn-base | 2 + .../.svn/text-base/wanpipe.ss7.4.svn-base | 21 + .../.svn/text-base/wanpipe.ss7.5.svn-base | 10 + .../.svn/text-base/wanpipe.ss7.6.svn-base | 9 + .../wanpipe.tdmvoiceapi.a100.svn-base | 52 + .../templates/ss7_a10u/.svn/all-wcprops | 47 + .../templates/ss7_a10u/.svn/entries | 112 + .../templates/ss7_a10u/.svn/format | 1 + .../.svn/text-base/wanpipe.ss7.1.svn-base | 20 + .../.svn/text-base/wanpipe.ss7.2.svn-base | 2 + .../.svn/text-base/wanpipe.ss7.3.svn-base | 3 + .../.svn/text-base/wanpipe.ss7.4.svn-base | 20 + .../.svn/text-base/wanpipe.ss7.5.svn-base | 9 + .../.svn/text-base/wanpipe.ss7.6.svn-base | 9 + .../wanpipe.tdmvoiceapi.a10u.svn-base | 50 + util/wancfg_zaptel/templates/wanpipe.tdm.a10u | 2 +- util/wancfg_zaptel/templates/wanpipe.tdm.a200 | 3 +- util/wancfg_zaptel/templates/zapata.conf | 9 +- util/wancfg_zaptel/templates/zaptel.conf | 7 +- util/wancfg_zaptel/wancfg_dahdi | 51 + util/wancfg_zaptel/wancfg_hp_tdmapi | 52 + util/wancfg_zaptel/wancfg_zaptel.pl | 485 ++- util/wanconfig/wanconfig.c | 2 + util/wanec_apilib/wanec_api.c | 95 +- util/wanec_apilib/wanec_api.h | 4 + util/wanec_client/.Makefile.Linux.swp | Bin 0 -> 12288 bytes util/wanec_client/Makefile.Linux | 3 +- util/wanec_client/wan_ec_arg.l | 2 + util/wanec_client/wan_ec_arg.y | 4 + util/wanec_client/wan_ecmain.c | 13 + util/wanpipemon/Makefile | 7 +- util/wanpipemon/Makefile.Linux | 7 +- util/wanpipemon/aftpipemon.c | 109 +- util/wanpipemon/atmpipemon.c | 16 +- util/wanpipemon/bpipemon.c | 16 +- util/wanpipemon/cpipemon.c | 16 +- util/wanpipemon/fe_lib.c | 259 +- util/wanpipemon/fpipemon.c | 17 +- util/wanpipemon/ppipemon.c | 16 +- util/wanpipemon/ss7pipemon.c | 16 +- util/wanpipemon/wanpipemon.c | 9 +- util/wanpipemon/wanpipemon.h | 12 + util/wanpipemon_legacy/Makefile | 3 +- util/wanpipemon_legacy/aftpipemon.c | 16 +- util/wanpipemon_legacy/atmpipemon.c | 16 +- util/wanpipemon_legacy/bpipemon.c | 16 +- util/wanpipemon_legacy/cpipemon.c | 16 +- util/wanpipemon_legacy/fe_lib.c | 4 +- util/wanpipemon_legacy/fpipemon.c | 16 +- util/wanpipemon_legacy/ppipemon.c | 16 +- util/wanpipemon_legacy/ss7pipemon.c | 16 +- zaptel/zaptel.path | 1 + 473 files changed, 38370 insertions(+), 7221 deletions(-) create mode 100644 .Makefile.swp delete mode 100644 api/libsangoma/.svn/text-base/Makefile.svn-base create mode 100644 api/libsangoma/.svn/text-base/doxygen.config.svn-base create mode 100644 api/libsangoma/.svn/text-base/libhpsangoma.c.svn-base create mode 100644 api/libsangoma/.svn/text-base/libhpsangoma.h.svn-base create mode 100644 api/libsangoma/.svn/text-base/libhpsangoma_priv.c.svn-base create mode 100644 api/libsangoma/.svn/text-base/libhpsangoma_priv.h.svn-base delete mode 100644 api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base delete mode 100644 api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base create mode 100644 api/libsangoma/.svn/tmp/tempfile.7.tmp rename api/libsangoma/{Makefile.mine => .svn/tmp/tempfile.8.tmp} (88%) delete mode 100644 api/libsangoma/Makefile.r11 delete mode 100644 api/libsangoma/Makefile.r9 create mode 100644 api/libsangoma/docs/.svn/all-wcprops create mode 100644 api/libsangoma/docs/.svn/entries create mode 100644 api/libsangoma/docs/.svn/format create mode 100644 api/libsangoma/docs/doxygen/.svn/all-wcprops create mode 100644 api/libsangoma/docs/doxygen/.svn/entries create mode 100644 api/libsangoma/docs/doxygen/.svn/format create mode 100644 api/libsangoma/docs/doxygen/html/.svn/all-wcprops create mode 100644 api/libsangoma/docs/doxygen/html/.svn/entries create mode 100644 api/libsangoma/docs/doxygen/html/.svn/format rename api/libsangoma/{examples/.svn/prop-base/sound.raw.svn-base => docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base} (100%) create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__span__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/annotated.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/files.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/functions.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/index.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8c-source.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8h-source.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8c-source.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8h-source.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.map.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.md5.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.map.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.md5.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__reg-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__reg.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.map.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.md5.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.png.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg-members.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg.html.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/.svn/text-base/tabs.css.svn-base create mode 100644 api/libsangoma/docs/doxygen/html/annotated.html create mode 100644 api/libsangoma/docs/doxygen/html/doxygen.css create mode 100644 api/libsangoma/docs/doxygen/html/doxygen.png create mode 100644 api/libsangoma/docs/doxygen/html/files.html create mode 100644 api/libsangoma/docs/doxygen/html/functions.html create mode 100644 api/libsangoma/docs/doxygen/html/functions_vars.html create mode 100644 api/libsangoma/docs/doxygen/html/graph_legend.dot create mode 100644 api/libsangoma/docs/doxygen/html/graph_legend.html create mode 100644 api/libsangoma/docs/doxygen/html/graph_legend.png create mode 100644 api/libsangoma/docs/doxygen/html/index.html create mode 100644 api/libsangoma/docs/doxygen/html/libhpsangoma_8c-source.html create mode 100644 api/libsangoma/docs/doxygen/html/libhpsangoma_8h-source.html create mode 100644 api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8c-source.html create mode 100644 api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8h-source.html create mode 100644 api/libsangoma/docs/doxygen/html/structhp__tdm__chunk-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structhp__tdm__chunk.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.map create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.md5 create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.png create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.map create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.md5 create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.png create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__reg-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__reg.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.map create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.md5 create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.png create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg-members.html create mode 100644 api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg.html create mode 100644 api/libsangoma/docs/doxygen/html/tab_b.gif create mode 100644 api/libsangoma/docs/doxygen/html/tab_l.gif create mode 100644 api/libsangoma/docs/doxygen/html/tab_r.gif create mode 100644 api/libsangoma/docs/doxygen/html/tabs.css create mode 100644 api/libsangoma/doxygen.config create mode 100644 api/libsangoma/examples/hptdm_api/.svn/all-wcprops create mode 100644 api/libsangoma/examples/hptdm_api/.svn/entries create mode 100644 api/libsangoma/examples/hptdm_api/.svn/format create mode 100644 api/libsangoma/examples/hptdm_api/.svn/prop-base/rebuild.sh.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/.svn/text-base/Makefile.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.c.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.h.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/.svn/text-base/doxygen.config.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/.svn/text-base/rebuild.sh.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/Makefile create mode 100644 api/libsangoma/examples/hptdm_api/aft_tdm_hp.c create mode 100644 api/libsangoma/examples/hptdm_api/aft_tdm_hp.c~ create mode 100644 api/libsangoma/examples/hptdm_api/aft_tdm_hp.h create mode 100644 api/libsangoma/examples/hptdm_api/docs/.svn/all-wcprops create mode 100644 api/libsangoma/examples/hptdm_api/docs/.svn/entries create mode 100644 api/libsangoma/examples/hptdm_api/docs/.svn/format create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/all-wcprops create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/entries create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/format create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/all-wcprops create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/entries create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/format create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8c-source.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8h-source.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/annotated.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/files.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/index.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx-members.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx-members.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx.html.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tabs.css.svn-base create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8c-source.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8h-source.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/annotated.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.css create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.png create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/files.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions_vars.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.dot create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.png create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/index.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx-members.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx-members.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx.html create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_b.gif create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_l.gif create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_r.gif create mode 100644 api/libsangoma/examples/hptdm_api/docs/doxygen/html/tabs.css create mode 100644 api/libsangoma/examples/hptdm_api/doxygen.config create mode 100755 api/libsangoma/examples/hptdm_api/rebuild.sh create mode 100644 api/libsangoma/examples/priserver/.svn/all-wcprops create mode 100644 api/libsangoma/examples/priserver/.svn/entries create mode 100644 api/libsangoma/examples/priserver/.svn/format create mode 100644 api/libsangoma/examples/priserver/.svn/prop-base/sound.raw.svn-base rename api/libsangoma/examples/{ => priserver}/.svn/text-base/Makefile.svn-base (100%) rename api/libsangoma/examples/{ => priserver}/.svn/text-base/README.svn-base (100%) rename api/libsangoma/examples/{ => priserver}/.svn/text-base/librc.svn-base (100%) rename api/libsangoma/examples/{ => priserver}/.svn/text-base/priserver.c.svn-base (100%) rename api/libsangoma/examples/{ => priserver}/.svn/text-base/sound.raw.svn-base (100%) rename api/libsangoma/examples/{ => priserver}/Makefile (100%) rename api/libsangoma/examples/{ => priserver}/README (100%) rename api/libsangoma/examples/{ => priserver}/librc (100%) rename api/libsangoma/examples/{ => priserver}/priserver.c (100%) rename api/libsangoma/examples/{ => priserver}/sound.raw (100%) create mode 100644 api/libsangoma/libhpsangoma.c create mode 100644 api/libsangoma/libhpsangoma.h create mode 100644 api/libsangoma/libhpsangoma_priv.c create mode 100644 api/libsangoma/libhpsangoma_priv.h delete mode 100644 api/libsangoma/svn-commit.2.tmp delete mode 100644 api/libsangoma/svn-commit.tmp delete mode 100644 patches/kdrivers/diff create mode 100644 patches/kdrivers/include/sdla_aft_te1.h~ create mode 100644 patches/kdrivers/include/wanpipe_cfg_adsl.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_atm.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_def.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_fr.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_hdlc.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_lip.h create mode 100644 patches/kdrivers/include/wanpipe_cfg_sppp.h create mode 100644 patches/kdrivers/include/zapcompat.h create mode 100644 patches/kdrivers/include/zapcompat_user.h create mode 100644 patches/kdrivers/src/net/.aft_a104.c.swp create mode 100644 patches/kdrivers/src/net/.sdla_aft_te1.c.swp create mode 100644 patches/kdrivers/src/net/.sdla_remora_tdmv.c.swp delete mode 100644 patches/kdrivers/src/net/Module.symvers create mode 100644 patches/kdrivers/src/net/sdla_remora_tdmv.c.orig delete mode 100644 patches/kdrivers/src/sangoma_xmtp2km.tgz delete mode 100644 patches/kdrivers/wanec/Module.symvers delete mode 100644 samples/diff create mode 100644 samples/wanpipe1.serial_lip_hdlc_mark delete mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/diff delete mode 100644 util/wan_aftup/A108dm_0100_V33.BIN create mode 100644 util/wan_aftup/A108dm_0100_V35.BIN create mode 100644 util/wan_aftup/A301_0040_V11.BIN create mode 100644 util/wancfg/zapcompat_user.h create mode 100644 util/wancfg_zaptel/.svn/all-wcprops create mode 100644 util/wancfg_zaptel/.svn/entries create mode 100644 util/wancfg_zaptel/.svn/format create mode 100644 util/wancfg_zaptel/.svn/prop-base/clean.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/install.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/setup-sangoma.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/uninstall.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/wancfg_dahdi.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/wancfg_hp_tdmapi.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/wancfg_tdmapi.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.pl.svn-base create mode 100644 util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/A10u.pm.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/A10x.pm.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/A20x.pm.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/A50x.pm.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/Card.pm.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/Makefile.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/clean.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/install.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/setup-sangoma.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/uninstall.sh.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_dahdi.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_hp_tdmapi.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_smg.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_tdmapi.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.pl.svn-base create mode 100644 util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/all-wcprops create mode 100644 util/wancfg_zaptel/templates/.svn/entries create mode 100644 util/wancfg_zaptel/templates/.svn/format create mode 100644 util/wancfg_zaptel/templates/.svn/prop-base/wanpipe.tdm_api.a500.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/dahdi_cfg_script.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/rc_init_template_freebsd.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/smg_bri.conf.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script_addon.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/smgbri_stop_script.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a100.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a10u.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a200.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a100.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a500.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.FreeBSD.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/woomera.conf.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zapata-auto.conf.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zapata.conf.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf_test.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.FreeBSD.svn-base create mode 100644 util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.svn-base create mode 100644 util/wancfg_zaptel/templates/dahdi_cfg_script create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/all-wcprops create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/entries create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/format create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.1.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.2.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.3.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.4.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.5.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.6.svn-base create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.1 create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.2 create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.3 create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.4 create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.5 create mode 100644 util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.6 create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/all-wcprops create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/entries create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/format create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.1.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.2.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.3.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.4.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.5.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.6.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.tdmvoiceapi.a100.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/all-wcprops create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/entries create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/format create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.1.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.2.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.3.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.4.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.5.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.6.svn-base create mode 100644 util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.tdmvoiceapi.a10u.svn-base create mode 100755 util/wancfg_zaptel/wancfg_dahdi create mode 100755 util/wancfg_zaptel/wancfg_hp_tdmapi create mode 100644 util/wanec_client/.Makefile.Linux.swp create mode 100644 zaptel/zaptel.path diff --git a/.Makefile.swp b/.Makefile.swp new file mode 100644 index 0000000000000000000000000000000000000000..1e9b3e328085464b11e4918358b2cdd1ec3c05d6 GIT binary patch literal 16384 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 - Beta - 3.3.14 +===================================================================== + +- Enabled Zaptel/DAHDI libss7 MTP2 option + +- Updated TDM API for A200 + Fixes FreeSwitch OpenZAP with TDM API for Analog + +- Bug fix in XMTP2 API + The fifo error could cause xmtp2 buffering to fail + +- wanpipemon utility + Updated T1/E1 Loopback comands + Bug fix on 2.6.25 kernels + +- Driver compile update for Latest + 2.6.26 kernels + +- Update AFT driver to implement new loopback commands + +- Updated for 56K driver + +- Added Asterisk DAHDI Support + +- A200/A400 Analog driver update + Bug fix possible race condition due to front end interrupt. + +- AFT Core Update + Disabled fifo overrun handling in transparent mode. + It does not provide any improvemnt. + XMTP2 API mode could run out of buffers due to overrun errors. + This has now been fixed. + +- Fixed A301 E3 Support + New firmware V11 is needed. + Please upgrade firmware before starting up the card. + To check firmware run: wanrouter hwprobe + + +* Fri Sep 1 2008 Nenad Corbic - Beta - 3.3.13 +===================================================================== + +- This release was never released. + + * Fri Aug 1 2008 Nenad Corbic - Beta - 3.3.12 ===================================================================== diff --git a/Makefile b/Makefile index 60354fe..49e3069 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,7 @@ all_bin_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver clean: clean_util _cleanoldwanpipe $(MAKE) -C $(KDIR) SUBDIRS=$(WAN_DIR) clean @find patches/kdrivers -name '.*.cmd' | xargs rm -f + @find . -name 'Module.symver*' | xargs rm -f #Clean old wanpipe headers from linux include @@ -177,6 +178,7 @@ _checkzap: eval "$(PWD)/patches/sangoma-zaptel-patch.sh $(ZAPDIR)"; \ ZAPDIR_PRIV=$(ZAPDIR); \ ENABLE_WANPIPEMON_ZAP=YES; \ + cp -f $(ZAPDIR)/Module.symvers $(WAN_DIR)/; \ echo ; \ echo "Please recompile and reinstall ZAPTEL after installation"; \ fi @@ -211,7 +213,7 @@ install_kmod: endif #Compile utilities only -all_util: +all_util: install_inc $(MAKE) -C util all EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I $(PWD)/api/libsangoma/include" CC=$(CC) \ PREFIX=$(INSTALLPREFIX) HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" ARCH=$(ARCH) $(MAKE) -C util all_wancfg EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I$(PWD)/api/libsangoma/include" CC=$(CC) \ @@ -264,6 +266,7 @@ install_inc: \rm -rf $(INSTALLPREFIX)/usr/include/wanpipe; \ fi @\mkdir -p $(INSTALLPREFIX)/usr/include/wanpipe + @ln -s $(INSTALLPREFIX)/usr/include/wanpipe/ $(INSTALLPREFIX)/usr/include/wanpipe/linux @\cp -f $(PWD)/patches/kdrivers/include/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ @\cp -rf $(PWD)/patches/kdrivers/wanec/oct6100_api/include/ $(INSTALLPREFIX)/usr/include/wanpipe/oct6100_api @\cp -rf $(PWD)/patches/kdrivers/wanec/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ diff --git a/Setup b/Setup index 42cdf55..660d5f5 100755 --- a/Setup +++ b/Setup @@ -323,6 +323,43 @@ ENDOFTEXT } +welcome_dahdi() +{ + + cat << ENDOFTEXT +${DISTR_NAME} INSTALLATION FOR DAHDI + +You are about to install ${DISTR_NAME} TDM Voice drivers +for Asterisk/Dahdi framework. + +You will be prompted for path to DAHDI source. + +Wanpipe drivers will compile into dahdi WITHOUT any +dahdi patching or need to recompile dahdi modules. + +You must have Linux Kernel Headers along with +full development tools (i.e. GNU C compiler and utilities) +installed in order to be able to install this product. + +If you have previoulsy installed WANPIPE, this release +will overrite/upgrade full release without the need to +uninstall first! + +IMPORTANT: +It is always recommended to say YES to all options +prompted during the install! + +Please visit: http://wiki.sangoma.com for more info. + +ENDOFTEXT + + return +} + + + + + welcome_default() { @@ -374,8 +411,12 @@ welcome() welcome_default elif [ $zaptel_auto_install = "YES" ]; then - - welcome_zaptel + + if [ $dahdi_auto_install = "YES" ]; then + welcome_dahdi + else + welcome_zaptel + fi else welcome_default fi @@ -433,6 +474,7 @@ and configuration/debug utilities have been compiled and installed. 1) Proceed to configure the WANPIPE drivers: Asterisk/Zaptel: /usr/sbin/wancfg_zaptel + Asterisk/Dahdi : /usr/sbin/wancfg_dahdi TDM API : /usr/sbin/wancfg_tdmapi SMG SS7/BRI : /usr/sbin/wancfg_smg WAN Routing/API: /usr/sbin/wancfg @@ -475,6 +517,7 @@ WANPIPE kernel modules: 1) Proceed to configure the WANPIPE drivers: Asterisk/Zaptel: /usr/sbin/wancfg_zaptel + Asterisk/Dahdi : /usr/sbin/wancfg_dahdi SMG SS7 or BRI : /usr/sbin/wancfg_smg TDM API : /usr/sbin/wancfg_tdmapi WAN Routing/API: /usr/sbin/wancfg @@ -1916,6 +1959,7 @@ WANPIPE UTILITIES SETUP WANPIPE utilities are used to: 1) create configuration files: for Zaptel and Asterisk /usr/sbin/wancfg_zaptel #Zaptel and Asterisk + /usr/sbin/wancfg_dahdi #Dahdi and Asterisk /usr/sbin/wancfg_smg #BRI/SS7, Zaptel and Asterisk /usr/sbin/wancfg_tdmapi #TDM API 2) create WANPIPE WAN/IP configuration files. @@ -2021,6 +2065,9 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. WANCFG_DEFS= if [ "$TDM_PROT" = "YES" ]; then WANCFG_DEFS=$WANCFG_DEFS" ENABLE_ZAPTEL_PARSER=YES ZAPINC=$ZAPTEL_SOURCE_DIR" + if [ -d $ZAPTEL_SOURCE_DIR/dahdi ]; then + WANCFG_DEFS=$WANCFG_DEFS" DAHDI_ISSUES=YES" + fi fi eval "make -C wancfg all CC=$CC SYSINC=$SOURCEDIR/include $WANCFG_DEFS >> $CMP_LOG 2>> $CMP_LOG" @@ -2510,7 +2557,9 @@ function build_wanec_module () mkdir tmp fi - + if [ -e $PROD_HOME/$MODSYM.wanrouter ]; then + cat $PROD_HOME/$MODSYM.wanrouter > $MODSYM + fi build_kernel_module wanec "$files" "$EXTRA_FLAGS" if [ $? -ne 0 ]; then return $?; @@ -3431,6 +3480,7 @@ ENDOFTEXT i386*) LD_ELF="-m elf_i386" ;; x86*) LD_ELF="-m elf_i386" + ARCH=i386 ;; ppc*) ;; @@ -3467,6 +3517,10 @@ CFLAGS="$CC -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dli fi check_inode_struct + + if [ "$BRI_MODULE_TEST" = "YES" ]; then + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DBUILD_MOD_TESTER" + fi if [ 1 -eq 1 ]; then echo @@ -3712,9 +3766,22 @@ WANPIPE_OBJS= rm -f sdladrv_src.c ln -s sdladrv.c sdladrv_src.c - build_kernel_module sdladrv "sdladrv_src sdladrv_fe sdladrv_utils" + + SDLADRV_OBJS="sdladrv_src sdladrv_fe sdladrv_utils " + + if [ "$AFT_USB_PROT" = "YES" ]; then + SDLADRV_OBJS=$SDLADRV_OBJS"sdladrv_usb " + fi + + build_kernel_module sdladrv "$SDLADRV_OBJS" + if [ -e $MODSYM ]; then + cp $MODSYM $PROD_HOME/$MODSYM.sdladrv + fi build_kernel_module wanrouter "wanmain wanproc waniface" + if [ -e $MODSYM ]; then + cp $MODSYM $PROD_HOME/$MODSYM.wanrouter + fi AF_EXTRA_FLAGS="-DCONFIG_PRODUCT_WANPIPE_SOCK_DATASCOPE" check_for_af_wanpipe_updates @@ -3722,6 +3789,9 @@ WANPIPE_OBJS= rm -f af_wanpipe_src.c ln -s af_wanpipe.c af_wanpipe_src.c build_kernel_module af_wanpipe "af_wanpipe_src af_wanpipe_datascope" "$AF_EXTRA_FLAGS" + if [ -e $MODSYM ]; then + cp $MODSYM $PROD_HOME/$MODSYM.af_wanpipe + fi echo -n "." @@ -3911,6 +3981,10 @@ WANPIPE_OBJS= \cp $DRIVER_UPDATE_DIR/src/net/sdla_tdmv_dummy.c . WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_remora_tdmv sdla_bri_tdmv sdla_tdmv_dummy " WANPIPE_EXTRA_CFLAGS=$WANPIPE_EXTRA_CFLAGS"-I$ZAPTEL_SOURCE_DIR " + if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + # this is required for some dependencies of kernel.h (dahdi_config.h, ecdis.h etc) + WANPIPE_EXTRA_CFLAGS=$WANPIPE_EXTRA_CFLAGS"-I$ZAPTEL_INSTALL_DIR/drivers/dahdi " + fi fi if [ "$AFT_TE1_PROT" = "YES" ]; then @@ -3921,6 +3995,10 @@ WANPIPE_OBJS= WANPIPE_OBJS=$WANPIPE_OBJS"sdla_bri aft_bri " fi + if [ "$AFT_USB_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"wanpipe_usb sdla_usb_remora sdla_usb_remora_tdmv " + fi + if [ "$AFT_SERIAL_PROT" = "YES" ]; then WANPIPE_OBJS=$WANPIPE_OBJS"sdla_serial " fi @@ -3934,6 +4012,9 @@ WANPIPE_OBJS= rm -f wanpipe_syncppp_src.c ln -s wanpipe_syncppp.c wanpipe_syncppp_src.c build_kernel_module wanpipe_syncppp wanpipe_syncppp_src + if [ -e $MODSYM ]; then + cp $MODSYM $PROD_HOME/$MODSYM.syncppp + fi fi echo -n "." @@ -3972,6 +4053,9 @@ WANPIPE_OBJS= else echo "WAN HWEC module failed to compile!" fi + if [ -e $MODSYM ]; then + cp $MODSYM $PROD_HOME/$MODSYM.wanec + fi cd $home_tmp fi @@ -4204,6 +4288,18 @@ WANPIPE_OBJS= echo -n "Linking Wanpipe Driver and protocols ..." #Link in appropriate protocols as needed. + if [ "$TDM_PROT" = "YES" ]; then + if [ -f $ZAPTEL_SOURCE_DIR/$MODSYM ]; then + cat $ZAPTEL_SOURCE_DIR/$MODSYM >> $MODSYM + fi + fi + if [ -f $PROD_HOME/$MODSYM.wanec ]; then + cat $PROD_HOME/$MODSYM.wanec >> $MODSYM + fi + if [ -f $PROD_HOME/$MODSYM.syncppp ]; then + cat $PROD_HOME/$MODSYM.syncppp >> $MODSYM + fi + WANPIPE_OBJS=$WANPIPE_OBJS"sdlamain wanpipe_tdm_api wanpipe_codec wanpipe_codec_law " build_kernel_module wanpipe "$WANPIPE_OBJS" "$WANPIPE_EXTRA_CFLAGS" "$WANPIPE_BIN_OBJS" @@ -5153,6 +5249,33 @@ echo -n "Please select a protocol option in []: " done } +# set the proper directory for headers depending on +# zaptel/dahdi version +set_zaptel_source_dir() +{ + ZAPTEL_SUPPORT="YES"; + DAHDI_SUPPORT="NO"; + + if [ -f $ZAPTEL_INSTALL_DIR/linux/include/dahdi/kernel.h ]; then + ZAPTEL_INSTALL_DIR="$ZAPTEL_INSTALL_DIR/linux" + fi + + #Check if this is Dahdi + if [ -d $ZAPTEL_INSTALL_DIR/include/dahdi ]; then + # when Dahdi present ZAPTEL_SOURCE_DIR is not really the source dir, but the headers dir + # no harm done, no conflict, just a bit misleading variable name + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/include + DAHDI_SUPPORT="YES" + ZAPTEL_SUPPORT="NO" + #Check if this is post Zaptel-1.4.9 + elif [ -d $ZAPTEL_INSTALL_DIR/kernel ]; then + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/kernel + #Good ol' zaptel + else + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + fi +} + search_and_replace() { local input_file_name=$1 @@ -5179,6 +5302,15 @@ search_and_replace() return $? } + +function main_zap_header_present() +{ + if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ] && [ ! -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + return 0; + fi + return 1; +} + function tdmv_get_zaptel_path () { @@ -5200,22 +5332,20 @@ if [ 0 ]; then [ $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 + set_zaptel_source_dir } fi fi - if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ]; then - echo " Zaptel source not found in $ZAPTEL_SOURCE_DIR" + + main_zap_header_present + if [ $? -eq 0 ]; then + echo " Zaptel/Dahdi 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" + getyn " Press Y to specify another Zaptel/Dahdi source directory, N to exit" if [ $? -ne 0 ]; then exit 1; fi @@ -5230,6 +5360,7 @@ fi return 0; } +# this function seems unused and does not seem to need to be updated for Dahdi function tdmv_apply_zaptel_dchan_patch_old () { local rc @@ -5302,86 +5433,107 @@ function tdmv_apply_zaptel_dchan_patch_old () return $rc } + function tdmv_apply_zaptel_chunk_patch () { lhome=`pwd` TEMP=tmp cd $ZAPTEL_SOURCE_DIR - echo "Applying Zaptel Chunk patch..." + echo "Applying Zaptel/Dahdi Chunk patch..." echo " " - #modify zaptel.h - eval "cat zaptel.h | sed '/^#define ZT_CHUNKSIZE/c\#define ZT_CHUNKSIZE $ZAP_CHUNK' >$TEMP 2>/dev/null" + + filetopatch="zaptel.h" + chunkname="ZT_CHUNKSIZE" + dhname="Zaptel" + isdahdi="no" + if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + filetopatch="kernel.h" + chunkname="DAHDI_CHUNKSIZE" + dhname="Dahdi" + isdahdi="yes" + fi + + #modify zaptel.h or kernel.h + eval "cat $filetopatch | sed '/^#define $chunkname/c\#define $chunkname $ZAP_CHUNK' >$TEMP 2>/dev/null" if [ $? -ne 0 ]; then - echo " Failed to substitute ZT_CHUNKSIZE string in zaptel.h" + echo " Failed to substitute $chunkname string in $filetopatch" exit 1 else - eval "\mv -f $TEMP zaptel.h" + eval "\mv -f $TEMP $filetopatch" if [ $? -ne 0 ]; then - echo " Failed to overwrite existing zaptel.h" + echo " Failed to overwrite existing $filetopatch" exit 1 else - echo " Zaptel patched for chunk size successfully" + echo " $dhname patched for chunk size successfully" zaptel_modified=1 fi fi #remove wct4xxp module from Makefile - eval "cat Makefile |sed 's/wct1xxp wct4xxp wcte11xp/wct1xxp wcte11xp/g'>$TEMP 2>/dev/null " - if [ $? -ne 0 ]; then - echo " Failed to remove wct4xxp from Makefile" - exit 1 - else - eval "\mv -f $TEMP Makefile" - if [ $? -ne 0 ]; then - echo " Failed to overwrite existing Makefile" - exit 1 - else - echo " wct4xxp module removed from Makefile successfully" - zaptel_modified=1 - fi - fi - - 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" - exit 1 - else - eval "\mv -f $TEMP Makefile" - if [ $? -ne 0 ]; then - echo " Failed to overwrite existing Makefile" - exit 1 - else - echo " wct4xxp module removed from Makefile successfully" - zaptel_modified=1 - fi - fi - - if [ -f Makefile.kernel26 ]; then - eval "cat Makefile.kernel26 | sed 's/^obj-m.*+=.*wct4xx.*//g'>$TEMP 2>/dev/null " + if [ $isdahdi = "no" ]; then + eval "cat Makefile |sed 's/wct1xxp wct4xxp wcte11xp/wct1xxp wcte11xp/g'>$TEMP 2>/dev/null " if [ $? -ne 0 ]; then - echo " Failed to remove wct4xxp from Makefile.kernel26" - exit 1 - + echo " Failed to remove wct4xxp from Makefile" + exit 1 else - eval "\mv -f $TEMP Makefile.kernel26" - echo " wct4xxp module removed from Makefile.kernel26 successfully" - zaptel_modified=1 + eval "\mv -f $TEMP Makefile" + if [ $? -ne 0 ]; then + echo " Failed to overwrite existing Makefile" + exit 1 + else + echo " wct4xxp module removed from Makefile successfully" + zaptel_modified=1 + fi fi fi - # for zaptel-1.2.26 or later - if [ -f Kbuild ]; then - eval "cat Kbuild | sed 's/^obj-m.*+=.*wct4xx.*//g'>$TEMP 2>/dev/null " - if [ $? -ne 0 ]; then - echo " Failed to remove wct4xxp from Kbuild" - exit 1 + cd $ZAPTEL_INSTALL_DIR + if [ $isdahdi = "no" ]; then + eval "cat Makefile |sed 's/^SUBDIR_MODULES:=.*//g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Makefile" + exit 1 + else + eval "\mv -f $TEMP Makefile" + if [ $? -ne 0 ]; then + echo " Failed to overwrite existing Makefile" + exit 1 + else + echo " wct4xxp module removed from Makefile successfully" + zaptel_modified=1 + fi + fi - else - eval "\mv -f $TEMP Kbuild" - echo " wct4xxp module removed from Kbuild successfully" - zaptel_modified=1 - fi - fi + if [ -f Makefile.kernel26 ]; then + eval "cat Makefile.kernel26 | sed 's/^obj-m.*+=.*wct4xx.*//g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Makefile.kernel26" + exit 1 + + else + eval "\mv -f $TEMP Makefile.kernel26" + echo " wct4xxp module removed from Makefile.kernel26 successfully" + zaptel_modified=1 + fi + fi + + fi # end if $isdahdi = "no" + + if [ $isdahdi = "yes" ]; then + cd drivers/dahdi + fi + # for zaptel-1.2.26 or later (including Dahdi) + if [ -f Kbuild ]; then + eval "cat Kbuild | sed 's/^obj-m.*+=.*wct4xx.*//g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Kbuild" + exit 1 + + else + eval "\mv -f $TEMP Kbuild" + echo " wct4xxp module removed from Kbuild successfully" + zaptel_modified=1 + fi + fi cd $lhome return 0; @@ -5390,6 +5542,12 @@ function tdmv_apply_zaptel_chunk_patch () { function tdmv_apply_zaptel_echo_debug_patch () { local rc + + if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + echo "Error: Patching for echo debugging not supported for Dahdi yet" + return 1; + fi + if [ ! -e $PROD_HOME/zaptel ]; then echo "Error: Zaptel Patch Directory Not Found!" return 1; @@ -5469,6 +5627,11 @@ function tdmv_apply_zaptel_edac_patch () { local rc + if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + echo "Error: TDMV Echo Detection and Control not supported for Dahdi yet" + return 1; + fi + if [ ! -e $PROD_HOME/edac ]; then echo "Error: Zaptel Patch Directory Not Found!" return 1; @@ -5741,6 +5904,15 @@ function find_zap_dirs_invalid () find_zap_dirs "$1" } +function is_valid_zap_dir() +{ + # one more !%*?@ change from Digium and we need an array here :-) + if [ -f $1/zaptel.h ] || [ -f $1/kernel/zaptel.h ] || [ -f $1/include/dahdi/kernel.h ] || [ -f $1/linux/include/dahdi/kernel.h ]; then + return 1; + fi + return 0; +} + function find_zap_dirs () { local cnt @@ -5754,14 +5926,18 @@ function find_zap_dirs () echo - echo "Looking for zaptel directory in /usr/src ..." + echo "Looking for zaptel/dahdi 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 - + dahdidirs=`find /usr/src -maxdepth 2 -name 'dahdi*' | xargs ` + if [ -d "/usr/src/dahdi" ]; then + zapdirs="/usr/src/dahdi $zapdirs" + fi + zapdirs="$dahdidirs $zapdirs" fi unset zapdir_array; @@ -5777,7 +5953,8 @@ function find_zap_dirs () continue fi - if [ ! -f $dir/zaptel.h ] && [ ! -f $dir/kernel/zaptel.h ]; then + is_valid_zap_dir $dir + if [ $? -eq 0 ]; then continue; fi @@ -5794,8 +5971,8 @@ function find_zap_dirs () if [ $cnt -eq 1 ]; then echo - echo "No zaptel dirs found in /usr/src " - echo "Please use option \"m\" to enter zaptel path" + echo "No zaptel/dahdi dirs found in /usr/src " + echo "Please use option \"m\" to enter zaptel/dahdi path" echo fi echo "------------------------------------------ " @@ -5806,7 +5983,8 @@ function find_zap_dirs () continue fi - if [ ! -f $dir/zaptel.h ] && [ ! -f $dir/kernel/zaptel.h ]; then + is_valid_zap_dir $dir + if [ $? -eq 0 ]; then continue; fi @@ -5857,16 +6035,11 @@ function find_zap_dirs () find_zap_dirs_invalid "$zapdirs" fi - #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_SOURCE_DIR=$ZAPTEL_INSTALL_DIR - fi - - if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ]; then + set_zaptel_source_dir + main_zap_header_present + if [ $? -eq 0 ]; then echo - echo "Error: zaptel.h not found in $ZAPTEL_SOURCE_DIR" + echo "Error: zaptel.h or dahdi/kernel.h not found in $ZAPTEL_SOURCE_DIR" echo echo zapdir_manual=0 @@ -6111,6 +6284,9 @@ function enable_protocols () if [ "$PROTOCOL" = "DEF" ]; then PROTOCOL=$DEFAULT_PROTOCOLS fi + if [ "$PROTOCOL" = "ALL" ]; then + PROTOCOL="$DEFAULT_PROTOCOLS $API_PROTOCOLS" + fi echo "$PROTOCOL" | grep "BRI" > /dev/null if [ $? -eq 0 ]; then @@ -6360,10 +6536,13 @@ ENDOFTEXT if [ $AFT_TE1_PROT != YES ]; then echo "Enabling the AFT TE1 Support" 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 " + + #PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_USB " fi AFT_TE1_PROT=YES AFT_BRI_PROT=YES AFT_SERIAL_PROT=YES + #AFT_USB_PROT=YES PROT_MATCH=YES fi @@ -6405,21 +6584,39 @@ ENDOFTEXT ZAPTEL_NAME=zaptel.ko fi - if [ -e $ZAP_MOD_DIR/zaptel/$ZAPTEL_NAME ] && [ -e $ZAP_MOD_DIR/misc/$ZAPTEL_NAME ]; then + zaplikeinstalls=0 + if [ -e $ZAP_MOD_DIR/zaptel/$ZAPTEL_NAME ]; then + zaplikeinstalls=$((zaplikeinstalls+1)) + fi + + if [ -e $ZAP_MOD_DIR/misc/$ZAPTEL_NAME ]; then + zaplikeinstalls=$((zaplikeinstalls+1)) + fi + + # Dahdi drops support for kernel 2.4, no need to check .o vs .ko + if [ -e $ZAP_MOD_DIR/dahdi/dahdi.ko ]; then + zaplikeinstalls=$((zaplikeinstalls+1)) + fi + + if [ $zaplikeinstalls -gt 1 ]; then + echo + echo echo echo "-------------------------------------------------------------" - echo "CRITICAL WARNING: Multiple ZAPTEL Installations Found" + echo "CRITICAL WARNING: Multiple ZAPTEL/DAHDI Installations Found" echo - echo "./Setup has found MULTIPLE ZAPTEL driver installations in:" + echo "./Setup has found MULTIPLE ZAPTEL/DAHDI driver installations" + echo " in 2 or more of this locations:" echo " $ZAP_MOD_DIR/zaptel and" echo " $ZAP_MOD_DIR/misc directory." + echo " $ZAP_MOD_DIR/dahdi directory." echo echo " The ZAPTEL drivers in $ZAP_MOD_DIR/zaptel are OLD." echo echo " This is illegal, and CAN cause Wanpipe to CRASH." echo echo " Please solve this PROBLEM by removing OLD ZAPTEL" - echo " kerenl modules before installing WANPIPE. " + echo " kernel modules before installing WANPIPE. " echo echo " eg: rm -rf $ZAP_MOD_DIR/zaptel" echo " depmod -a" @@ -6456,6 +6653,17 @@ ENDOFTEXT PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL " fi fi + + # if this is Dahdi, no need to check, already include hdlc_hard_xmit + if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then + echo " " + echo "Dahdi HW HDLC Support Detected: Enabling DCHAN Feature" + echo "Native Dahdi HW HDLC Support Detected - No patch required" + echo "Dahdi source unmodified" + echo " " + TDM_DCHAN="(DCHAN)" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL -DDAHDI_ISSUES" + fi #Check if dchan patch is already enabled if [ "$TDM_DCHAN" = "" ]; then @@ -6508,7 +6716,7 @@ ENDOFTEXT #################################################################### if [ $ENABLE_ECHO_DEBUG -eq 1 ]; then - getyn "Compile Echo Debugging Support for Zaptel ? " + getyn "Compile Echo Debugging Support for Zaptel (not supported for Dahdi yet) ? " if [ $? -eq 0 ]; then tdmv_apply_zaptel_echo_debug_patch if [ $? -eq 0 ]; then @@ -6529,7 +6737,7 @@ ENDOFTEXT if [ $ENABLE_EDAC -gt 0 ] && [ "$ECHO_MASTER_PROT" = "NO" ]; then echo - getyn "Compile TDMV Echo Detection and Control (EDAC) Support (y/n)? " + getyn "Compile TDMV Echo Detection and Control (EDAC) Support (No Dahdi support yet) (y/n)? " if [ $? -eq 0 ]; then echo tdmv_apply_zaptel_edac_patch @@ -6676,6 +6884,7 @@ CHDLC_PROT=NO X25_PROT=NO AFT_TE1_PROT=NO AFT_BRI_PROT=NO +AFT_USB_PROT=NO AFT_SERIAL_PROT=NO AFT_TE3_PROT=NO SSMG=NO @@ -6915,7 +7124,7 @@ ENDOFTEXT } ####### MAIN ################################################################# -# set -x +#set -x PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin @@ -6924,7 +7133,7 @@ KERNEL_UNAME=`uname -r` PKG_NAME=wanpipe DISTR_NAME="WANPIPE" PROD=wanrouter -PROD_VER=3.3.12 +PROD_VER=3.3.14 PROD_HOME=`pwd` META_CONF=$PROD_HOME/$PROD.rc WAN_INTR_DIR=$PROD_HOME/interfaces @@ -6953,6 +7162,7 @@ ENABLE_EDAC=0 ENABLE_ECHO_DEBUG=0 ZAPTEL_PATH_OP="NO" ZAPTEL_COMPILE_DISABLE="NO" +BRI_MODULE_TEST="NO" ZAP_CHUNK_OP="NO" CMP_LOG=$PROD_HOME/setup_drv_compile.log CMP_BUILD=build.sh @@ -6963,12 +7173,15 @@ SSMG_DIR=ssmg WANPIPE_INCLUDE_DIR=/usr/include/wanpipe WANCFG_ZAPTEL_CFG=NO WANCFG_ZAPTEL=/usr/sbin/wancfg_zaptel +WANCFG_DAHDI=/usr/sbin/wancfg_dahdi WANCFG_SMG=/usr/sbin/wancfg_smg find_zap_dir_quit=0 find_ast_dir_quit=0 zaptel_auto_install="NO" +dahdi_auto_install="NO" bri_auto_install="NO" setup_install_quick="NO" +MODSYM=Module.symvers echo > $CMP_LOG @@ -7022,6 +7235,8 @@ ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR ZAPTEL_C_FILE="zaptel.c" ASTERISK_IFLAGS= EDAC_ZAP_PATCH_FILE=ed_zaptel.patch +ZAPTEL_SUPPORT="NO" +DAHDI_SUPPORT="NO" ASTERISK_INSTALL_DIR="/usr/src/asterisk" EDAC_ASTERISK_PATCH_FILE=ed_asterisk.patch @@ -7181,10 +7396,13 @@ if [ "$setup_cmd" = "uninstall" ] || [ "$setup_cmd" = "remove" ]; then exit; fi -if [ "$setup_cmd" = "zaptel" ]; then - setup_cmd="install" +if [ "$setup_cmd" = "zaptel" ] || [ "$setup_cmd" = "dahdi" ] ; then zaptel_auto_install="YES" setup_install_quick="YES" + if [ "$setup_cmd" = "dahdi" ]; then + dahdi_auto_install="YES" + fi + setup_cmd="install" #EXTRA_ARGS=" --protocol=TDM --silent --no-zaptel-compile " #EXTRA_ARGS=" --protocol=TDM " fi @@ -7224,6 +7442,16 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then case $arg in --silent*) + if [ $bri_auto_install = "YES" ]; then + #default + bri_auto_install="NO" + elif [ $zaptel_auto_install = "YES" ]; then + zaptel_auto_install="NO" + PROTS=TDM; + fi + zaptel_auto_install="NO" + setup_install_quick="NO" + bri_auto_install="NO" NONINTERACTIVE=1; ;; --linux-vanilla*) @@ -7260,6 +7488,9 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then --edac*) #TAKEN OUT ;; + --bri_module_test*) + BRI_MODULE_TEST="YES" + ;; --noautostart*) NO_AUTO_START=1 ;; @@ -7314,12 +7545,8 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then 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 + + set_zaptel_source_dir ;; @@ -7340,12 +7567,7 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then 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 + set_zaptel_source_dir ;; @@ -7375,6 +7597,9 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then WANPIPE_INCLUDE_DIR=$ROOT/$TMP_123 TMP_123=${WANCFG_ZAPTEL#/*} WANCFG_ZAPTEL=$ROOT/$TMP_123 + TMP_123=${WANCFG_DAHDI#/*} + WANCFG_DAHDI=$ROOT/$TMP_123 + ;; --acflags*) @@ -7803,17 +8028,21 @@ if [ $zaptel_auto_install = "YES" ]; then NONINTERACTIVE= fi -NONINTERACTIVE= +#NONINTERACTIVE= if [ -z $NONINTERACTIVE ]; then if [ "$WANCFG_ZAPTEL_CFG" = "YES" ] && [ -e $WANCFG_ZAPTEL ]; then echo if [ $SSMG_BRI == "YES" ]; then - echo "Wanpipe / Zaptel & SMG BRI Configuration" + echo "Wanpipe / Zaptel/Dahdi & SMG BRI Configuration" echo "========================================" else - echo "Wanpipe / Zaptel Configuration" + if [ $DAHDI_SUPPORT = "YES" ]; then + echo "Wanpipe / Zaptel Configuration" + else + echo "Wanpipe / Dahdi Configuration" + fi echo "==============================" fi echo @@ -7821,27 +8050,49 @@ if [ "$WANCFG_ZAPTEL_CFG" = "YES" ] && [ -e $WANCFG_ZAPTEL ]; then echo "wancfg_smg configurator can create all wanpipe config files" echo "for ZAPTEL as well as for SMG BRI." else - echo "wancfg_zaptel configurator can create all wanpipe config files" - echo "for ZAPTEL including /etc/zaptel.conf file." + if [ $DAHDI_SUPPORT = "YES" ]; then + echo "wancfg_zaptel configurator can create all wanpipe config files" + echo "for ZAPTEL including /etc/zaptel.conf file." + echo "Optionally: the configurator can also create Asterisk zapata.conf" + else + echo "wancfg_dahdi configurator can create all wanpipe config files" + echo "for DAHDI including /etc/dahdi/dahdi.conf file." + echo "Optionally: the configurator can also create Asterisk dahdi.conf" + fi fi - echo "Optionally: the configurator can also create Asterisk zapata.conf" echo "-----------------------------------------------------" if [ $SSMG_BRI == "YES" ]; then - getyn "Would you like to configure wanpipe devices for ZAPTEL & BRI?" + getyn "Would you like to configure wanpipe devices for ZAPTEL/DAHDI & BRI?" else - getyn "Would you like to configure wanpipe devices for ZAPTEL?" + if [ $DAHDI_SUPPORT = "YES" ]; then + getyn "Would you like to configure wanpipe devices for DAHDI?" + else + getyn "Would you like to configure wanpipe devices for ZAPTEL?" + fi fi if [ $? -eq 0 ]; then if [ $SSMG_BRI == "YES" ]; then eval "$WANCFG_SMG" else - eval "$WANCFG_ZAPTEL" + if [ $DAHDI_SUPPORT = "YES" ]; then + eval "$WANCFG_DAHDI" + else + eval "$WANCFG_ZAPTEL" + fi fi else echo "Wanpipe Installation Complete" echo "-----------------------------" - echo "Please proceed to configure wanpipe user /usr/sbin/wancfg" + if [ $SSMG_BRI == "YES" ]; then + echo "Please proceed to configure wanpipe user /usr/sbin/wancfg_smg" + else + if [ $DAHDI_SUPPORT = "YES" ]; then + echo "Please proceed to configure wanpipe user /usr/sbin/wancfg_dahdi" + else + echo "Please proceed to configure wanpipe user /usr/sbin/wancfg_zaptel" + fi + fi echo fi elif [ "$SSMG_BRI" = "YES" ]; then @@ -7857,7 +8108,11 @@ elif [ "$SSMG_BRI" = "YES" ]; then if [ $SSMG_BRI == "YES" ]; then eval "$WANCFG_SMG" else - eval "$WANCFG_ZAPTEL" + if [ $DAHDI_SUPPORT = "YES" ]; then + eval "$WANCFG_DAHDI" + else + eval "$WANCFG_ZAPTEL" + fi fi else echo "Wanpipe Installation Complete" diff --git a/api/Makefile b/api/Makefile index 0e751ce..593bbde 100644 --- a/api/Makefile +++ b/api/Makefile @@ -4,21 +4,17 @@ # Copyright (c) 1995-2000 Sangoma Technologies Inc. All Rights Reserved. # ============================================================================ -SYSINC=$(shell if [ -f ../.sysinclude ]; then cat ../.sysinclude; else echo ""; fi) -ifeq "$(SYSINC)" "" -SYSINC=/lib/modules/$(shell uname -r)/build/include -endif APIINC=/etc/wanpipe/api/include ####### RULES ################################################################ all: - make -C x25 all SYSINC=$(SYSINC) APIINC=$(APIINC) - make -C chdlc all SYSINC=$(SYSINC) APIINC=$(APIINC) - make -C fr all SYSINC=$(SYSINC) APIINC=$(APIINC) - make -C bitstrm all SYSINC=$(SYSINC) APIINC=$(APIINC) - make -C bisync all SYSINC=$(SYSINC) APIINC=$(APIINC) -# make -C ss7 all SYSINC=$(SYSINC) APIINC=$(APIINC) + make -C x25 all APIINC=$(APIINC) + make -C chdlc all APIINC=$(APIINC) + make -C fr all APIINC=$(APIINC) + make -C bitstrm all APIINC=$(APIINC) + make -C bisync all APIINC=$(APIINC) +# make -C ss7 all APIINC=$(APIINC) clean: make -C x25 clean diff --git a/api/adccp/Makefile b/api/adccp/Makefile index 6345773..89ee794 100644 --- a/api/adccp/Makefile +++ b/api/adccp/Makefile @@ -10,13 +10,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 -SYSINC=$(shell if [ -f ../../.sysinclude ]; then cat ../../.sysinclude; else echo ""; fi) -ifeq "$(SYSINC)" "" -SYSINC=/usr/src/linux/include -endif # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/aft/Makefile b/api/aft/Makefile index f3aaeb3..fad77cd 100644 --- a/api/aft/Makefile +++ b/api/aft/Makefile @@ -10,18 +10,12 @@ OS_TYPE = __LINUX__ DEBUG = 2 -SYSINC=$(shell if [ -f ../../.sysinclude ]; then cat ../../.sysinclude; else echo ""; fi) -ifeq "$(SYSINC)" "" -SYSINC=/usr/src/linux/include -endif -VPATH = $(SYSINC) - 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) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_GNUC_ -I../lib -I$(SYSINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_GNUC_ -I../lib CFLAGS += -I/usr/include/wanpipe TARGETS=aft_api diff --git a/api/asyhdlc/Makefile b/api/asyhdlc/Makefile index 8acde5f..6c56a6d 100644 --- a/api/asyhdlc/Makefile +++ b/api/asyhdlc/Makefile @@ -11,11 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include APIINC = /usr/src/linux/include # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/bisync/Makefile b/api/bisync/Makefile index bdf0e8d..f836c60 100644 --- a/api/bisync/Makefile +++ b/api/bisync/Makefile @@ -11,12 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) APIINC = /usr/src/linux/include # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(APIINC) ####### RULES ################################################################ diff --git a/api/bisync_strm/Makefile b/api/bisync_strm/Makefile index c9e9ce9..b220dfc 100644 --- a/api/bisync_strm/Makefile +++ b/api/bisync_strm/Makefile @@ -11,12 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include APIINC = ../include -VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/bitstrm/Makefile b/api/bitstrm/Makefile index 97ce8a0..f2325fa 100644 --- a/api/bitstrm/Makefile +++ b/api/bitstrm/Makefile @@ -11,12 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) APIINC = /usr/src/linux/include # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/bitstrm/datascope/Makefile b/api/bitstrm/datascope/Makefile index 33f0d4d..8924d64 100644 --- a/api/bitstrm/datascope/Makefile +++ b/api/bitstrm/datascope/Makefile @@ -11,11 +11,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I../../lib -I$(SYSINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I../../lib ####### RULES ################################################################ diff --git a/api/bitstrm/te1/Makefile b/api/bitstrm/te1/Makefile index ce39911..7712123 100644 --- a/api/bitstrm/te1/Makefile +++ b/api/bitstrm/te1/Makefile @@ -11,10 +11,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ ####### RULES ################################################################ diff --git a/api/chdlc/Makefile b/api/chdlc/Makefile index 2ec2d42..f6672ff 100644 --- a/api/chdlc/Makefile +++ b/api/chdlc/Makefile @@ -11,11 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -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) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/fr/Makefile b/api/fr/Makefile index 0cf20af..db76d53 100644 --- a/api/fr/Makefile +++ b/api/fr/Makefile @@ -11,10 +11,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(APIINC) TARGETS = fr_api #TARGETS += fr_api_fast diff --git a/api/libsangoma/.svn/all-wcprops b/api/libsangoma/.svn/all-wcprops index bda8bf7..ff4780d 100644 --- a/api/libsangoma/.svn/all-wcprops +++ b/api/libsangoma/.svn/all-wcprops @@ -1,7 +1,7 @@ K 25 svn:wc:ra_dav:version-url V 33 -/svn/libsangoma/!svn/ver/11/trunk +/svn/libsangoma/!svn/ver/22/trunk END configure K 25 @@ -9,11 +9,17 @@ svn:wc:ra_dav:version-url V 43 /svn/libsangoma/!svn/ver/11/trunk/configure END +doxygen.config +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/libsangoma/!svn/ver/18/trunk/doxygen.config +END Makefile.in K 25 svn:wc:ra_dav:version-url V 45 -/svn/libsangoma/!svn/ver/11/trunk/Makefile.in +/svn/libsangoma/!svn/ver/21/trunk/Makefile.in END AUTHORS K 25 @@ -21,6 +27,12 @@ svn:wc:ra_dav:version-url V 40 /svn/libsangoma/!svn/ver/1/trunk/AUTHORS END +libhpsangoma_priv.c +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/libsangoma/!svn/ver/18/trunk/libhpsangoma_priv.c +END depcomp K 25 svn:wc:ra_dav:version-url @@ -39,11 +51,11 @@ svn:wc:ra_dav:version-url V 45 /svn/libsangoma/!svn/ver/1/trunk/config.guess END -svn-commit.2.tmp +libhpsangoma_priv.h K 25 svn:wc:ra_dav:version-url -V 49 -/svn/libsangoma/!svn/ver/1/trunk/svn-commit.2.tmp +V 53 +/svn/libsangoma/!svn/ver/18/trunk/libhpsangoma_priv.h END ltmain.sh K 25 @@ -61,7 +73,7 @@ libsangoma.c K 25 svn:wc:ra_dav:version-url V 46 -/svn/libsangoma/!svn/ver/11/trunk/libsangoma.c +/svn/libsangoma/!svn/ver/12/trunk/libsangoma.c END libsangoma.dsp K 25 @@ -87,29 +99,29 @@ svn:wc:ra_dav:version-url V 40 /svn/libsangoma/!svn/ver/1/trunk/INSTALL END -COPYING -K 25 -svn:wc:ra_dav:version-url -V 40 -/svn/libsangoma/!svn/ver/1/trunk/COPYING -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 +sangoma_pri.c K 25 svn:wc:ra_dav:version-url -V 42 -/svn/libsangoma/!svn/ver/11/trunk/Makefile +V 46 +/svn/libsangoma/!svn/ver/1/trunk/sangoma_pri.c END libsangoma.so.conf K 25 @@ -117,29 +129,29 @@ svn:wc:ra_dav:version-url V 51 /svn/libsangoma/!svn/ver/1/trunk/libsangoma.so.conf END -sangoma_pri.c -K 25 -svn:wc:ra_dav:version-url -V 46 -/svn/libsangoma/!svn/ver/1/trunk/sangoma_pri.c -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 -sangoma_pri.h +libhpsangoma.c K 25 svn:wc:ra_dav:version-url -V 46 -/svn/libsangoma/!svn/ver/1/trunk/sangoma_pri.h +V 48 +/svn/libsangoma/!svn/ver/18/trunk/libhpsangoma.c END configure.in K 25 @@ -153,11 +165,11 @@ svn:wc:ra_dav:version-url V 42 /svn/libsangoma/!svn/ver/1/trunk/ChangeLog END -svn-commit.tmp +libhpsangoma.h K 25 svn:wc:ra_dav:version-url -V 47 -/svn/libsangoma/!svn/ver/1/trunk/svn-commit.tmp +V 48 +/svn/libsangoma/!svn/ver/18/trunk/libhpsangoma.h END README K 25 @@ -171,18 +183,18 @@ svn:wc:ra_dav:version-url V 44 /svn/libsangoma/!svn/ver/1/trunk/config.h.in END +Makefile.am +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/libsangoma/!svn/ver/21/trunk/Makefile.am +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 diff --git a/api/libsangoma/.svn/entries b/api/libsangoma/.svn/entries index 702f093..53e6b3c 100644 --- a/api/libsangoma/.svn/entries +++ b/api/libsangoma/.svn/entries @@ -1,14 +1,14 @@ 8 dir -11 +22 https://www.sangomapbx.com/svn/libsangoma/trunk https://www.sangomapbx.com/svn/libsangoma -2008-07-23T22:34:10.394780Z -11 +2008-09-17T21:25:40.156211Z +22 ncorbic @@ -32,23 +32,35 @@ file -2008-02-28T19:04:34.000000Z +2008-09-17T15:43:38.000000Z f84c30e2597ef02a8b7ae6e7abc79cba 2008-07-23T22:34:10.394780Z 11 ncorbic has-props +doxygen.config +file + + + + +2008-08-18T04:42:48.000000Z +9f9274a01491fc18fc590cc72aee50b5 +2008-08-18T04:37:20.241598Z +18 +ncorbic + Makefile.in file -2008-07-14T15:22:04.000000Z -af46a5508ab9308c4adb270328403f05 -2008-07-23T22:34:10.394780Z -11 +2008-09-17T15:43:37.000000Z +b64570263ebee3d9e6ba2d2337fd986f +2008-09-17T16:28:59.949208Z +21 ncorbic AUTHORS @@ -57,19 +69,31 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z d41d8cd98f00b204e9800998ecf8427e 2008-02-28T18:51:53.196120Z 1 root +libhpsangoma_priv.c +file + + + + +2008-08-18T04:42:48.000000Z +bd544f6a63804d97771b5d6f14f9c7cd +2008-08-18T04:37:20.241598Z +18 +ncorbic + depcomp file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z e181e2c8720c60522c4c4c981108e367 2008-02-28T18:51:53.196120Z 1 @@ -82,37 +106,64 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z a7ecc032b527a0d578545f19d3418073 2008-02-28T18:51:53.196120Z 1 root has-props +docs +dir + config.guess file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 9ae396244b8f138c76514a6b7531e696 2008-02-28T18:51:53.196120Z 1 root has-props -svn-commit.2.tmp +libhpsangoma_priv.h file -2008-07-02T13:55:55.000000Z -9bf5427f205140ba936f4feb06d54cac -2008-02-28T18:51:53.196120Z -1 -root +2008-08-18T04:42:48.000000Z +d1808b1e536319bd48486efa8bea18bc +2008-08-18T04:37:20.241598Z +18 +ncorbic + +svn-commit.2.tmp +file +24 + + + + + + + + + + + + + + + + + + + +deleted ltmain.sh file @@ -120,7 +171,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z c8215e3aa0858d700783015614f53b79 2008-02-28T18:51:53.196120Z 1 @@ -132,7 +183,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 3d36962d51070d30b7554203b0d7c01c 2008-02-28T18:51:53.196120Z 1 @@ -145,10 +196,10 @@ file -2008-07-24T14:57:18.000000Z -52feb22ab727ea6afbf6a9501e813c85 -2008-07-23T22:34:10.394780Z -11 +2008-08-18T04:42:48.000000Z +997c16d3e1205046feceb00ab3fee8dd +2008-08-18T00:57:37.953171Z +12 ncorbic libsangoma.dsp @@ -157,7 +208,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z f934aab66c529599725686f321d182e6 2008-02-28T18:51:53.196120Z 1 @@ -181,7 +232,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 0f725f95ced42af15dcaef21f3a1722b 2008-02-28T18:51:53.196120Z 1 @@ -193,43 +244,43 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 40539bd3eff06e4b82f380103145415b 2008-02-28T18:51:53.196120Z 1 root -libsangoma.dsw -file - - - - -2008-05-22T23:06:17.000000Z -f13496d2105bae2add104c36a1d656f6 -2008-02-28T18:51:53.196120Z -1 -root - COPYING file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z d41d8cd98f00b204e9800998ecf8427e 2008-02-28T18:51:53.196120Z 1 root +libsangoma.dsw +file + + + + +2008-07-17T12:20:35.000000Z +f13496d2105bae2add104c36a1d656f6 +2008-02-28T18:51:53.196120Z +1 +root + NEWS file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z d41d8cd98f00b204e9800998ecf8427e 2008-02-28T18:51:53.196120Z 1 @@ -237,35 +288,27 @@ root Makefile file - - - - -2008-07-14T15:18:57.000000Z -2f0d18b13150848a1bb2c513a790498c -2008-07-23T22:34:10.394780Z -11 -ncorbic +23 -Makefile.r9 -Makefile.r11 -Makefile.mine - -sangoma_pri.c -file -2008-05-22T23:06:17.000000Z -e2a6c68fadfefb2d2b16c52534e85675 -2008-02-28T18:51:53.196120Z -1 -root + + + + + + + + + + +deleted libsangoma.so.conf file @@ -273,55 +316,79 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z bcdcb23c5d5fb460cee2ce315ef7bd32 2008-02-28T18:51:53.196120Z 1 root +sangoma_pri.c +file + + + + +2008-07-17T12:20:35.000000Z +e2a6c68fadfefb2d2b16c52534e85675 +2008-02-28T18:51:53.196120Z +1 +root + win_api_common.h file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z b6be170d18fa90b79f7264cf8b0f7348 2008-02-28T18:51:53.196120Z 1 root -sangoma_pri.h -file - - - - -2008-05-22T23:06:17.000000Z -f24c6cf396aeaa6df2747f7f6b32969d -2008-02-28T18:51:53.196120Z -1 -root - version file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 35f672d1fb01b542f667952c9dbb26fe 2008-02-28T18:51:53.196120Z 1 root +sangoma_pri.h +file + + + + +2008-07-17T12:20:35.000000Z +f24c6cf396aeaa6df2747f7f6b32969d +2008-02-28T18:51:53.196120Z +1 +root + +libhpsangoma.c +file + + + + +2008-08-18T04:42:48.000000Z +b1d5eaa1c7cde587df266b1833f5e735 +2008-08-18T04:37:20.241598Z +18 +ncorbic + configure.in file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 5b9888fc365c4ebffdbb55656c091a2f 2008-02-28T18:51:53.196120Z 1 @@ -333,23 +400,47 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z d41d8cd98f00b204e9800998ecf8427e 2008-02-28T18:51:53.196120Z 1 root -svn-commit.tmp +libhpsangoma.h file -2008-07-02T13:55:55.000000Z -4ac38b24bcff9c3975171af8ccbcfa36 -2008-02-28T18:51:53.196120Z -1 -root +2008-08-18T04:42:48.000000Z +706cd7f3886d4f5f7515cf84bdae55ad +2008-08-18T04:37:20.241598Z +18 +ncorbic + +svn-commit.tmp +file +24 + + + + + + + + + + + + + + + + + + + +deleted README file @@ -357,7 +448,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z e8a0abce86211364eb60bbe6e07d4b05 2008-02-28T18:51:53.196120Z 1 @@ -369,36 +460,36 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 5c51918deee8d041af37226bd4b4271e 2008-02-28T18:51:53.196120Z 1 root -missing -file - - - - -2008-05-22T23:06:17.000000Z -fd5dd60aa8cefab9462677280ea74a61 -2008-02-28T18:51:53.196120Z -1 -root -has-props - Makefile.am file -2008-05-22T23:06:17.000000Z -061d814c4cf9a1066e4ff2501fa0a100 +2008-09-17T15:43:08.000000Z +5796040dd24c0fe0d5873523ba46ae01 +2008-09-17T16:28:59.949208Z +21 +ncorbic + +missing +file + + + + +2008-07-17T12:20:35.000000Z +fd5dd60aa8cefab9462677280ea74a61 2008-02-28T18:51:53.196120Z 1 root +has-props examples dir @@ -409,7 +500,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z 92067666ddce97609bd0ec67d36460cd 2008-02-28T18:51:53.196120Z 1 @@ -422,7 +513,7 @@ file -2008-05-22T23:06:17.000000Z +2008-07-17T12:20:35.000000Z a09711e3b6aac93dd48d8e9b3014955f 2008-02-28T18:51:53.196120Z 1 diff --git a/api/libsangoma/.svn/text-base/Makefile.am.svn-base b/api/libsangoma/.svn/text-base/Makefile.am.svn-base index 1d5ee14..a7afd47 100644 --- a/api/libsangoma/.svn/text-base/Makefile.am.svn-base +++ b/api/libsangoma/.svn/text-base/Makefile.am.svn-base @@ -1,18 +1,18 @@ -KINC=/lib/modules/$(shell uname -r)/build -WINC=../../patches/kdrivers/include +WLINC=../../patches/kdrivers/include +WINC=/usr/include/wanpipe -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 +AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WLINC) -I$(WINC) -I. \ + -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O2 -D_DEBUG_=2 -D_GNUC_ -I../lib -LIB_SOURCES = libsangoma.c libsangoma.h +LIB_SOURCES = libsangoma.c libsangoma.h libhpsangoma.c libhpsangoma.h libhpsangoma_priv.c libhpsangoma_priv.h if LIBPRI LIB_SOURCES += sangoma_pri.c sangoma_pri.h endif library_includedir = $(includedir) -library_include_HEADERS = libsangoma.h +library_include_HEADERS = libsangoma.h libhpsangoma.h if LIBPRI library_include_HEADERS += sangoma_pri.h diff --git a/api/libsangoma/.svn/text-base/Makefile.in.svn-base b/api/libsangoma/.svn/text-base/Makefile.in.svn-base index 251a1de..91327a3 100644 --- a/api/libsangoma/.svn/text-base/Makefile.in.svn-base +++ b/api/libsangoma/.svn/text-base/Makefile.in.svn-base @@ -75,9 +75,12 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libsangoma_la_LIBADD = am__libsangoma_la_SOURCES_DIST = libsangoma.c libsangoma.h \ - sangoma_pri.c sangoma_pri.h + libhpsangoma.c libhpsangoma.h libhpsangoma_priv.c \ + libhpsangoma_priv.h sangoma_pri.c sangoma_pri.h @LIBPRI_TRUE@am__objects_1 = libsangoma_la-sangoma_pri.lo -am__objects_2 = libsangoma_la-libsangoma.lo $(am__objects_1) +am__objects_2 = libsangoma_la-libsangoma.lo \ + libsangoma_la-libhpsangoma.lo \ + libsangoma_la-libhpsangoma_priv.lo $(am__objects_1) am_libsangoma_la_OBJECTS = $(am__objects_2) libsangoma_la_OBJECTS = $(am_libsangoma_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) @@ -94,7 +97,8 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 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 +am__library_include_HEADERS_DIST = libsangoma.h libhpsangoma.h \ + sangoma_pri.h library_includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(library_include_HEADERS) ETAGS = etags @@ -210,14 +214,15 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @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 +WLINC = ../../patches/kdrivers/include +WINC = /usr/include/wanpipe +AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WLINC) -I$(WINC) -I. \ + -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O2 -D_DEBUG_=2 -D_GNUC_ -I../lib -LIB_SOURCES = libsangoma.c libsangoma.h $(am__append_1) +LIB_SOURCES = libsangoma.c libsangoma.h libhpsangoma.c libhpsangoma.h \ + libhpsangoma_priv.c libhpsangoma_priv.h $(am__append_1) library_includedir = $(includedir) -library_include_HEADERS = libsangoma.h $(am__append_2) +library_include_HEADERS = libsangoma.h libhpsangoma.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) @@ -331,6 +336,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libhpsangoma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libsangoma.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-sangoma_pri.Plo@am__quote@ @@ -362,6 +369,20 @@ libsangoma_la-libsangoma.lo: libsangoma.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @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-libhpsangoma.lo: libhpsangoma.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-libhpsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libhpsangoma.c' object='libsangoma_la-libhpsangoma.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c + +libsangoma_la-libhpsangoma_priv.lo: libhpsangoma_priv.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-libhpsangoma_priv.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libhpsangoma_priv.c' object='libsangoma_la-libhpsangoma_priv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c + libsangoma_la-sangoma_pri.lo: 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 diff --git a/api/libsangoma/.svn/text-base/Makefile.svn-base b/api/libsangoma/.svn/text-base/Makefile.svn-base deleted file mode 100644 index ef6c4f4..0000000 --- a/api/libsangoma/.svn/text-base/Makefile.svn-base +++ /dev/null @@ -1,679 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - - - -srcdir = . -top_srcdir = . - -pkgdatadir = $(datadir)/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) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(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} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run aclocal-1.9 -AMDEP_FALSE = # -AMDEP_TRUE = -AMTAR = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run tar -AR = ar -AUTOCONF = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run autoconf -AUTOHEADER = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run autoheader -AUTOMAKE = ${SHELL} /root/3.3/wanpipe/ssmg/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 = f95 -FFLAGS = -g -O2 -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s -LDFLAGS = -LIBOBJS = -LIBPRI_FALSE = -LIBPRI_TRUE = # -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LN_S = ln -s -LTLIBOBJS = -MAKEINFO = ${SHELL} /root/3.3/wanpipe/ssmg/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 -SED = /bin/sed -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 = f95 -ac_ct_RANLIB = ranlib -ac_ct_STRIP = strip -am__fastdepCC_FALSE = # -am__fastdepCC_TRUE = -am__fastdepCXX_FALSE = # -am__fastdepCXX_TRUE = -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build = i686-pc-linux-gnu -build_alias = -build_cpu = i686 -build_os = linux-gnu -build_vendor = pc -datadir = ${prefix}/share -exec_prefix = ${prefix} -host = i686-pc-linux-gnu -host_alias = -host_cpu = i686 -host_os = linux-gnu -host_vendor = pc -includedir = ${prefix}/include -infodir = ${prefix}/info -install_sh = /root/3.3/wanpipe/ssmg/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 -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 = /common/include -#WINC = ../../patches/kdrivers/include -AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WINC) -I/wanpipe/code/include -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) --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) --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) --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) --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 - -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/doxygen.config.svn-base b/api/libsangoma/.svn/text-base/doxygen.config.svn-base new file mode 100644 index 0000000..de802b0 --- /dev/null +++ b/api/libsangoma/.svn/text-base/doxygen.config.svn-base @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libhpsangoma + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = libhpsangoma.c libhpsangoma_priv.c libhpsangoma.h libhpsangoma_priv.h + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/api/libsangoma/.svn/text-base/libhpsangoma.c.svn-base b/api/libsangoma/.svn/text-base/libhpsangoma.c.svn-base new file mode 100644 index 0000000..3909a90 --- /dev/null +++ b/api/libsangoma/.svn/text-base/libhpsangoma.c.svn-base @@ -0,0 +1,442 @@ +/***************************************************************************** + * libhpsangoma.c: Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 "libhpsangoma.h" +#include "libhpsangoma_priv.h" + +/*--------------------------------------------------------- + PRIVATE STRUCTURES + ----------------------------------------------------------*/ + +void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)=NULL; + + +/*! + \brief Channel Method: User tx a chunk into a channel + \param chan channel object + \param data pointer to user voice chunk + \param len size of user voice chunk + \return -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok +*/ + +static int sangoma_hp_tdm_chan_push(struct sangoma_hptdm_chan *chan, char *data, int len) +{ + hp_tmd_chunk_t *tx_chunk; + int free_slots; + + if (!chan->init) { + return -2; + } + + if (len >= SMG_HP_MAX_CHAN_DATA) { + /* Data Too Big */ + lib_printf(0,NULL,"chan_push c%i tx chunk len %i too big\n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in,len); + return -1; + } + + /* Lock */ + if (chan->tx_idx_in >= chan->tx_idx_out) { + free_slots=SMG_HP_TDM_CHUNK_IDX_SZ-(chan->tx_idx_in-chan->tx_idx_out); + } else { + free_slots=chan->tx_idx_out-chan->tx_idx_in; + } + /* Un Lock */ + + if (!free_slots) { + /* We have just overruned the tx buffer */ + lib_printf(0,NULL,"chan_push c%i failed no free slots in %i out %i\n", + chan->span_no+1,chan->chan_no+1, chan->tx_idx_in,chan->tx_idx_out); + return 1; + } + + tx_chunk = &chan->tx_idx[chan->tx_idx_in]; + if (tx_chunk->init) { + /* This should NEVER happen the chunk should be free */ + lib_printf(15,NULL,"chan_push s%ic%i tx chunk overrun in %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in); + return 1; + } + + memset(tx_chunk,0,sizeof(hp_tmd_chunk_t)); + memcpy(&tx_chunk->data,data,len); + tx_chunk->len=len; + tx_chunk->init=1; + + lib_printf(15,NULL,"chan_push s%ic%i tx chunk in %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in); + + chan->tx_idx_in++; + if (chan->tx_idx_in >= SMG_HP_TDM_CHUNK_IDX_SZ) { + chan->tx_idx_in=0; + } + + return 0; +} + +/*------------------------------------------------- + Internal Span Methods + -------------------------------------------------*/ + + +/*! + \brief Span Method: Open a channel inside of span + \param span span object + \param cfg channel registration structure + \param chan_no channel number + \param chan_ptr pass user the channel pointer reference + \return 0 = pass, non zero fail +*/ + +static int sangoma_hp_tdm_open_chan(sangoma_hptdm_span_t *span, + sangoma_hptdm_chan_reg_t *cfg, + unsigned int chan_no, + sangoma_hptdm_chan_t **chan_ptr) +{ + sangoma_hptdm_chan_t *chan; + + if (!span->init) { + return -1; + } + + if (chan_no >= SMG_HP_TDM_MAX_CHANS) { + lib_printf(0,NULL,"open_chan failed chan_no %i >= max chans %i\n", + chan_no, SMG_HP_TDM_MAX_CHANS); + return -1; + } + + if (!cfg->rx_data || !cfg->p) { + return -1; + } + + if (span->chan_idx[chan_no].chan_no_hw < 0) { + lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is not mapped to hardware\n", + span->span_no+1,chan_no+1); + return -1; + } + + chan = &span->chan_idx[chan_no].chan; + if (chan->init) { + /* Chan Busy */ + lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is busy\n", + span->span_no+1,chan_no+1); + return 1; + } + + memset(chan,0,sizeof(sangoma_hptdm_chan_t)); + + chan->chan_no = chan_no; + chan->span = span; + memcpy(&chan->chan_reg, cfg, sizeof(sangoma_hptdm_chan_reg_t)); + + chan->push = sangoma_hp_tdm_chan_push; + + chan->init=1; + lib_printf(15,NULL,"open_chan chan_no s%ic%i ok\n", + span->span_no+1,chan_no+1); + + *chan_ptr = chan; + + return 0; + +} + + +/*! + \brief Span Method: Close channel + \param chan channel object + \return 0 = pass, non zero fail +*/ + +static int sangoma_hp_tdm_close_chan(sangoma_hptdm_chan_t *chan) +{ + chan->init=0; + chan->chan_reg.p=NULL; + lib_printf(15,NULL,"close_chan chan_no s%ic%i ok\n", + chan->span_no+1,chan->chan_no+1); + return 0; +} + + +/*! + \brief Span Method: Test if channel is closed + \param chan channel object + \return 0 = channel is NOT closed, non zero channel IS closed +*/ +static int sangoma_hp_tdm_is_chan_closed (sangoma_hptdm_chan_t *chan) +{ + return (chan->init == 0) ? 1:0; +} + +/*! + \brief Span Method: Close span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_close_span(sangoma_hptdm_span_t *span) +{ + int i; + sangoma_hptdm_chan_t *chan=NULL; + + for (i=0;ichan_idx[i].chan; + if (chan->init) { + chan->init=0; + } + } + + close(span->sock); + span->sock=-1; + + return 0; +} + +/*! + \brief Span Method: User passes cmd to the span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_event_ctrl_span(sangoma_hptdm_span_t *span, hp_tdmapi_tx_event_t *event) +{ + int err; + + if (!span->init || span->sock < 0) { + return -1; + } + + err = ioctl(span->sock,SIOC_WANPIPE_API,event); + if (err < 0){ + lib_printf(0,NULL,"Error: SPAN %i Failed to execute event!\n", + span->span_no+1); + return -1; + } + + return 0; +} + +/*! + \brief Span Method: User requests full span configuration + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_event_get_cfg(sangoma_hptdm_span_t *span, wan_if_cfg_t *if_cfg) +{ + memcpy(if_cfg,&span->span_cfg,sizeof(if_cfg)); + return 0; +} + +/*! + \brief Span Method: handle the span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_run_span(sangoma_hptdm_span_t *span) +{ + int err=0; + fd_set sock_read,sock_write,sock_oob; + + if (!span->init) { + lib_printf(0, NULL, "Span %i not initialized %i\n",span->span_no+1); + return -1; + } + + lib_printf(15, NULL, "Starting RUN SPAN %i Sock=%i\n",span->span_no+1, span->sock); + + if (span->sock < 0) { + err=sangoma_hptdm_span_open(span); + if (err) { + usleep(500000); + err=-2; + goto sangoma_hp_tdm_run_span_exit; + } + } + + /* Initialize all select() descriptors */ + FD_ZERO(&sock_read); + FD_ZERO(&sock_write); + FD_ZERO(&sock_oob); + + FD_SET(span->sock,&sock_oob); + FD_SET(span->sock,&sock_read); + FD_SET(span->sock,&sock_write); + + err=select(span->sock + 1,&sock_read, NULL, &sock_oob, NULL); + + if (err > 0) { + + if (FD_ISSET(span->sock,&sock_oob)){ + err=sangoma_hp_tdm_handle_oob_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i oob err %i\n", + span->span_no+1, err); + err=-3; + goto sangoma_hp_tdm_run_span_exit; + } + } + if (FD_ISSET(span->sock,&sock_read)){ + err=sangoma_hp_tdm_handle_read_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i read err %i\n", + span->span_no+1, err); + err=-4; + goto sangoma_hp_tdm_run_span_exit; + } + + err=sangoma_hp_tdm_handle_write_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i write err %i\n", + span->span_no+1, err); + err=-5; + goto sangoma_hp_tdm_run_span_exit; + } + } + + } else if (err==0) { + /* Timeout continue */ + return 0; + + } else { + /* Error */ + if (errno == EAGAIN) { + goto sangoma_hp_tdm_run_span_exit; + } + + err=-6; + } + +sangoma_hp_tdm_run_span_exit: + + if (err < 0) { + if (span->sock) { + close(span->sock); + span->sock=-1; + } + } + + return err; +} + + + +/*--------------------------------------------------------- + PUBLIC STRUCTURES + ----------------------------------------------------------*/ + + +/* + \brief Initialize and Configure Span - private functions not to be used directly! + \param span_no span number - integer + \param cfg span registration struct + \param version library version number added by the macro + \return NULL: fail, Span Object: pass + * + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ + +sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version) +{ + int err,i,ch=0; + sangoma_hptdm_span_t *span; + + span = malloc(sizeof(sangoma_hptdm_span_t)); + if (!span) { + return NULL; + } + + memset(span,0,sizeof(sangoma_hptdm_span_t)); + + span->span_no=span_no; + sprintf(span->if_name,"w%ig1",span_no+1); + + if (cfg) { + memcpy(&span->span_reg,cfg,sizeof(sangoma_hptdm_span_reg_t)); + if (!lib_log) { + lib_log=cfg->log; + } + } + + err=sangoma_hptdm_span_open(span); + if (err) { + free(span); + return NULL; + } + + if (span->span_cfg.media == WAN_MEDIA_E1) { + span->span_cfg.active_ch = span->span_cfg.active_ch >> 1; + } + + lib_printf(0,NULL,"Span %i Configuration\n",span->span_no+1); + lib_printf(0,NULL,"Used By\t:%i\n",span->span_cfg.usedby); + lib_printf(0,NULL,"Media\t:%i\n",span->span_cfg.media); + lib_printf(0,NULL,"Active Ch\t:0x%08X\n",span->span_cfg.active_ch); + lib_printf(0,NULL,"Chunk Sz\t:%i\n",span->span_cfg.chunk_sz); + lib_printf(0,NULL,"HW Coding\t:%i\n",span->span_cfg.hw_coding); + lib_printf(0,NULL,"If Number\t:%i\n",span->span_cfg.interface_number); + + + /* Map all channels to the actually configued on hardware */ + for (i=0;ichan_idx[i].chan_no_hw=-1; + if (span->span_cfg.active_ch & (1<chan_idx[i].chan_no_hw=ch; + lib_printf(0,NULL,"Chan %i Mapped to %i",i,ch); + ch++; + span->max_chans++; + } else { + lib_printf(0,NULL,"Chan %i Not Mapped",i); + } + } + + lib_printf(0,NULL,"Total Chans\t:%i\n",span->max_chans); + + /* Must be configurable */ + span->chunk_sz=span->span_cfg.chunk_sz; + span->tx_size=span->max_chans*span->chunk_sz; + + span->init=1; + span->idle=0xFF; + + span->open_chan = sangoma_hp_tdm_open_chan; + span->close_chan = sangoma_hp_tdm_close_chan; + span->is_chan_closed = sangoma_hp_tdm_is_chan_closed; + span->run_span =sangoma_hp_tdm_run_span; + span->close_span = sangoma_hp_tdm_close_span; + span->event_ctrl = sangoma_hp_tdm_event_ctrl_span; + span->get_cfg = sangoma_hp_tdm_event_get_cfg; + + lib_printf(5, NULL, "Span %i Initialized\n",span->span_no+1); + + return span; +} + +/* + \brief Free, Un-Initialize Span + \param span_no span object + \return 0 = pass, non zero fail + */ + +int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span) +{ + if (span->sock >= 0) { + span->close_span(span); + } + + free(span); + span=NULL; + + return 0; +} + diff --git a/api/libsangoma/.svn/text-base/libhpsangoma.h.svn-base b/api/libsangoma/.svn/text-base/libhpsangoma.h.svn-base new file mode 100644 index 0000000..8467f9d --- /dev/null +++ b/api/libsangoma/.svn/text-base/libhpsangoma.h.svn-base @@ -0,0 +1,324 @@ +/***************************************************************************** + * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 _LIB_HP_SNAGOMA_H +#define _LIB_HP_SNAGOMA_H + + +#ifdef WIN32 + +#error "WINDOWS NOT DEFINED" + +#else +/* L I N U X */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#endif + +#define SMG_HP_MAX_CHAN_DATA 1024 +#define SMG_HP_TDM_CHUNK_IDX_SZ 16 +#define SMG_HP_TDM_MAX_CHANS 31 +#define SMG_HP_MAX_SPAN_DATA (31*160)+32 + +#define hp_tdmapi_rx_event_t api_rx_hdr_t +#define hp_tdmapi_tx_event_t api_tx_hdr_t + +#define SANGOMA_HPTDM_VERSION 1 + +/*--------------------------------------------------------- + * PUBLIC DEFINITIONS + */ + + +/*! + \brief Span registration structure + */ +typedef struct sangoma_hptdm_span_reg +{ + /*! pointer to user object used with callback functions */ + void *p; + /*! callback function to implement library logging */ + void (*log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + /*! callback function to span global events for all channels in a span */ + int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data); +}sangoma_hptdm_span_reg_t; + + +/*! + \brief A chunk structure used to implement a chunk buffer + */ +typedef struct hp_tdm_chunk +{ + /*! chunk init flag used to determine if chunk is being used*/ + int init; + /*! length of the current data chunk */ + int len; + /*! current offset to write/read to/from the chunk data structure. */ + int offset; + /*! chunk data location */ + char data[SMG_HP_MAX_CHAN_DATA]; +}hp_tmd_chunk_t; + +/*! + \brief Chan registration structure + */ +typedef struct sangoma_hptdm_chan_reg +{ + /*! pointer to user object used with callback functions */ + void *p; + /*! callback function used to pass rx chunk to user application */ + int (*rx_data)(void *p, char *data, int len); + /*! callback function used to pass channel specific event to user application */ + int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data); + +}sangoma_hptdm_chan_reg_t; + +/*! + \brief Channel structure, describes a single timeslot/channel in a span. + */ +typedef struct sangoma_hptdm_chan +{ + /*! channel init flag used to determine if chan is being used */ + int init; + + /*! channel number: starting from 0 */ + int chan_no; + + /*! span number the current channel belongs to: starting from 0 */ + int span_no; + + /*! span object pointer the current channel belongs */ + void *span; + + /*! Rx chunk buffer used to rx data from the span */ + hp_tmd_chunk_t rx_chunk; + + /*! Circular buffer of tx data chunks used to tx data to span */ + hp_tmd_chunk_t tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ]; + + /*! Circular buffer index for user to chan tx */ + int tx_idx_in; + + /*! Circular buffer index for chan to span tx */ + int tx_idx_out; + + /*! Callback func called by user to push chunk of data into the channel */ + int (*push)(struct sangoma_hptdm_chan *, char *data, int len); + + /*! Channel registration struct used to store user data, cfg and callbacks */ + sangoma_hptdm_chan_reg_t chan_reg; + +}sangoma_hptdm_chan_t; + +/*! + \brief Structure describing a array index of a channel inside the span structure. + * + * Structure describing a array index of a channel inside the span structure. + * Furthermore the index * also servers as a map from hardware channels to library channels. + * Hardware might be configured for channels 1-15.17-31, however library always + * provides all 31 channels + */ +typedef struct sangoma_hptdm_chan_map +{ + /*! A hardware channel number that is mapped to the current channel structure. + * Hardware might be configured for channels 1-15.17-31, however library always + * provides all 31 channels */ + int chan_no_hw; + + /*! A channel structure */ + sangoma_hptdm_chan_t chan; + +}sangoma_hptdm_chan_map_t; + + +/*! + \brief Span structure. Structure describing a single span. + */ +typedef struct sangoma_hptdm_span +{ + /*! span init flag used to determine if span is being used */ + int init; + + /*! span number - integer starting from 0 */ + int span_no; + + /*! span hw interface name to which span is bounded to */ + char if_name[100]; + + /*! span socket file descriptor used to rx/tx data to and from hw interface */ + int sock; + + /*! chunk size for each channel inside the span */ + int chunk_sz; + + /*! total number of channels configured in the span */ + int max_chans; + + /*! total tx data size to hw interface. tx_size = max_chans * chunk_sz */ + int tx_size; + + /*! idle flag used to fill an unused channel */ + unsigned char idle; + + /*! bit map of configured timeslots obtained from hw interface */ + unsigned int timeslot_cfg; + + /*! hw data encoding: ULAW/ALAW obtained from hw interface */ + unsigned int hwcoding; + + /*! array of maximum number of channels in a span */ + sangoma_hptdm_chan_map_t chan_idx[SMG_HP_TDM_MAX_CHANS]; + + /*! span rx data block: used to receive a block of data from hw interface: recv() */ + char rx_data[SMG_HP_MAX_SPAN_DATA]; + + /*! span rx data len, obtained after a recv() call to hw interface */ + int rx_len; + + /*! span tx data block: used to transmit a block of data to hw interface: send() */ + char tx_data[SMG_HP_MAX_SPAN_DATA]; + + /*! span tx data block len: passed to send() function */ + int tx_len; + + /*! span registration functions: contains user callback functions */ + sangoma_hptdm_span_reg_t span_reg; + + /*! span config structure obtained from hw interface via managment ioctl call. */ + wan_if_cfg_t span_cfg; + + /*! span managment structure used to execute mgmnt ioctl commands to hw interface */ + wan_udp_hdr_t wan_udp; + + /*! \brief Method: open a channel inside a span + * \param span span object + * \param chan_reg channel registration structure: callbacks and cfg + * \param chan_no channel number - integer starting from 0 + * \param chan_ptr user container for channel object passed up to the user. + */ + int (*open_chan)(struct sangoma_hptdm_span *span, + sangoma_hptdm_chan_reg_t *chan_reg, + unsigned int chan_no, + sangoma_hptdm_chan_t **chan_ptr); + + /*! \brief Method: close a channel inside the span + * \param chan chan object + */ + int (*close_chan)(sangoma_hptdm_chan_t *chan); + + /*! \brief Method: check if channel is closed + * \param chan chan object */ + int (*is_chan_closed)(sangoma_hptdm_chan_t *chan); + + /*! \brief Method: run main span execution logic: rx/tx/oob + * \param span span object + * + * Run main span execution logic. This function peforms all socket operations + * on a hw interface. Rx/Tx/Oob. + * Receives data and demultiplexes it to channels. + * Receives oob data and passes user events global to all channels. + * Multiplexes all channel tx data into a single tx data block and + * passes it to hw iface. + */ + int (*run_span)(struct sangoma_hptdm_span *span); + + /*! \brief Method: close span + * \param span span object */ + int (*close_span)(struct sangoma_hptdm_span *span); + + /*! \brief Method: used by user app to execute events on current span + * \param span span object + * \param event event object + */ + int (*event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event); + + /*! \brief Method: request full span configuration from a current span + * \param span span object + * \param cfg configuratoin object to be filled by span + */ + int (*get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg); + + +}sangoma_hptdm_span_t; + +/*--------------------------------------------------------- + * PUBLIC FUNCTIONS + */ + +/*! + \brief Initialize and Configure a Span + \param span_no span number - integer + \param cfg span registration struct + \return NULL: fail, Span Object: pass + */ + +/* Initialize and Configure a Span */ +#define sangoma_hptdm_api_span_init(span,cfg) __sangoma_hptdm_api_span_init(span, cfg, SANGOMA_HPTDM_VERSION); + +/*! + \brief Initialize and Configure Span - private functions not to be used directly! + \param span_no span number - integer + \param cfg span registration struct + \param version library version number added by the macro + \return NULL: fail, Span Object: pass + * + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ + + /* + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ +extern sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version); + + +/*! + \brief Free, Un-Initialize Span + \param span_no span object + \return 0 = pass, non zero fail + */ +extern int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span); + + + + + +#endif + diff --git a/api/libsangoma/.svn/text-base/libhpsangoma_priv.c.svn-base b/api/libsangoma/.svn/text-base/libhpsangoma_priv.c.svn-base new file mode 100644 index 0000000..778fe06 --- /dev/null +++ b/api/libsangoma/.svn/text-base/libhpsangoma_priv.c.svn-base @@ -0,0 +1,403 @@ +/***************************************************************************** + * libhpsangoma_priv.c: Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 "libhpsangoma.h" +#include "libhpsangoma_priv.h" +#define DFT_CARD "wanpipe1" + + +/*! + \brief Span read data from a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail +*/ +int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag) +{ + int rx_len=0; + +#if defined(WIN32) + +#error "WINDOWS HP TDMAPI NOT DEFINED" + +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + rx_len = recvmsg(fd,&msg,0); + + if (rx_len <= sizeof(api_rx_hdr_t)){ + return -EINVAL; + } + + rx_len-=sizeof(api_rx_hdr_t); +#endif + + return rx_len; +} + + + +/*! + \brief Span write data into a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail +*/ +int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag) +{ + int bsent; + +#if defined(WIN32) + +#error "Windows TX not implemented" + +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + bsent = sendmsg(fd,&msg,0); + if (bsent > 0){ + bsent-=sizeof(api_tx_hdr_t); + } +#endif + return bsent; +} + +/*! + \brief Execute a management ioctl command + \param span span object + \return 0 = pass, non zero fail + */ +int do_wanpipemon_cmd(sangoma_hptdm_span_t *span) +{ + struct ifreq ifr; + memset(&ifr,0,sizeof(ifr)); + ifr.ifr_data = (void*)&span->wan_udp; + sprintf (ifr.ifr_name, "%s", span->if_name); + return ioctl(span->sock,SIOC_WANPIPE_PIPEMON,&ifr); +} + +/*! + \brief Get full span hw configuration + \param span span object + \return 0 = pass, non zero fail + */ +unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span) +{ + span->wan_udp.wan_udphdr_command = READ_CONFIGURATION; + span->wan_udp.wan_udphdr_data_len = 0; + span->wan_udp.wan_udphdr_return_code = 0xaa; + do_wanpipemon_cmd(span); + if (span->wan_udp.wan_udphdr_return_code != 0){ + lib_printf(0,NULL,"Error: SPAN %i management command failed 0x02Xs (%s)", + span->span_no+1, span->wan_udp.wan_udphdr_return_code,strerror(errno)); + return -1; + } + + memcpy(&span->span_cfg,&span->wan_udp.wan_udphdr_data[0],sizeof(span->span_cfg)); + + return 0; +} + + +/*! + \brief Open socket to span hw interface + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span) +{ + struct wan_sockaddr_ll sa; + char if_name[100]; + int sock=-1; + int err; + + memset(&sa,0,sizeof(struct wan_sockaddr_ll)); + sock = socket(AF_WANPIPE, SOCK_RAW, 0); + if( sock < 0 ) { + perror("Socket"); + return -1; + } /* if */ + + sprintf(if_name, "w%ig1", span->span_no+1); + + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, DFT_CARD); + sa.sll_protocol = htons(PVC_PROT); + sa.sll_family=AF_WANPIPE; + + if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){ + lib_printf(0,NULL,"bind failed on span span %i %s\n", + span->span_no+1,strerror(errno)); + return -1; + } + + span->sock=sock; + + err= sangoma_get_cfg(span); + if (err) { + goto sangoma_hptdm_span_open_error; + } + + lib_printf(0,NULL,"libhp: span %i opened\n", + span->span_no+1); + + return 0; + +sangoma_hptdm_span_open_error: + + if (span->sock) { + close(span->sock); + span->sock=-1; + } + + return err; +} + + +/*! + \brief Read oob event from hw and push oob event up to the user. Called after select() + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span) +{ + int err; + hp_tdmapi_rx_event_t *rx_event; + + err = recv(span->sock, span->rx_data, sizeof(span->rx_data), MSG_OOB); + if (err > 0) { + rx_event=(hp_tdmapi_rx_event_t*)&span->rx_data; + if (span->span_reg.rx_event && span->span_reg.p) { + span->span_reg.rx_event(span->span_reg.p, rx_event); + } + } + /* For now treat all err as socket reload */ + return 1; +} + +/*! + \brief Multiplex span rx data and push it up to each channel + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span) +{ + int i=0,x=0,err=0; + sangoma_hptdm_chan_t *chan=NULL; + hp_tmd_chunk_t *chunk=NULL; + int chan_no_hw; + char *rx_data = &span->rx_data[sizeof(api_rx_hdr_t)]; + + + for (i=0;ichan_idx[i].chan; + if (!chan->init) { + continue; + } + chan_no_hw = span->chan_idx[i].chan_no_hw; + + lib_printf(15,NULL, "SPAN %i Chan %i Chunk %i Channelizing\n", + span->span_no+1, chan->chan_no+1, span->chunk_sz); + + chunk = &chan->rx_chunk; + + for (x=0;xchunk_sz;x++) { + chunk->data[x] = rx_data[(span->max_chans*x)+chan_no_hw]; + } + + chunk->len = span->chunk_sz; + if (chan->chan_reg.p && chan->chan_reg.rx_data) { + err=chan->chan_reg.rx_data(chan->chan_reg.p,chunk->data,chunk->len); + } else { + err=1; + } + + if (err) { + chan->init=0; + chan->chan_reg.p=NULL; + } + + } + + return err; + + +} + +/*! + \brief Read data from hw interface and pass it up to the rxdata handler: called by run_span() + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span) +{ + int err; + hp_tdmapi_rx_event_t *rx_event = (hp_tdmapi_rx_event_t*)&span->rx_data[0]; + + err = sangoma_readmsg_hp_tdm(span->sock, + &span->rx_data[0],sizeof(api_rx_hdr_t), + &span->rx_data[sizeof(api_rx_hdr_t)], + sizeof(span->rx_data) - sizeof(api_rx_hdr_t), + 0); + + if (err > sizeof(api_rx_hdr_t)) { + + lib_printf(15,NULL, "SPAN %i Read Len = %i\n",span->span_no+1,err); + + if (rx_event->event_type) { + + if (span->span_reg.rx_event && span->span_reg.p) { + span->span_reg.rx_event(span->span_reg.p, rx_event); + } + + } else { + + if (err % span->chunk_sz) { + lib_printf(0,NULL, "Error: SPAN %i Read Len = %i Block not chunk %i aligned! \n",span->span_no+1,err,span->chunk_sz); + /* Received chunk size is not aligned drop it for now */ + return 0; + } + + sangoma_hp_tdm_push_rx_data(span); + } + + err=0; + + } else { + if (errno == EAGAIN) { + err = 0; + } else { + err=-1; + } + } + + return err; +} + + +/*! + \brief Pull data from all chans and write data to hw interface: called by run_span() + \param span span object + \return 0 = pass, non zero fail +*/ +int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span) +{ + int i=0,x=0,err=0; + sangoma_hptdm_chan_t *chan; + hp_tmd_chunk_t *chunk; + int chan_no_hw=0; + char *tx_data = &span->tx_data[sizeof(api_tx_hdr_t)]; + + memset(&span->tx_data,span->idle,sizeof(span->tx_data)); + + + for (i=0;ichan_idx[i].chan; + if (!chan->init) { + /* This channel is not open */ + continue; + } + chan_no_hw=span->chan_idx[i].chan_no_hw; + + chunk = &chan->tx_idx[chan->tx_idx_out]; + if (!chunk->init) { + lib_printf(15,NULL,"span write s%ic%i tx chunk underrun out %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_out); + /* There is no tx data for this channel */ + continue; + } + + for (x=0;xchunk_sz;x++) { + + tx_data[(span->max_chans*x)+chan_no_hw] = chunk->data[chunk->offset]; + chunk->offset++; + + if (chunk->offset >= chunk->len) { + chunk->init=0; + + lib_printf(15,NULL,"span write s%ic%i tx chunk out %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_out); + + chan->tx_idx_out++; + if (chan->tx_idx_out >= SMG_HP_TDM_CHUNK_IDX_SZ) { + chan->tx_idx_out=0; + } + chunk=&chan->tx_idx[chan->tx_idx_out]; + if (!chunk->init) { + /* We are out of tx data on this channel */ + break; + } + } + } + } + + + err = sangoma_writemsg_hp_tdm(span->sock, + span->tx_data,sizeof(api_tx_hdr_t), + tx_data, span->tx_size, + 0); + + lib_printf(15, NULL, "SPAN %i TX Len %i Expecting %i\n", + span->span_no+1, err, span->tx_size+sizeof(api_tx_hdr_t)); + + if (err < span->tx_size) { + if (errno == EAGAIN) { + return 0; + } else { + return -1; + } + } else { + err=0; + } + + return err; + +} diff --git a/api/libsangoma/.svn/text-base/libhpsangoma_priv.h.svn-base b/api/libsangoma/.svn/text-base/libhpsangoma_priv.h.svn-base new file mode 100644 index 0000000..3d10f0a --- /dev/null +++ b/api/libsangoma/.svn/text-base/libhpsangoma_priv.h.svn-base @@ -0,0 +1,118 @@ +/***************************************************************************** + * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 _LIB_HP_SANGOMA_PRIV_H +#define _LIB_HP_SANGOMA_PRIV_H + +#include "libhpsangoma.h" + + +/*! + \brief library print function based on registered span callback function + \return void + */ +#define lib_printf(level, fp, fmt, ...) if (lib_log) lib_log(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + +extern void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + + +/*--------------------------------------------------------- + * PRIVATE - FUNCTIONS + */ + +/*! + \brief Span read data from a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail + */ +int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag); + + +/*! + \brief Span write data into a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail + */ +int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag); + +/*! + \brief Execute a management ioctl command + \param span span object + \return 0 = pass, non zero fail + */ +int do_wanpipemon_cmd(sangoma_hptdm_span_t *span); + + +/*! + \brief Get full span hw configuration + \param span span object + \return 0 = pass, non zero fail + */ +unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span); + + +/*! + \brief Open socket to span hw interface + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span); + + +/*! + \brief Read oob event from hw and push oob event up to the user. Called after select() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span); + + +/*! + \brief Multiplex span rx data and push it up to each channel + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span); + + +/*! + \brief Read data from hw interface and pass it up to the rxdata handler: called by run_span() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span); + + +/*! + \brief Pull data from all chans and write data to hw interface: called by run_span() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span); + + + + +#endif + diff --git a/api/libsangoma/.svn/text-base/libsangoma.c.svn-base b/api/libsangoma/.svn/text-base/libsangoma.c.svn-base index 55f7a23..7a1c738 100644 --- a/api/libsangoma/.svn/text-base/libsangoma.c.svn-base +++ b/api/libsangoma/.svn/text-base/libsangoma.c.svn-base @@ -227,7 +227,11 @@ sng_fd_t sangoma_open_tdmapi_ctrl(void) { int fd=-1; +#if defined(WIN32) +#warning "sangoma_open_tdmapi_ctrl: Not support on Windows" +#else fd = open("/dev/wptdm_ctrl", O_RDWR); +#endif return fd; } @@ -662,6 +666,7 @@ int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api) return tdm_api->wp_tdm_cmd.hw_tdm_coding; } +#ifdef WP_TDM_FEATURE_DTMF_EVENTS /*======================================================== * GET Current User Hardware DTMF Enabled/Disabled * @@ -678,6 +683,7 @@ int sangoma_tdm_get_hw_dtmf(int fd, wanpipe_tdm_api_t *tdm_api) } return tdm_api->wp_tdm_cmd.hw_dtmf; } +#endif /*======================================================== * GET Current User MTU/MRU values in bytes. @@ -949,7 +955,6 @@ 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) { @@ -1169,6 +1174,8 @@ 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; @@ -1214,7 +1221,6 @@ int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return tdm_api->wp_tdm_cmd.fe_alarms; } -#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) @@ -1227,6 +1233,7 @@ int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned return err; } +#endif /* get current Line Connection state - Connected/Disconnected */ #ifdef WP_TDM_FEATURE_LINK_STATUS @@ -1240,7 +1247,6 @@ int sangoma_tdm_get_link_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigne return err; } -#endif /* 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) @@ -1250,5 +1256,6 @@ int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned return sangoma_tdm_cmd_exec(fd, tdm_api); } +#endif #endif /* WANPIPE_TDM_API */ 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 deleted file mode 100644 index 48940b9..0000000 --- a/api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index 4965420..0000000 --- a/api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -Added new event features ---This line, and those below, will be ignored-- - -M libsangoma.c -M libsangoma.h diff --git a/api/libsangoma/.svn/tmp/tempfile.7.tmp b/api/libsangoma/.svn/tmp/tempfile.7.tmp new file mode 100644 index 0000000..7a1c738 --- /dev/null +++ b/api/libsangoma/.svn/tmp/tempfile.7.tmp @@ -0,0 +1,1261 @@ +/***************************************************************************** + * libsangoma.c AFT T1/E1: HDLC API Code Library + * + * Author(s): Anthony Minessale II + * Nenad Corbic + * David Rokhvarg + * Michael Jerris + * + * 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. + * ============================================================================ + * + * Aug 15, 2006 David Rokhvarg Ported to MS Windows 2000/XP + * Sep 24, 2006 Michael Jerris Windows port, standardize api, cleanup + * + */ + +#include "libsangoma.h" +#define DFT_CARD "wanpipe1" + +#ifndef WP_TDM_FEATURE_FE_ALARM +#warning "Warning: TDM FE ALARM not supported by driver" +#endif + +#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 + +#ifndef WP_TDM_FEATURE_LINK_STATUS +#warning "Warning: TDM LINK STATUS not supported by driver" +#endif + + +#if defined(WIN32) +//extern int verbose; + +#define DEV_NAME_LEN 100 +char device_name[DEV_NAME_LEN]; + +/* IOCTL management structures and variables*/ +wan_udp_hdr_t wan_udp; + +#include "win_api_common.h" + +static wan_cmd_api_t api_cmd; +static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data; + +/* keeps the LAST (and single) event received */ +static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer; + +#endif /* WIN32 */ + +void sangoma_socket_close(sng_fd_t *sp) +{ +#if defined(WIN32) + if( *sp != INVALID_HANDLE_VALUE){ + CloseHandle(*sp); + *sp = INVALID_HANDLE_VALUE; + } +#else + if (*sp > -1) { + close(*sp); + *sp = -1; + } +#endif +} + +int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags) +{ +#if defined(WIN32) + API_POLL_STRUCT api_poll; + + memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT)); + + api_poll.user_flags_bitmap = flags; + + if(DoApiPollCommand(fd, &api_poll)){ + //failed + return 0; + } + + switch(api_poll.operation_status) + { + case SANG_STATUS_RX_DATA_AVAILABLE: + break; + + default: + prn(1, "Error: sangoma_socket_waitfor(): Unknown Operation Status: %d\n", + api_poll.operation_status); + return 0; + }//switch() + + if(api_poll.poll_events_bitmap == 0){ + prn(1, "Error: invalid Poll Events bitmap: 0x%X\n", + api_poll.poll_events_bitmap); + } + return api_poll.poll_events_bitmap; +#else + 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 & POLLERR)) { + res = -1; + } else if((pfds[0].revents)) { + res = 1; + } + } + + return res; +#endif +} + + +int sangoma_span_chan_toif(int span, int chan, char *interface_name) +{ + sprintf(interface_name,"s%ic%i",span,chan); + return 0; +} + +int sangoma_interface_toi(char *interface_name, int *span, int *chan) +{ + char *p=NULL, *sp = NULL, *ch = NULL; + int ret = 0; + char data[FNAME_LEN]; + + strncpy(data, interface_name, FNAME_LEN); + if ((data[0])) { + for (p = data; *p; p++) { + if (sp && *p == 'g') { + *p = '\0'; + ch = (p + 1); + break; + } else if (*p == 'w') { + sp = (p + 1); + } + } + + if(ch && sp) { + *span = atoi(sp); + *chan = atoi(ch); + ret = 1; + } else { + *span = -1; + *chan = -1; + } + } + + return ret; +} + +int sangoma_span_chan_fromif(char *interface_name, int *span, int *chan) +{ + char *p = NULL, *sp = NULL, *ch = NULL; + int ret = 0; + char data[FNAME_LEN]; + + strncpy(data, interface_name, FNAME_LEN); + if ((data[0])) { + for (p = data; *p; p++) { + if (sp && *p == 'c') { + *p = '\0'; + ch = (p + 1); + break; + } else if (*p == 's') { + sp = (p + 1); + } + } + + if(ch && sp) { + *span = atoi(sp); + *chan = atoi(ch); + ret = 1; + } else { + *span = -1; + *chan = -1; + } + } + + return ret; +} + +sng_fd_t sangoma_open_tdmapi_span_chan(int span, int chan) +{ + char fname[FNAME_LEN]; +#if defined(WIN32) + + //NOTE: under Windows Interfaces are zero based but 'chan' is 1 based. + // Subtract 1 from 'chan'. + _snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1); + + //prn(verbose, "Opening device: %s...\n", fname); + + return CreateFile( fname, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, + (HANDLE)NULL + ); +#else + int fd=-1; + + sprintf(fname,"/dev/wptdm_s%dc%d",span,chan); + + fd = open(fname, O_RDWR); + + return fd; +#endif +} + + +sng_fd_t sangoma_open_tdmapi_ctrl(void) +{ + int fd=-1; + +#if defined(WIN32) +#warning "sangoma_open_tdmapi_ctrl: Not support on Windows" +#else + fd = open("/dev/wptdm_ctrl", O_RDWR); +#endif + + return fd; +} + +sng_fd_t sangoma_create_socket_by_name(char *device, char *card) +{ + int span,chan; + sangoma_interface_toi(device,&span,&chan); + + return sangoma_open_tdmapi_span_chan(span,chan); +} + + +sng_fd_t sangoma_open_tdmapi_span(int span) +{ + int i=0; +#if defined(WIN32) + sng_fd_t fd = INVALID_HANDLE_VALUE; + + for(i = 1; i < 32; i++){ + if((fd = sangoma_open_tdmapi_span_chan(span, i)) == INVALID_HANDLE_VALUE){ + //prn(verbose, "Span: %d, chan: %d: is not running, consider 'busy'\n", + // span, i); + continue; + } + + //get the open handle counter + wan_udp.wan_udphdr_command = GET_OPEN_HANDLES_COUNTER; + wan_udp.wan_udphdr_data_len = 0; + + DoManagementCommand(fd, &wan_udp); + if(wan_udp.wan_udphdr_return_code){ + prn(1, "Error: command GET_OPEN_HANDLES_COUNTER failed! Span: %d, chan: %d\n", + span, i); + //don't forget to close!! otherwize counter will stay incremented. + sangoma_socket_close(&fd); + continue; + } + + //prn(verbose, "open handles counter: %d\n", *(int*)&wan_udp.wan_udphdr_data[0]); + if(*(int*)&wan_udp.wan_udphdr_data[0] == 1){ + //this is the only process using this chan/span, so it is 'free' + //prn(verbose, "Found 'free' Span: %d, chan: %d\n",span, i); + break; + } + //don't forget to close!! otherwize counter will stay incremented. + sangoma_socket_close(&fd); + }//for() + +#else + char fname[FNAME_LEN]; + int fd=0; + for (i=1;i<32;i++){ + sprintf(fname,"/dev/wptdm_s%dc%d",span,i); + fd = open(fname, O_RDWR); + if (fd < 0){ + continue; + } + break; + } +#endif + return fd; +} + +int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag) +{ + int rx_len=0; + +#if defined(WIN32) + static RX_DATA_STRUCT rx_data; + api_header_t *pri; + wp_tdm_api_rx_hdr_t *tdm_api_rx_hdr; + wp_tdm_api_rx_hdr_t *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf; + + if(hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){ + //error + prn(1, "Error: sangoma_readmsg_tdm(): invalid size of user's 'header buffer'.\ +Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n"); + return -1; + } + + if(DoReadCommand(fd, &rx_data) ){ + //error + prn(1, "Error: DoReadCommand() failed! Check messages log.\n"); + return -1; + } + + //use our special buffer at rxdata to hold received data + pri = &rx_data.api_header; + tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t*)rx_data.data; + + user_buf->wp_tdm_api_event_type = pri->operation_status; + + switch(pri->operation_status) + { + case SANG_STATUS_RX_DATA_AVAILABLE: + //prn(verbose, "SANG_STATUS_RX_DATA_AVAILABLE\n"); + + if(pri->data_length > datalen){ + rx_len=0; + break; + } + memcpy(databuf, rx_data.data, pri->data_length); + rx_len = pri->data_length; + break; + + case SANG_STATUS_TDM_EVENT_AVAILABLE: + //prn(verbose, "SANG_STATUS_TDM_EVENT_AVAILABLE\n"); + + //make event is accessable for the caller directly: + memcpy(databuf, rx_data.data, pri->data_length); + rx_len = pri->data_length; + + //make copy for use with sangoma_tdm_read_event() - indirect access. + memcpy( &last_tdm_api_event_buffer, tdm_api_rx_hdr, sizeof(wp_tdm_api_rx_hdr_t)); + break; + + default: + switch(pri->operation_status) + { + case SANG_STATUS_RX_DATA_TIMEOUT: + //no data in READ_CMD_TIMEOUT, try again. + prn(1, "Error: Timeout on read.\n"); + break; + + case SANG_STATUS_BUFFER_TOO_SMALL: + //Recieved data longer than the pre-configured maximum. + //Maximum length is set in 'Interface Properties', + //in the 'Device Manager'. + prn(1, "Error: Received data longer than buffer passed to API.\n"); + break; + + case SANG_STATUS_LINE_DISCONNECTED: + //Front end monitoring is enabled and Line is + //in disconnected state. + //Check the T1/E1 line is in "Connected" state, + //alse check the Alarms and the message log. + prn(1, "Error: Line disconnected.\n"); + break; + + default: + prn(1, "Rx:Unknown Operation Status: %d\n", pri->operation_status); + break; + }//switch() + return 0; + }//switch() + +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + rx_len = read(fd,&msg,datalen+hdrlen); + + if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)){ + return -EINVAL; + } + + rx_len-=sizeof(wp_tdm_api_rx_hdr_t); +#endif + return rx_len; +} + +int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag) +{ + int bsent; + +#if defined(WIN32) + static TX_DATA_STRUCT local_tx_data; + api_header_t *pri; + + pri = &local_tx_data.api_header; + + pri->data_length = datalen; + memcpy(local_tx_data.data, databuf, pri->data_length); + + //queue data for transmission + if( DoWriteCommand(fd, &local_tx_data)){ + //error + prn(1, "Error: DoWriteCommand() failed!! Check messages log.\n"); + return -1; + } + + bsent=0; + //check that frame was transmitted + switch(local_tx_data.api_header.operation_status) + { + case SANG_STATUS_SUCCESS: + bsent = datalen; + break; + + case SANG_STATUS_TX_TIMEOUT: + //error + prn(1, "****** Error: SANG_STATUS_TX_TIMEOUT ******\n"); + //Check messages log or look at statistics. + break; + + case SANG_STATUS_TX_DATA_TOO_LONG: + //Attempt to transmit data longer than the pre-configured maximum. + //Maximum length is set in 'Interface Properties', + //in the 'Device Manager'. + prn(1, "****** SANG_STATUS_TX_DATA_TOO_LONG ******\n"); + break; + + case SANG_STATUS_TX_DATA_TOO_SHORT: + //Minimum is 1 byte for Primary port, + // 2 bytes for Secondary port + prn(1, "****** SANG_STATUS_TX_DATA_TOO_SHORT ******\n"); + break; + + case SANG_STATUS_LINE_DISCONNECTED: + //Front end monitoring is enabled and Line is + //in disconnected state. + //Check the T1/E1 line is in "Connected" state, + //alse check the Alarms and the message log. + prn(1, "****** SANG_STATUS_LINE_DISCONNECTED ******\n"); + break; + + default: + prn(1, "Unknown return code (0x%X) on transmission!\n", + local_tx_data.api_header.operation_status); + break; + }//switch() +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + bsent = write(fd,&msg,datalen+hdrlen); + if (bsent > 0){ + bsent-=sizeof(wp_tdm_api_tx_hdr_t); + } +#endif + return bsent; +} + + +#ifdef WANPIPE_TDM_API + +/*======================================================== + * Execute TDM command + * + */ +static int sangoma_tdm_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + +#if defined(WIN32) + err = tdmv_api_ioctl(fd, &tdm_api->wp_tdm_cmd); +#else + err = ioctl(fd,SIOC_WANPIPE_TDM_API,&tdm_api->wp_tdm_cmd); + if (err < 0){ + char tmp[50]; + sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_tdm_cmd.cmd); + perror(tmp); + return -1; + } +#endif + return err; +} + +/*======================================================== + * Get Full TDM API configuration per channel + * + */ +int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FULL_CFG; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + +#if 0 + printf("TDM API CFG:\n"); + printf("\thw_tdm_coding:\t%d\n",tdm_api->wp_tdm_cmd.hw_tdm_coding); + printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_tdm_cmd.hw_mtu_mru); + printf("\tusr_period:\t%d\n",tdm_api->wp_tdm_cmd.usr_period); + printf("\ttdm_codec:\t%d\n",tdm_api->wp_tdm_cmd.tdm_codec); + printf("\tpower_level:\t%d\n",tdm_api->wp_tdm_cmd.power_level); + printf("\trx_disable:\t%d\n",tdm_api->wp_tdm_cmd.rx_disable); + printf("\ttx_disable:\t%d\n",tdm_api->wp_tdm_cmd.tx_disable); + 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_FEATURE_FE_ALARM + printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_tdm_cmd.fe_alarms); +#endif + + printf("\trx pkt\t%d\ttx pkt\t%d\n",tdm_api->wp_tdm_cmd.stats.rx_packets, + tdm_api->wp_tdm_cmd.stats.tx_packets); + printf("\trx err\t%d\ttx err\t%d\n", + tdm_api->wp_tdm_cmd.stats.rx_errors, + tdm_api->wp_tdm_cmd.stats.tx_errors); +#ifndef __WINDOWS__ + printf("\trx ovr\t%d\ttx idl\t%d\n", + tdm_api->wp_tdm_cmd.stats.rx_fifo_errors, + tdm_api->wp_tdm_cmd.stats.tx_carrier_errors); +#endif +#endif + + return 0; +} + +/*======================================================== + * SET Codec on a particular Channel. + * + * Available codecs are defined in + * /usr/src/linux/include/linux/wanpipe_cfg.h + * + * enum wan_codec_format { + * WP_NONE, + * WP_SLINEAR + * } + * + */ +int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int codec) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC; + tdm_api->wp_tdm_cmd.tdm_codec = codec; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + + return err; +} + +/*======================================================== + * GET Codec from a particular Channel. + * + * Available codecs are defined in + * /usr/src/linux/include/linux/wanpipe_cfg.h + * + * enum wan_codec_format { + * WP_NONE, + * WP_SLINEAR + * } + * + */ +int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_CODEC; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.tdm_codec; +} + +/*======================================================== + * SET Rx/Tx Hardware Period in milliseconds. + * + * Available options are: + * 10,20,30,40,50 ms + * + */ +int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int period) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD; + tdm_api->wp_tdm_cmd.usr_period = period; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + + return err; +} + +/*======================================================== + * GET Rx/Tx Hardware Period in milliseconds. + * + * Available options are: + * 10,20,30,40,50 ms + * + */ +int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.usr_period; +} + +/*======================================================== + * GET Current User Hardware Coding Format + * + * Coding Format will be ULAW/ALAW based on T1/E1 + */ + +int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + return tdm_api->wp_tdm_cmd.hw_tdm_coding; +} + +#ifdef WP_TDM_FEATURE_DTMF_EVENTS +/*======================================================== + * GET Current User Hardware DTMF Enabled/Disabled + * + * Will return true if HW DTMF is enabled on Octasic + */ + +int sangoma_tdm_get_hw_dtmf(int fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_DTMF; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + return tdm_api->wp_tdm_cmd.hw_dtmf; +} +#endif + +/*======================================================== + * GET Current User MTU/MRU values in bytes. + * + * The USER MTU/MRU values will change each time a PERIOD + * or CODEC is adjusted. + */ +int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_MTU_MRU; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.usr_mtu_mru; +} + +/*======================================================== + * SET TDM Power Level + * + * This option is not implemented yet + * + */ +int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int power) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_POWER_LEVEL; + tdm_api->wp_tdm_cmd.power_level = power; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + + return err; +} + +/*======================================================== + * GET TDM Power Level + * + * This option is not implemented yet + * + */ +int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_POWER_LEVEL; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.power_level; +} + +int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ +#if 0 + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_FLUSH_BUFFERS; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } +#endif + return 0; +} + +int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int poll_in_sec) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RBS_EVENTS; + tdm_api->wp_tdm_cmd.rbs_poll=poll_in_sec; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.rbs_poll; +} + + +int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RBS_EVENTS; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char rbs) +{ + + int err; + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS; + tdm_api->wp_tdm_cmd.rbs_tx_bits=rbs; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + +#ifdef WP_TDM_FEATURE_EVENTS + + wp_tdm_api_event_t *rx_event; + +#if defined(WIN32) + rx_event = &last_tdm_api_event_buffer; +#else + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + rx_event = &tdm_api->wp_tdm_cmd.event; +#endif + + + switch (rx_event->wp_tdm_api_event_type){ + + case WP_TDMAPI_EVENT_RBS: + if (tdm_api->wp_tdm_event.wp_rbs_event) { + tdm_api->wp_tdm_event.wp_rbs_event(fd,rx_event->wp_tdm_api_event_rbs_bits); + } + + break; + +#ifdef WP_TDM_FEATURE_DTMF_EVENTS + case WP_TDMAPI_EVENT_DTMF: + if (tdm_api->wp_tdm_event.wp_dtmf_event) { + tdm_api->wp_tdm_event.wp_dtmf_event(fd, + rx_event->wp_tdm_api_event_dtmf_digit, + rx_event->wp_tdm_api_event_dtmf_type, + rx_event->wp_tdm_api_event_dtmf_port); + } + break; +#endif + + case WP_TDMAPI_EVENT_RXHOOK: + if (tdm_api->wp_tdm_event.wp_rxhook_event) { + tdm_api->wp_tdm_event.wp_rxhook_event(fd, + rx_event->wp_tdm_api_event_hook_state); + } + break; + + case WP_TDMAPI_EVENT_RING_DETECT: + if (tdm_api->wp_tdm_event.wp_ring_detect_event) { + tdm_api->wp_tdm_event.wp_ring_detect_event(fd, + rx_event->wp_tdm_api_event_ring_state); + } + break; + + case WP_TDMAPI_EVENT_RING_TRIP_DETECT: + if (tdm_api->wp_tdm_event.wp_ring_trip_detect_event) { + tdm_api->wp_tdm_event.wp_ring_trip_detect_event(fd, + rx_event->wp_tdm_api_event_ring_state); + } + break; + +#ifdef WP_TDM_FEATURE_FE_ALARM + case WP_TDMAPI_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_alarm); + } + break; +#endif + +#ifdef WP_TDM_FEATURE_LINK_STATUS + /* Link Status */ + case WP_TDMAPI_EVENT_LINK_STATUS: + if(tdm_api->wp_tdm_event.wp_link_status_event){ + tdm_api->wp_tdm_event.wp_link_status_event(fd, + rx_event->wp_tdm_api_event_link_status); + } + + break; +#endif + default: + printf("%d: Unknown TDM event!", (int)fd); + break; + } + + return 0; +#else + printf("Error: Read Event not supported!\n"); + return -1; +#endif +} + +#ifdef WP_TDM_FEATURE_DTMF_EVENTS +int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_DTMF; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_DTMF; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RM_DTMF; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RM_DTMF; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RXHOOK; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + 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; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RXHOOK; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.rbs_poll; +} + + +int sangoma_tdm_disable_ring_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_enable_ring_detect_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_DETECT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.rbs_poll; +} + + +int sangoma_tdm_disable_ring_detect_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_DETECT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_enable_ring_trip_detect_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_TRIP_DETECT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.rbs_poll; +} + + +int sangoma_tdm_disable_ring_trip_detect_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_DETECT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_KEWL; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_START; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + + +int sangoma_tdm_enable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int tone_id) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TONE; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_tone_type = tone_id; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.rbs_poll; +} + +int sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { + + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TONE; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE; + tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_tone_type = 0x00; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + 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_FEATURE_FE_ALARM +int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_ALARMS; + + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return tdm_api->wp_tdm_cmd.fe_alarms; +} + +/* 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; +} +#endif + +/* get current Line Connection state - Connected/Disconnected */ +#ifdef WP_TDM_FEATURE_LINK_STATUS +int sangoma_tdm_get_link_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_LINK_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 + +#endif /* WANPIPE_TDM_API */ diff --git a/api/libsangoma/Makefile.mine b/api/libsangoma/.svn/tmp/tempfile.8.tmp similarity index 88% rename from api/libsangoma/Makefile.mine rename to api/libsangoma/.svn/tmp/tempfile.8.tmp index 6d7b323..c795ab6 100644 --- a/api/libsangoma/Makefile.mine +++ b/api/libsangoma/.svn/tmp/tempfile.8.tmp @@ -75,9 +75,12 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libsangoma_la_LIBADD = am__libsangoma_la_SOURCES_DIST = libsangoma.c libsangoma.h \ - sangoma_pri.c sangoma_pri.h + libhpsangoma.c libhpsangoma.h libhpsangoma_priv.c \ + libhpsangoma_priv.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__objects_2 = libsangoma_la-libsangoma.lo \ + libsangoma_la-libhpsangoma.lo \ + libsangoma_la-libhpsangoma_priv.lo $(am__objects_1) am_libsangoma_la_OBJECTS = $(am__objects_2) libsangoma_la_OBJECTS = $(am_libsangoma_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) @@ -94,7 +97,8 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 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 +am__library_include_HEADERS_DIST = libsangoma.h libhpsangoma.h \ + sangoma_pri.h library_includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(library_include_HEADERS) ETAGS = etags @@ -110,14 +114,28 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print +<<<<<<< .mine ACLOCAL = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run aclocal-1.9 +======= +ACLOCAL = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run aclocal-1.9 +>>>>>>> .r20 AMDEP_FALSE = # AMDEP_TRUE = +<<<<<<< .mine AMTAR = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run tar +======= +AMTAR = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run tar +>>>>>>> .r20 AR = ar +<<<<<<< .mine 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 +======= +AUTOCONF = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run autoconf +AUTOHEADER = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run autoheader +AUTOMAKE = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run automake-1.9 +>>>>>>> .r20 AWK = gawk CC = gcc CCDEPMODE = depmode=gcc3 @@ -151,7 +169,11 @@ LIBS = LIBTOOL = $(SHELL) $(top_builddir)/libtool LN_S = ln -s LTLIBOBJS = +<<<<<<< .mine MAKEINFO = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run makeinfo +======= +MAKEINFO = ${SHELL} /usr/src/ssmg/libsangoma.trunk/missing --run makeinfo +>>>>>>> .r20 OBJEXT = o PACKAGE = libsangoma PACKAGE_BUGREPORT = anthmct@yahoo.com @@ -196,7 +218,11 @@ host_os = linux-gnu host_vendor = pc includedir = ${prefix}/include infodir = ${prefix}/info +<<<<<<< .mine install_sh = /root/3.3/wanpipe/api/libsangoma/install-sh +======= +install_sh = /usr/src/ssmg/libsangoma.trunk/install-sh +>>>>>>> .r20 libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec libpripath = @@ -215,9 +241,10 @@ 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) +LIB_SOURCES = libsangoma.c libsangoma.h libhpsangoma.c libhpsangoma.h \ + libhpsangoma_priv.c libhpsangoma_priv.h $(am__append_1) library_includedir = $(includedir) -library_include_HEADERS = libsangoma.h $(am__append_2) +library_include_HEADERS = libsangoma.h libhpsangoma.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) @@ -331,6 +358,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +include ./$(DEPDIR)/libsangoma_la-libhpsangoma.Plo +include ./$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo include ./$(DEPDIR)/libsangoma_la-libsangoma.Plo include ./$(DEPDIR)/libsangoma_la-sangoma_pri.Plo @@ -362,6 +391,20 @@ libsangoma_la-libsangoma.lo: libsangoma.c # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ # $(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-libhpsangoma.lo: libhpsangoma.c + if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libhpsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c; \ + then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo"; exit 1; fi +# source='libhpsangoma.c' object='libsangoma_la-libhpsangoma.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c + +libsangoma_la-libhpsangoma_priv.lo: libhpsangoma_priv.c + if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libhpsangoma_priv.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c; \ + then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo"; exit 1; fi +# source='libhpsangoma_priv.c' object='libsangoma_la-libhpsangoma_priv.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c + libsangoma_la-sangoma_pri.lo: 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 diff --git a/api/libsangoma/Makefile.am b/api/libsangoma/Makefile.am index 1d5ee14..a7afd47 100644 --- a/api/libsangoma/Makefile.am +++ b/api/libsangoma/Makefile.am @@ -1,18 +1,18 @@ -KINC=/lib/modules/$(shell uname -r)/build -WINC=../../patches/kdrivers/include +WLINC=../../patches/kdrivers/include +WINC=/usr/include/wanpipe -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 +AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WLINC) -I$(WINC) -I. \ + -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O2 -D_DEBUG_=2 -D_GNUC_ -I../lib -LIB_SOURCES = libsangoma.c libsangoma.h +LIB_SOURCES = libsangoma.c libsangoma.h libhpsangoma.c libhpsangoma.h libhpsangoma_priv.c libhpsangoma_priv.h if LIBPRI LIB_SOURCES += sangoma_pri.c sangoma_pri.h endif library_includedir = $(includedir) -library_include_HEADERS = libsangoma.h +library_include_HEADERS = libsangoma.h libhpsangoma.h if LIBPRI library_include_HEADERS += sangoma_pri.h diff --git a/api/libsangoma/Makefile.in b/api/libsangoma/Makefile.in index 251a1de..91327a3 100644 --- a/api/libsangoma/Makefile.in +++ b/api/libsangoma/Makefile.in @@ -75,9 +75,12 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libsangoma_la_LIBADD = am__libsangoma_la_SOURCES_DIST = libsangoma.c libsangoma.h \ - sangoma_pri.c sangoma_pri.h + libhpsangoma.c libhpsangoma.h libhpsangoma_priv.c \ + libhpsangoma_priv.h sangoma_pri.c sangoma_pri.h @LIBPRI_TRUE@am__objects_1 = libsangoma_la-sangoma_pri.lo -am__objects_2 = libsangoma_la-libsangoma.lo $(am__objects_1) +am__objects_2 = libsangoma_la-libsangoma.lo \ + libsangoma_la-libhpsangoma.lo \ + libsangoma_la-libhpsangoma_priv.lo $(am__objects_1) am_libsangoma_la_OBJECTS = $(am__objects_2) libsangoma_la_OBJECTS = $(am_libsangoma_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) @@ -94,7 +97,8 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 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 +am__library_include_HEADERS_DIST = libsangoma.h libhpsangoma.h \ + sangoma_pri.h library_includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(library_include_HEADERS) ETAGS = etags @@ -210,14 +214,15 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @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 +WLINC = ../../patches/kdrivers/include +WINC = /usr/include/wanpipe +AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WLINC) -I$(WINC) -I. \ + -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O2 -D_DEBUG_=2 -D_GNUC_ -I../lib -LIB_SOURCES = libsangoma.c libsangoma.h $(am__append_1) +LIB_SOURCES = libsangoma.c libsangoma.h libhpsangoma.c libhpsangoma.h \ + libhpsangoma_priv.c libhpsangoma_priv.h $(am__append_1) library_includedir = $(includedir) -library_include_HEADERS = libsangoma.h $(am__append_2) +library_include_HEADERS = libsangoma.h libhpsangoma.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) @@ -331,6 +336,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libhpsangoma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-libsangoma.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsangoma_la-sangoma_pri.Plo@am__quote@ @@ -362,6 +369,20 @@ libsangoma_la-libsangoma.lo: libsangoma.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @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-libhpsangoma.lo: libhpsangoma.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-libhpsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libhpsangoma.c' object='libsangoma_la-libhpsangoma.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma.lo `test -f 'libhpsangoma.c' || echo '$(srcdir)/'`libhpsangoma.c + +libsangoma_la-libhpsangoma_priv.lo: libhpsangoma_priv.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-libhpsangoma_priv.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo" "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libhpsangoma_priv.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libhpsangoma_priv.c' object='libsangoma_la-libhpsangoma_priv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libhpsangoma_priv.lo `test -f 'libhpsangoma_priv.c' || echo '$(srcdir)/'`libhpsangoma_priv.c + libsangoma_la-sangoma_pri.lo: 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 diff --git a/api/libsangoma/Makefile.r11 b/api/libsangoma/Makefile.r11 deleted file mode 100644 index ef6c4f4..0000000 --- a/api/libsangoma/Makefile.r11 +++ /dev/null @@ -1,679 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - - - -srcdir = . -top_srcdir = . - -pkgdatadir = $(datadir)/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) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(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} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run aclocal-1.9 -AMDEP_FALSE = # -AMDEP_TRUE = -AMTAR = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run tar -AR = ar -AUTOCONF = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run autoconf -AUTOHEADER = ${SHELL} /root/3.3/wanpipe/ssmg/libsangoma.trunk/missing --run autoheader -AUTOMAKE = ${SHELL} /root/3.3/wanpipe/ssmg/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 = f95 -FFLAGS = -g -O2 -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s -LDFLAGS = -LIBOBJS = -LIBPRI_FALSE = -LIBPRI_TRUE = # -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LN_S = ln -s -LTLIBOBJS = -MAKEINFO = ${SHELL} /root/3.3/wanpipe/ssmg/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 -SED = /bin/sed -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 = f95 -ac_ct_RANLIB = ranlib -ac_ct_STRIP = strip -am__fastdepCC_FALSE = # -am__fastdepCC_TRUE = -am__fastdepCXX_FALSE = # -am__fastdepCXX_TRUE = -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build = i686-pc-linux-gnu -build_alias = -build_cpu = i686 -build_os = linux-gnu -build_vendor = pc -datadir = ${prefix}/share -exec_prefix = ${prefix} -host = i686-pc-linux-gnu -host_alias = -host_cpu = i686 -host_os = linux-gnu -host_vendor = pc -includedir = ${prefix}/include -infodir = ${prefix}/info -install_sh = /root/3.3/wanpipe/ssmg/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 -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 = /common/include -#WINC = ../../patches/kdrivers/include -AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WINC) -I/wanpipe/code/include -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) --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) --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) --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) --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 - -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/Makefile.r9 b/api/libsangoma/Makefile.r9 deleted file mode 100644 index ac4db0c..0000000 --- a/api/libsangoma/Makefile.r9 +++ /dev/null @@ -1,679 +0,0 @@ -# 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/docs/.svn/all-wcprops b/api/libsangoma/docs/.svn/all-wcprops new file mode 100644 index 0000000..80c8c22 --- /dev/null +++ b/api/libsangoma/docs/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/libsangoma/!svn/ver/16/trunk/docs +END diff --git a/api/libsangoma/docs/.svn/entries b/api/libsangoma/docs/.svn/entries new file mode 100644 index 0000000..df5087b --- /dev/null +++ b/api/libsangoma/docs/.svn/entries @@ -0,0 +1,31 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/docs +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:23:57.469320Z +16 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +doxygen +dir + diff --git a/api/libsangoma/docs/.svn/format b/api/libsangoma/docs/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/docs/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/docs/doxygen/.svn/all-wcprops b/api/libsangoma/docs/doxygen/.svn/all-wcprops new file mode 100644 index 0000000..952a447 --- /dev/null +++ b/api/libsangoma/docs/doxygen/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/libsangoma/!svn/ver/16/trunk/docs/doxygen +END diff --git a/api/libsangoma/docs/doxygen/.svn/entries b/api/libsangoma/docs/doxygen/.svn/entries new file mode 100644 index 0000000..abbbd16 --- /dev/null +++ b/api/libsangoma/docs/doxygen/.svn/entries @@ -0,0 +1,31 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/docs/doxygen +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:23:57.469320Z +16 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +html +dir + diff --git a/api/libsangoma/docs/doxygen/.svn/format b/api/libsangoma/docs/doxygen/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/docs/doxygen/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/docs/doxygen/html/.svn/all-wcprops b/api/libsangoma/docs/doxygen/html/.svn/all-wcprops new file mode 100644 index 0000000..48cb56f --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/all-wcprops @@ -0,0 +1,239 @@ +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html +END +structsangoma__hptdm__span__coll__graph.png +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.png +END +tabs.css +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/tabs.css +END +structsangoma__hptdm__span__coll__graph.md5 +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.md5 +END +structsangoma__hptdm__chan__coll__graph.map +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.map +END +graph_legend.html +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/graph_legend.html +END +tab_l.gif +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/tab_l.gif +END +tab_r.gif +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/tab_r.gif +END +structsangoma__hptdm__span__reg-members.html +K 25 +svn:wc:ra_dav:version-url +V 96 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span__reg-members.html +END +libhpsangoma_8c-source.html +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/libhpsangoma_8c-source.html +END +structsangoma__hptdm__span-members.html +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span-members.html +END +doxygen.png +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/doxygen.png +END +graph_legend.dot +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/graph_legend.dot +END +libhpsangoma_8h-source.html +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/libhpsangoma_8h-source.html +END +structsangoma__hptdm__span__coll__graph.map +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.map +END +structhp__tdm__chunk.html +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structhp__tdm__chunk.html +END +functions.html +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/functions.html +END +structsangoma__hptdm__chan__map.html +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__map.html +END +structsangoma__hptdm__chan__reg.html +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__reg.html +END +structsangoma__hptdm__chan.html +K 25 +svn:wc:ra_dav:version-url +V 83 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan.html +END +annotated.html +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/annotated.html +END +structsangoma__hptdm__chan__map__coll__graph.png +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.png +END +structsangoma__hptdm__chan__map__coll__graph.md5 +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.md5 +END +structsangoma__hptdm__chan__coll__graph.png +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.png +END +structsangoma__hptdm__chan__coll__graph.md5 +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.md5 +END +libhpsangoma__priv_8c-source.html +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/libhpsangoma__priv_8c-source.html +END +structhp__tdm__chunk-members.html +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structhp__tdm__chunk-members.html +END +graph_legend.png +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/graph_legend.png +END +libhpsangoma__priv_8h-source.html +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/libhpsangoma__priv_8h-source.html +END +structsangoma__hptdm__span__reg.html +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span__reg.html +END +structsangoma__hptdm__chan__map-members.html +K 25 +svn:wc:ra_dav:version-url +V 96 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__map-members.html +END +structsangoma__hptdm__chan__reg-members.html +K 25 +svn:wc:ra_dav:version-url +V 96 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__reg-members.html +END +doxygen.css +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/doxygen.css +END +files.html +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/files.html +END +functions_vars.html +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/functions_vars.html +END +structsangoma__hptdm__chan-members.html +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan-members.html +END +structsangoma__hptdm__span.html +K 25 +svn:wc:ra_dav:version-url +V 83 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__span.html +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/index.html +END +tab_b.gif +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/tab_b.gif +END +structsangoma__hptdm__chan__map__coll__graph.map +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/libsangoma/!svn/ver/15/trunk/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.map +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/entries b/api/libsangoma/docs/doxygen/html/.svn/entries new file mode 100644 index 0000000..893bb1b --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/entries @@ -0,0 +1,504 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/docs/doxygen/html +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:23:14.087315Z +15 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +structsangoma__hptdm__span__coll__graph.png +file + + + + +2008-08-18T04:42:47.000000Z +2cbc1427b003c1c0e2068e9b168e501f +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +tabs.css +file + + + + +2008-08-18T04:42:47.000000Z +86ffb0e311553e43db9ee79414d0ba6c +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__span__coll__graph.md5 +file + + + + +2008-08-18T04:42:47.000000Z +dbc3ded7880b972ce000b3398a01afac +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__coll__graph.map +file + + + + +2008-08-18T04:42:47.000000Z +917d8a65704b4bb1d21bb71c54315898 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +graph_legend.html +file + + + + +2008-08-18T04:42:47.000000Z +015137c99afc978457ec4c0934fe035f +2008-08-18T04:23:14.087315Z +15 +ncorbic + +tab_l.gif +file + + + + +2008-08-18T04:42:47.000000Z +749f90bcfb2030b4f2c0d274ac3b60ff +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +tab_r.gif +file + + + + +2008-08-18T04:42:47.000000Z +9802233fa0b185ac2242b8dce096cb90 +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +structsangoma__hptdm__span__reg-members.html +file + + + + +2008-08-18T04:42:47.000000Z +874c50d984c045d05224d33b769cd4a6 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +libhpsangoma_8c-source.html +file + + + + +2008-08-18T04:42:47.000000Z +6b16d4e7aa1ada9fd74e3098f37b96d8 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__span-members.html +file + + + + +2008-08-18T04:42:47.000000Z +4a65b9dd6a45e13cd1e18fa4767448bd +2008-08-18T04:23:14.087315Z +15 +ncorbic + +doxygen.png +file + + + + +2008-08-18T04:42:47.000000Z +33f874b8cd0ceafd80ccad649e6e7846 +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +graph_legend.dot +file + + + + +2008-08-18T04:42:47.000000Z +2555cc3d29aaacbea4f702c94774d76b +2008-08-18T04:23:14.087315Z +15 +ncorbic + +libhpsangoma_8h-source.html +file + + + + +2008-08-18T04:42:47.000000Z +e674d33c6767bcbab69a1b86f4cf91c2 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__span__coll__graph.map +file + + + + +2008-08-18T04:42:47.000000Z +9309d59e29ec60d4c848451eab681d47 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structhp__tdm__chunk.html +file + + + + +2008-08-18T04:42:47.000000Z +6da8f6c1482bd06c98e336e2152e4a30 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +functions.html +file + + + + +2008-08-18T04:42:47.000000Z +3ffdd9cc70d2075caf0561d043396f38 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__reg.html +file + + + + +2008-08-18T04:42:47.000000Z +32621cba0df66ea92025d460ee0a543c +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__map.html +file + + + + +2008-08-18T04:42:47.000000Z +e3f18b71078a7814154925f583e05afe +2008-08-18T04:23:14.087315Z +15 +ncorbic + +annotated.html +file + + + + +2008-08-18T04:42:47.000000Z +311ba25cc656be438a7f404b20e69d42 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan.html +file + + + + +2008-08-18T04:42:47.000000Z +18c8ce4890829bbf7ea3837d23c0326f +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__map__coll__graph.png +file + + + + +2008-08-18T04:42:47.000000Z +fd8f957dc612ae92c353877228b2c709 +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +structsangoma__hptdm__chan__map__coll__graph.md5 +file + + + + +2008-08-18T04:42:47.000000Z +7894ad9f937a98695d38d669ab59c1e5 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__coll__graph.png +file + + + + +2008-08-18T04:42:47.000000Z +1c25352ff33af94586f48ab8319e9d7c +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +structsangoma__hptdm__chan__coll__graph.md5 +file + + + + +2008-08-18T04:42:47.000000Z +35b4356b5a362fb524c8fc8ff9f398f9 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +libhpsangoma__priv_8c-source.html +file + + + + +2008-08-18T04:42:47.000000Z +04a7d3d9603c1371b0275a2d88574fd7 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structhp__tdm__chunk-members.html +file + + + + +2008-08-18T04:42:47.000000Z +819b5090c097a04679bc8ee1b40161ae +2008-08-18T04:23:14.087315Z +15 +ncorbic + +graph_legend.png +file + + + + +2008-08-18T04:42:47.000000Z +297ad643196daac99daaaa13e0c3a865 +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +libhpsangoma__priv_8h-source.html +file + + + + +2008-08-18T04:42:47.000000Z +c32a4cc389c783f0a37ce5d252decfe6 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +doxygen.css +file + + + + +2008-08-18T04:42:47.000000Z +702b19635b285e21fa5697bc643b2ba6 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__reg-members.html +file + + + + +2008-08-18T04:42:47.000000Z +fa8a002f9e6bd116b9b1877900e88a3b +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan__map-members.html +file + + + + +2008-08-18T04:42:47.000000Z +5741c57edce21d1b5c6853d39d7191fd +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__span__reg.html +file + + + + +2008-08-18T04:42:47.000000Z +8ccc9e680809ac6a56b7c760c98f2731 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +files.html +file + + + + +2008-08-18T04:42:47.000000Z +9ea6ab3ed7e2a0d5e0b482440f8f4d08 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +functions_vars.html +file + + + + +2008-08-18T04:42:47.000000Z +46f2bdf8f407adda396870e89585f18c +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__chan-members.html +file + + + + +2008-08-18T04:42:47.000000Z +3a09a8b7d8a0ec4bf73a3365ba6d65f4 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +structsangoma__hptdm__span.html +file + + + + +2008-08-18T04:42:47.000000Z +20d0a11d193ba3994057364cec902c29 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +index.html +file + + + + +2008-08-18T04:42:47.000000Z +71a02a48e5bce43237676dc39fb42f50 +2008-08-18T04:23:14.087315Z +15 +ncorbic + +tab_b.gif +file + + + + +2008-08-18T04:42:47.000000Z +a22ef28753006f7a725a9099ade93548 +2008-08-18T04:23:14.087315Z +15 +ncorbic +has-props + +structsangoma__hptdm__chan__map__coll__graph.map +file + + + + +2008-08-18T04:42:47.000000Z +3cd01b906611687a6a71ae7efa1f288e +2008-08-18T04:23:14.087315Z +15 +ncorbic + diff --git a/api/libsangoma/docs/doxygen/html/.svn/format b/api/libsangoma/docs/doxygen/html/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/.svn/prop-base/sound.raw.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/prop-base/sound.raw.svn-base rename to api/libsangoma/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__coll__graph.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__coll__graph.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__span__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__span__coll__graph.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/structsangoma__hptdm__span__coll__graph.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/annotated.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/annotated.html.svn-base new file mode 100644 index 0000000..f7c233e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/annotated.html.svn-base @@ -0,0 +1,31 @@ + + +libhpsangoma: Class List + + + + + + +

libhpsangoma Class List

Here are the classes, structs, unions and interfaces with brief descriptions: + + + + + + +
hp_tdm_chunkA chunk structure used to implement a chunk buffer
sangoma_hptdm_chanChannel structure, describes a single timeslot/channel in a span
sangoma_hptdm_chan_mapStructure describing a array index of a channel inside the span structure
sangoma_hptdm_chan_regChan registration structure
sangoma_hptdm_spanSpan structure. Structure describing a single span
sangoma_hptdm_span_regSpan registration structure
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base new file mode 100644 index 0000000..5d58369 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..f0a274bbaffdd67f6d784c894d9cf28729db0e14 GIT binary patch literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/files.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/files.html.svn-base new file mode 100644 index 0000000..6396ef7 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/files.html.svn-base @@ -0,0 +1,24 @@ + + +libhpsangoma: File Index + + + + + +

libhpsangoma File List

Here is a list of all documented files with brief descriptions: + + + + +
libhpsangoma.c [code]
libhpsangoma.h [code]
libhpsangoma_priv.c [code]
libhpsangoma_priv.h [code]
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/functions.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/functions.html.svn-base new file mode 100644 index 0000000..b5a617c --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/functions.html.svn-base @@ -0,0 +1,120 @@ + + +libhpsangoma: Class Members + + + + + + +
+ +
+
+ +
+ +

+Here is a list of all documented class members with links to the class documentation for each member: +

+

- c -

+

- d -

+

- e -

+

- g -

+

- h -

+

- i -

+

- l -

+

- m -

+

- o -

+

- p -

+

- r -

+

- s -

+

- t -

+

- w -

+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base new file mode 100644 index 0000000..069284a --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base @@ -0,0 +1,120 @@ + + +libhpsangoma: Class Members - Variables + + + + + + +
+ +
+
+ +
+ +

+  +

+

- c -

+

- d -

+

- e -

+

- g -

+

- h -

+

- i -

+

- l -

+

- m -

+

- o -

+

- p -

+

- r -

+

- s -

+

- t -

+

- w -

+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base new file mode 100644 index 0000000..4a1a09c --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="FreeSans.ttf",fontsize=10,labelfontname="FreeSans.ttf",labelfontsize=10]; + node [fontname="FreeSans.ttf",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",fillcolor="grey75",style="filled" fontcolor="black"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="FreeSans.ttf"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="FreeSans.ttf"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classUsed.html"]; +} diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base new file mode 100644 index 0000000..91e5a73 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base @@ -0,0 +1,80 @@ + + +libhpsangoma: Graph Legend + + + + + +

Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

+Consider the following example:

/*! Invisible class because of truncation */
+class Invisible { };
+
+/*! Truncated class, inheritance relation is hidden */
+class Truncated : public Invisible { };
+
+/* Class not documented with doxygen comments */
+class Undocumented { };
+
+/*! Class that is inherited using public inheritance */
+class PublicBase : public Truncated { };
+
+/*! A template class */
+template<class T> class Templ { };
+
+/*! Class that is inherited using protected inheritance */
+class ProtectedBase { };
+
+/*! Class that is inherited using private inheritance */
+class PrivateBase { };
+
+/*! Class that is used by the Inherited class */
+class Used { };
+
+/*! Super class that inherits a number of other classes */
+class Inherited : public PublicBase,
+                  protected ProtectedBase,
+                  private PrivateBase,
+                  public Undocumented
+                  public Templ<int>
+{
+  private:
+    Used *m_usedClass;
+};
+
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

+

+graph_legend.png +
+

+The boxes in the above graph have the following meaning:

    +
  • +A filled black box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a grey border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+The arrows have the following meaning:
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..f937e8510ff86b63eb7e4bccafa42ce692df9689 GIT binary patch literal 21232 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 literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/index.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..17484bf --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/index.html.svn-base @@ -0,0 +1,20 @@ + + +libhpsangoma: Main Page + + + + + +

libhpsangoma Documentation

+

+

1


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8c-source.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8c-source.html.svn-base new file mode 100644 index 0000000..ace7165 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8c-source.html.svn-base @@ -0,0 +1,412 @@ + + +libhpsangoma: libhpsangoma.c Source File + + + + + +

libhpsangoma.c

00001 /*****************************************************************************
+00002  * libhpsangoma.c:  Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  *
+00014  */
+00015 
+00016 #include "libhpsangoma.h"
+00017 #include "libhpsangoma_priv.h"
+00018 
+00019 /*---------------------------------------------------------
+00020   PRIVATE STRUCTURES
+00021  ----------------------------------------------------------*/
+00022 
+00023 void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)=NULL;
+00024 
+00025 
+00034 static int sangoma_hp_tdm_chan_push(struct sangoma_hptdm_chan *chan, char *data, int len)
+00035 {
+00036         hp_tmd_chunk_t *tx_chunk;
+00037         int free_slots;
+00038 
+00039         if (!chan->init) {
+00040                 return -2;
+00041         }
+00042 
+00043         if (len >= SMG_HP_MAX_CHAN_DATA) {
+00044                 /* Data Too Big */
+00045                 lib_printf(0,NULL,"chan_push c%i tx chunk len %i too big\n",
+00046                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in,len);
+00047                 return -1;
+00048         }
+00049 
+00050         /* Lock */
+00051         if (chan->tx_idx_in >= chan->tx_idx_out) {
+00052                 free_slots=SMG_HP_TDM_CHUNK_IDX_SZ-(chan->tx_idx_in-chan->tx_idx_out);
+00053         } else {
+00054                 free_slots=chan->tx_idx_out-chan->tx_idx_in;
+00055         }
+00056         /* Un Lock */
+00057 
+00058         if (!free_slots) {
+00059                 /* We have just overruned the tx buffer */
+00060                 lib_printf(0,NULL,"chan_push c%i failed no free slots in %i out %i\n",
+00061                                 chan->span_no+1,chan->chan_no+1, chan->tx_idx_in,chan->tx_idx_out);
+00062                 return 1;
+00063         }
+00064 
+00065         tx_chunk = &chan->tx_idx[chan->tx_idx_in];
+00066         if (tx_chunk->init) {
+00067                 /* This should NEVER happen the chunk should be free */
+00068                 lib_printf(15,NULL,"chan_push s%ic%i tx chunk overrun in %i \n",
+00069                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
+00070                 return 1;
+00071         }
+00072 
+00073         memset(tx_chunk,0,sizeof(hp_tmd_chunk_t));
+00074         memcpy(&tx_chunk->data,data,len);
+00075         tx_chunk->len=len;
+00076         tx_chunk->init=1;
+00077 
+00078         lib_printf(15,NULL,"chan_push s%ic%i tx chunk in %i \n",
+00079                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
+00080 
+00081         chan->tx_idx_in++;
+00082         if (chan->tx_idx_in >= SMG_HP_TDM_CHUNK_IDX_SZ) {
+00083                 chan->tx_idx_in=0;
+00084         }
+00085 
+00086         return 0;
+00087 }
+00088 
+00089 /*-------------------------------------------------
+00090   Internal Span Methods
+00091  -------------------------------------------------*/
+00092 
+00093 
+00103 static int sangoma_hp_tdm_open_chan(sangoma_hptdm_span_t *span,
+00104                               sangoma_hptdm_chan_reg_t *cfg,
+00105                               unsigned int chan_no,
+00106                               sangoma_hptdm_chan_t **chan_ptr)
+00107 {
+00108         sangoma_hptdm_chan_t *chan;
+00109 
+00110         if (!span->init) {
+00111                 return -1;
+00112         }
+00113 
+00114         if (chan_no >= SMG_HP_TDM_MAX_CHANS) {
+00115                 lib_printf(0,NULL,"open_chan failed chan_no %i >= max chans %i\n",
+00116                                 chan_no, SMG_HP_TDM_MAX_CHANS);
+00117                 return -1;
+00118         }
+00119 
+00120         if (!cfg->rx_data || !cfg->p) {
+00121                 return -1;
+00122         }
+00123 
+00124         if (span->chan_idx[chan_no].chan_no_hw < 0) {
+00125                 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is not mapped to hardware\n",
+00126                                 span->span_no+1,chan_no+1);
+00127                 return -1;
+00128         }
+00129 
+00130         chan = &span->chan_idx[chan_no].chan;
+00131         if (chan->init) {
+00132                 /* Chan Busy */
+00133                 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is busy\n",
+00134                                 span->span_no+1,chan_no+1);
+00135                 return 1;
+00136         }
+00137 
+00138         memset(chan,0,sizeof(sangoma_hptdm_chan_t));
+00139 
+00140         chan->chan_no = chan_no;
+00141         chan->span = span;
+00142         memcpy(&chan->chan_reg, cfg, sizeof(sangoma_hptdm_chan_reg_t));
+00143 
+00144         chan->push = sangoma_hp_tdm_chan_push;
+00145 
+00146         chan->init=1;
+00147         lib_printf(15,NULL,"open_chan chan_no s%ic%i ok\n",
+00148                                 span->span_no+1,chan_no+1);
+00149 
+00150         *chan_ptr = chan;
+00151 
+00152         return 0;
+00153 
+00154 }
+00155 
+00156 
+00163 static int sangoma_hp_tdm_close_chan(sangoma_hptdm_chan_t *chan)
+00164 {
+00165         chan->init=0;
+00166         chan->chan_reg.p=NULL;
+00167         lib_printf(15,NULL,"close_chan chan_no s%ic%i ok\n",
+00168                                 chan->span_no+1,chan->chan_no+1);
+00169         return 0;
+00170 }
+00171 
+00172 
+00178 static int sangoma_hp_tdm_is_chan_closed (sangoma_hptdm_chan_t *chan)
+00179 {
+00180         return (chan->init == 0) ? 1:0;
+00181 }
+00182 
+00188 static int sangoma_hp_tdm_close_span(sangoma_hptdm_span_t *span)
+00189 {
+00190         int i;
+00191         sangoma_hptdm_chan_t *chan=NULL;
+00192 
+00193         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00194                 chan = &span->chan_idx[i].chan;
+00195                 if (chan->init) {
+00196                         chan->init=0;
+00197                 }
+00198         }
+00199 
+00200         close(span->sock);
+00201         span->sock=-1;
+00202 
+00203         return 0;
+00204 }
+00205 
+00211 static int sangoma_hp_tdm_event_ctrl_span(sangoma_hptdm_span_t *span, hp_tdmapi_tx_event_t *event)
+00212 {
+00213         int err;
+00214 
+00215         if (!span->init || span->sock < 0) {
+00216                 return -1;
+00217         }
+00218 
+00219         err = ioctl(span->sock,SIOC_WANPIPE_API,event);
+00220         if (err < 0){
+00221                 lib_printf(0,NULL,"Error: SPAN %i Failed to execute event!\n",
+00222                                 span->span_no+1);
+00223                 return -1;
+00224         }
+00225 
+00226         return 0;
+00227 }
+00228 
+00234 static int sangoma_hp_tdm_event_get_cfg(sangoma_hptdm_span_t *span, wan_if_cfg_t *if_cfg)
+00235 {
+00236         memcpy(if_cfg,&span->span_cfg,sizeof(if_cfg));
+00237         return 0;
+00238 }
+00239 
+00245 static int sangoma_hp_tdm_run_span(sangoma_hptdm_span_t *span)
+00246 {
+00247         int err=0;
+00248         fd_set  sock_read,sock_write,sock_oob;
+00249 
+00250         if (!span->init) {
+00251                 lib_printf(0, NULL, "Span %i not initialized %i\n",span->span_no+1);
+00252                 return -1;
+00253         }
+00254 
+00255         lib_printf(15, NULL, "Starting RUN SPAN %i Sock=%i\n",span->span_no+1, span->sock);
+00256 
+00257         if (span->sock < 0) {
+00258                 err=sangoma_hptdm_span_open(span);
+00259                 if (err) {
+00260                         usleep(500000);
+00261                         err=-2;
+00262                         goto sangoma_hp_tdm_run_span_exit;
+00263                 }
+00264         }
+00265 
+00266         /* Initialize all select() descriptors */
+00267         FD_ZERO(&sock_read);
+00268         FD_ZERO(&sock_write);
+00269         FD_ZERO(&sock_oob);
+00270 
+00271         FD_SET(span->sock,&sock_oob);
+00272         FD_SET(span->sock,&sock_read);
+00273         FD_SET(span->sock,&sock_write);
+00274 
+00275         err=select(span->sock + 1,&sock_read, NULL, &sock_oob, NULL);
+00276 
+00277         if (err > 0) {
+00278 
+00279                 if (FD_ISSET(span->sock,&sock_oob)){
+00280                         err=sangoma_hp_tdm_handle_oob_event(span);
+00281                         if (err) {
+00282                                 lib_printf(0, NULL, "RUN SPAN: %i oob err %i\n",
+00283                                         span->span_no+1, err);
+00284                                 err=-3;
+00285                                 goto sangoma_hp_tdm_run_span_exit;
+00286                         }
+00287                 }
+00288                 if (FD_ISSET(span->sock,&sock_read)){
+00289                         err=sangoma_hp_tdm_handle_read_event(span);
+00290                         if (err) {
+00291                                 lib_printf(0, NULL, "RUN SPAN: %i read err %i\n",
+00292                                         span->span_no+1, err);
+00293                                 err=-4;
+00294                                 goto sangoma_hp_tdm_run_span_exit;
+00295                         }
+00296 
+00297                         err=sangoma_hp_tdm_handle_write_event(span);
+00298                         if (err) {
+00299                                 lib_printf(0, NULL, "RUN SPAN: %i write err %i\n",
+00300                                         span->span_no+1, err);
+00301                                 err=-5;
+00302                                 goto sangoma_hp_tdm_run_span_exit;
+00303                         }
+00304                 }
+00305 
+00306         } else if (err==0) {
+00307                 /* Timeout continue */
+00308                 return 0;
+00309 
+00310         } else {
+00311                 /* Error */
+00312                 if (errno == EAGAIN) {
+00313                         goto sangoma_hp_tdm_run_span_exit;
+00314                 }
+00315 
+00316                 err=-6;
+00317         }
+00318 
+00319 sangoma_hp_tdm_run_span_exit:
+00320 
+00321         if (err < 0) {
+00322                 if (span->sock) {
+00323                         close(span->sock);
+00324                         span->sock=-1;
+00325                 }
+00326         }
+00327 
+00328         return err;
+00329 }
+00330 
+00331 
+00332 
+00333 /*---------------------------------------------------------
+00334   PUBLIC STRUCTURES
+00335  ----------------------------------------------------------*/
+00336 
+00337 
+00338 /*
+00339   \brief Initialize and Configure Span - private functions not to be used directly!
+00340   \param span_no span number - integer
+00341   \param cfg span registration struct
+00342   \param version library version number added by the macro
+00343   \return NULL: fail,  Span Object: pass
+00344  *
+00345  * The __sangoma_hptdm_api_span_init() function must NOT be called directly!
+00346  *  One MUST use defined sangoma_hptdm_api_span_init() macro instead
+00347  */
+00348 
+00349 sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version)
+00350 {
+00351         int err,i,ch=0;
+00352         sangoma_hptdm_span_t *span;
+00353 
+00354         span = malloc(sizeof(sangoma_hptdm_span_t));
+00355         if (!span) {
+00356                 return NULL;
+00357         }
+00358 
+00359         memset(span,0,sizeof(sangoma_hptdm_span_t));
+00360 
+00361         span->span_no=span_no;
+00362         sprintf(span->if_name,"w%ig1",span_no+1);
+00363 
+00364         if (cfg) {
+00365                 memcpy(&span->span_reg,cfg,sizeof(sangoma_hptdm_span_reg_t));
+00366                 if (!lib_log) {
+00367                         lib_log=cfg->log;
+00368                 }
+00369         }
+00370 
+00371         err=sangoma_hptdm_span_open(span);
+00372         if (err) {
+00373                 free(span);
+00374                 return NULL;
+00375         }
+00376 
+00377         if (span->span_cfg.media == WAN_MEDIA_E1) {
+00378                 span->span_cfg.active_ch = span->span_cfg.active_ch >> 1;
+00379         }
+00380 
+00381         lib_printf(0,NULL,"Span %i Configuration\n",span->span_no+1);
+00382         lib_printf(0,NULL,"Used By\t:%i\n",span->span_cfg.usedby);
+00383         lib_printf(0,NULL,"Media\t:%i\n",span->span_cfg.media);
+00384         lib_printf(0,NULL,"Active Ch\t:0x%08X\n",span->span_cfg.active_ch);
+00385         lib_printf(0,NULL,"Chunk Sz\t:%i\n",span->span_cfg.chunk_sz);
+00386         lib_printf(0,NULL,"HW Coding\t:%i\n",span->span_cfg.hw_coding);
+00387         lib_printf(0,NULL,"If Number\t:%i\n",span->span_cfg.interface_number);
+00388 
+00389 
+00390         /* Map all channels to the actually configued on hardware */
+00391         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00392                 span->chan_idx[i].chan_no_hw=-1;
+00393                 if (span->span_cfg.active_ch & (1<<i)) {
+00394                         span->chan_idx[i].chan_no_hw=ch;
+00395                         lib_printf(0,NULL,"Chan %i Mapped to %i",i,ch);
+00396                         ch++;
+00397                         span->max_chans++;
+00398                 } else {
+00399                         lib_printf(0,NULL,"Chan %i Not Mapped",i);
+00400                 }
+00401         }
+00402 
+00403         lib_printf(0,NULL,"Total Chans\t:%i\n",span->max_chans);
+00404 
+00405         /* Must be configurable */
+00406         span->chunk_sz=span->span_cfg.chunk_sz;
+00407         span->tx_size=span->max_chans*span->chunk_sz;
+00408 
+00409         span->init=1;
+00410         span->idle=0xFF;
+00411 
+00412         span->open_chan = sangoma_hp_tdm_open_chan;
+00413         span->close_chan = sangoma_hp_tdm_close_chan;
+00414         span->is_chan_closed = sangoma_hp_tdm_is_chan_closed;
+00415         span->run_span =sangoma_hp_tdm_run_span;
+00416         span->close_span = sangoma_hp_tdm_close_span;
+00417         span->event_ctrl = sangoma_hp_tdm_event_ctrl_span;
+00418         span->get_cfg = sangoma_hp_tdm_event_get_cfg;
+00419 
+00420         lib_printf(5, NULL, "Span %i Initialized\n",span->span_no+1);
+00421 
+00422         return span;
+00423 }
+00424 
+00425 /*
+00426   \brief Free, Un-Initialize Span
+00427   \param span_no span object
+00428   \return 0 = pass, non zero fail
+00429  */
+00430 
+00431 int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span)
+00432 {
+00433         if (span->sock >= 0) {
+00434                 span->close_span(span);
+00435         }
+00436 
+00437         free(span);
+00438         span=NULL;
+00439 
+00440         return 0;
+00441 }
+00442 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8h-source.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8h-source.html.svn-base new file mode 100644 index 0000000..6d27991 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma_8h-source.html.svn-base @@ -0,0 +1,223 @@ + + +libhpsangoma: libhpsangoma.h Source File + + + + + +

libhpsangoma.h

00001 /*****************************************************************************
+00002  * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  */
+00014 
+00015 #ifndef _LIB_HP_SNAGOMA_H
+00016 #define _LIB_HP_SNAGOMA_H
+00017 
+00018 
+00019 #ifdef WIN32
+00020 
+00021 #error "WINDOWS NOT DEFINED"
+00022 
+00023 #else
+00024 /* L I N U X */
+00025 #include <stdio.h>
+00026 #include <stdlib.h>
+00027 #include <ctype.h>
+00028 #include <unistd.h>
+00029 #include <sys/time.h>
+00030 #include <sys/socket.h>
+00031 #include <sys/ioctl.h>
+00032 #include <sys/types.h>
+00033 #include <sys/signal.h>
+00034 #include <sys/select.h>
+00035 #include <sys/wait.h>
+00036 #include <sys/resource.h>
+00037 #include <netinet/in.h>
+00038 #include <string.h>
+00039 #include <errno.h>
+00040 #include <fcntl.h>
+00041 #include <linux/if.h>
+00042 #include <poll.h>
+00043 #include <signal.h>
+00044 
+00045 
+00046 #include <linux/wanpipe_defines.h>
+00047 #include <linux/wanpipe_common.h>
+00048 #include <linux/wanpipe_cfg.h>
+00049 #include <linux/wanpipe.h>
+00050 #include <linux/if_wanpipe.h>
+00051 #include <linux/sdla_aft_te1.h>
+00052 #endif
+00053 
+00054 #define SMG_HP_MAX_CHAN_DATA 1024
+00055 #define SMG_HP_TDM_CHUNK_IDX_SZ 16
+00056 #define SMG_HP_TDM_MAX_CHANS 31
+00057 #define SMG_HP_MAX_SPAN_DATA (31*160)+32
+00058 
+00059 #define hp_tdmapi_rx_event_t api_rx_hdr_t
+00060 #define hp_tdmapi_tx_event_t api_tx_hdr_t
+00061 
+00062 #define SANGOMA_HPTDM_VERSION 1
+00063 
+00064 /*---------------------------------------------------------
+00065  * PUBLIC DEFINITIONS
+00066  */
+00067 
+00068 
+00072 typedef struct sangoma_hptdm_span_reg
+00073 {
+00075         void *p;
+00077         void (*log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00079         int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data);
+00080 }sangoma_hptdm_span_reg_t;
+00081 
+00082 
+00086 typedef struct hp_tdm_chunk
+00087 {
+00089         int init;
+00091         int len;
+00093         int offset;
+00095         char data[SMG_HP_MAX_CHAN_DATA];
+00096 }hp_tmd_chunk_t;
+00097 
+00101 typedef struct sangoma_hptdm_chan_reg
+00102 {
+00104         void *p;
+00106         int (*rx_data)(void *p, char *data, int len);
+00108         int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data);
+00109 
+00110 }sangoma_hptdm_chan_reg_t;
+00111 
+00115 typedef struct sangoma_hptdm_chan
+00116 {
+00118         int init;
+00119 
+00121         int chan_no;
+00122 
+00124         int span_no;
+00125 
+00127         void *span;
+00128 
+00130         hp_tmd_chunk_t rx_chunk;
+00131 
+00133         hp_tmd_chunk_t tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ];
+00134 
+00136         int tx_idx_in;
+00137 
+00139         int tx_idx_out;
+00140 
+00142         int (*push)(struct sangoma_hptdm_chan *, char *data, int len);
+00143 
+00145         sangoma_hptdm_chan_reg_t chan_reg;
+00146 
+00147 }sangoma_hptdm_chan_t;
+00148 
+00157 typedef struct sangoma_hptdm_chan_map
+00158 {
+00162         int chan_no_hw;
+00163 
+00165         sangoma_hptdm_chan_t chan;
+00166 
+00167 }sangoma_hptdm_chan_map_t;
+00168 
+00169 
+00173 typedef struct sangoma_hptdm_span
+00174 {
+00176         int init;
+00177 
+00179         int span_no;
+00180 
+00182         char if_name[100];
+00183 
+00185         int sock;
+00186 
+00188         int chunk_sz;
+00189 
+00191         int max_chans;
+00192 
+00194         int tx_size;
+00195 
+00197         unsigned char idle;
+00198 
+00200         unsigned int timeslot_cfg;
+00201 
+00203         unsigned int hwcoding;
+00204 
+00206         sangoma_hptdm_chan_map_t chan_idx[SMG_HP_TDM_MAX_CHANS];
+00207 
+00209         char rx_data[SMG_HP_MAX_SPAN_DATA];
+00210 
+00212         int rx_len;
+00213 
+00215         char tx_data[SMG_HP_MAX_SPAN_DATA];
+00216 
+00218         int tx_len;
+00219 
+00221         sangoma_hptdm_span_reg_t span_reg;
+00222 
+00224         wan_if_cfg_t span_cfg;
+00225 
+00227         wan_udp_hdr_t wan_udp;
+00228 
+00235         int (*open_chan)(struct sangoma_hptdm_span *span,
+00236                               sangoma_hptdm_chan_reg_t *chan_reg,
+00237                               unsigned int chan_no,
+00238                               sangoma_hptdm_chan_t **chan_ptr);
+00239 
+00243         int (*close_chan)(sangoma_hptdm_chan_t *chan);
+00244 
+00247         int (*is_chan_closed)(sangoma_hptdm_chan_t *chan);
+00248 
+00259         int (*run_span)(struct sangoma_hptdm_span *span);
+00260 
+00263         int (*close_span)(struct sangoma_hptdm_span *span);
+00264 
+00269         int (*event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event);
+00270 
+00275         int (*get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg);
+00276 
+00277 
+00278 }sangoma_hptdm_span_t;
+00279 
+00280 /*---------------------------------------------------------
+00281  * PUBLIC FUNCTIONS
+00282  */
+00283 
+00291 /* Initialize and Configure a Span  */
+00292 #define sangoma_hptdm_api_span_init(span,cfg) __sangoma_hptdm_api_span_init(span, cfg, SANGOMA_HPTDM_VERSION);
+00293 
+00305  /*
+00306   * The __sangoma_hptdm_api_span_init() function must NOT be called directly!
+00307   * One MUST use defined sangoma_hptdm_api_span_init() macro instead
+00308   */
+00309 extern sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version);
+00310 
+00311 
+00317 extern int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span);
+00318 
+00319 
+00320 
+00321 
+00322 
+00323 #endif
+00324 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8c-source.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8c-source.html.svn-base new file mode 100644 index 0000000..fc7572b --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8c-source.html.svn-base @@ -0,0 +1,362 @@ + + +libhpsangoma: libhpsangoma_priv.c Source File + + + + + +

libhpsangoma_priv.c

00001 /*****************************************************************************
+00002  * libhpsangoma_priv.c:  Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  *
+00014  */
+00015 
+00016 #include "libhpsangoma.h"
+00017 #include "libhpsangoma_priv.h"
+00018 #define DFT_CARD "wanpipe1"
+00019 
+00020 
+00031 int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
+00032 {
+00033         int rx_len=0;
+00034 
+00035 #if defined(WIN32)
+00036 
+00037 #error "WINDOWS HP TDMAPI NOT DEFINED"
+00038 
+00039 #else
+00040         struct msghdr msg;
+00041         struct iovec iov[2];
+00042 
+00043         memset(&msg,0,sizeof(struct msghdr));
+00044 
+00045         iov[0].iov_len=hdrlen;
+00046         iov[0].iov_base=hdrbuf;
+00047 
+00048         iov[1].iov_len=datalen;
+00049         iov[1].iov_base=databuf;
+00050 
+00051         msg.msg_iovlen=2;
+00052         msg.msg_iov=iov;
+00053 
+00054         rx_len = recvmsg(fd,&msg,0);
+00055 
+00056         if (rx_len <= sizeof(api_rx_hdr_t)){
+00057                 return -EINVAL;
+00058         }
+00059 
+00060         rx_len-=sizeof(api_rx_hdr_t);
+00061 #endif
+00062 
+00063         return rx_len;
+00064 }
+00065 
+00066 
+00067 
+00078 int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
+00079 {
+00080         int bsent;
+00081 
+00082 #if defined(WIN32)
+00083 
+00084 #error "Windows TX not implemented"
+00085 
+00086 #else
+00087         struct msghdr msg;
+00088         struct iovec iov[2];
+00089 
+00090         memset(&msg,0,sizeof(struct msghdr));
+00091 
+00092         iov[0].iov_len=hdrlen;
+00093         iov[0].iov_base=hdrbuf;
+00094 
+00095         iov[1].iov_len=datalen;
+00096         iov[1].iov_base=databuf;
+00097 
+00098         msg.msg_iovlen=2;
+00099         msg.msg_iov=iov;
+00100 
+00101         bsent = sendmsg(fd,&msg,0);
+00102         if (bsent > 0){
+00103                 bsent-=sizeof(api_tx_hdr_t);
+00104         }
+00105 #endif
+00106         return bsent;
+00107 }
+00108 
+00114 int do_wanpipemon_cmd(sangoma_hptdm_span_t *span)
+00115 {
+00116         struct ifreq ifr;
+00117         memset(&ifr,0,sizeof(ifr));
+00118         ifr.ifr_data = (void*)&span->wan_udp;
+00119         sprintf (ifr.ifr_name, "%s", span->if_name);
+00120         return ioctl(span->sock,SIOC_WANPIPE_PIPEMON,&ifr);
+00121 }
+00122 
+00128 unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span)
+00129 {
+00130         span->wan_udp.wan_udphdr_command = READ_CONFIGURATION;
+00131         span->wan_udp.wan_udphdr_data_len = 0;
+00132         span->wan_udp.wan_udphdr_return_code = 0xaa;
+00133         do_wanpipemon_cmd(span);
+00134         if (span->wan_udp.wan_udphdr_return_code != 0){
+00135                 lib_printf(0,NULL,"Error: SPAN %i management command failed 0x02Xs (%s)",
+00136                         span->span_no+1, span->wan_udp.wan_udphdr_return_code,strerror(errno));
+00137                 return -1;
+00138         }
+00139 
+00140         memcpy(&span->span_cfg,&span->wan_udp.wan_udphdr_data[0],sizeof(span->span_cfg));
+00141 
+00142         return 0;
+00143 }
+00144 
+00145 
+00152 int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span)
+00153 {
+00154         struct wan_sockaddr_ll  sa;
+00155         char if_name[100];
+00156         int sock=-1;
+00157         int err;
+00158 
+00159         memset(&sa,0,sizeof(struct wan_sockaddr_ll));
+00160         sock = socket(AF_WANPIPE, SOCK_RAW, 0);
+00161         if( sock < 0 ) {
+00162                 perror("Socket");
+00163                 return -1;
+00164         } /* if */
+00165 
+00166         sprintf(if_name, "w%ig1", span->span_no+1);
+00167 
+00168         strcpy( (char*)sa.sll_device, if_name);
+00169         strcpy( (char*)sa.sll_card, DFT_CARD);
+00170         sa.sll_protocol = htons(PVC_PROT);
+00171         sa.sll_family=AF_WANPIPE;
+00172 
+00173         if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
+00174         lib_printf(0,NULL,"bind failed on span span %i %s\n",
+00175                 span->span_no+1,strerror(errno));
+00176                         return -1;
+00177         }
+00178 
+00179         span->sock=sock;
+00180 
+00181         err= sangoma_get_cfg(span);
+00182         if (err) {
+00183                 goto sangoma_hptdm_span_open_error;
+00184         }
+00185 
+00186         lib_printf(0,NULL,"libhp: span %i opened\n",
+00187                         span->span_no+1);
+00188 
+00189         return 0;
+00190 
+00191 sangoma_hptdm_span_open_error:
+00192 
+00193         if (span->sock) {
+00194                 close(span->sock);
+00195                 span->sock=-1;
+00196         }
+00197 
+00198         return err;
+00199 }
+00200 
+00201 
+00208 int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span)
+00209 {
+00210         int err;
+00211         hp_tdmapi_rx_event_t *rx_event;
+00212 
+00213         err = recv(span->sock, span->rx_data, sizeof(span->rx_data), MSG_OOB);
+00214         if (err > 0) {
+00215                 rx_event=(hp_tdmapi_rx_event_t*)&span->rx_data;
+00216                 if (span->span_reg.rx_event && span->span_reg.p) {
+00217                         span->span_reg.rx_event(span->span_reg.p, rx_event);
+00218                 }
+00219         }
+00220         /* For now treat all err as socket reload */
+00221         return 1;
+00222 }
+00223 
+00230 int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span)
+00231 {
+00232         int i=0,x=0,err=0;
+00233         sangoma_hptdm_chan_t *chan=NULL;
+00234         hp_tmd_chunk_t *chunk=NULL;
+00235         int chan_no_hw;
+00236         char *rx_data = &span->rx_data[sizeof(api_rx_hdr_t)];
+00237 
+00238 
+00239         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00240                 chan = &span->chan_idx[i].chan;
+00241                 if (!chan->init) {
+00242                         continue;
+00243                 }
+00244                 chan_no_hw = span->chan_idx[i].chan_no_hw;
+00245 
+00246                 lib_printf(15,NULL, "SPAN %i Chan %i Chunk %i Channelizing\n",
+00247                                 span->span_no+1, chan->chan_no+1, span->chunk_sz);
+00248 
+00249                 chunk = &chan->rx_chunk;
+00250 
+00251                 for (x=0;x<span->chunk_sz;x++) {
+00252                         chunk->data[x] = rx_data[(span->max_chans*x)+chan_no_hw];
+00253                 }
+00254 
+00255                 chunk->len = span->chunk_sz;
+00256                 if (chan->chan_reg.p && chan->chan_reg.rx_data) {
+00257                         err=chan->chan_reg.rx_data(chan->chan_reg.p,chunk->data,chunk->len);
+00258                 } else {
+00259                         err=1;
+00260                 }
+00261 
+00262                 if (err) {
+00263                         chan->init=0;
+00264                         chan->chan_reg.p=NULL;
+00265                 }
+00266 
+00267         }
+00268 
+00269         return err;
+00270 
+00271 
+00272 }
+00273 
+00280 int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span)
+00281 {
+00282         int err;
+00283         hp_tdmapi_rx_event_t *rx_event = (hp_tdmapi_rx_event_t*)&span->rx_data[0];
+00284 
+00285         err = sangoma_readmsg_hp_tdm(span->sock,
+00286                                      &span->rx_data[0],sizeof(api_rx_hdr_t),
+00287                                      &span->rx_data[sizeof(api_rx_hdr_t)],
+00288                                      sizeof(span->rx_data) - sizeof(api_rx_hdr_t),
+00289                                      0);
+00290 
+00291         if (err >  sizeof(api_rx_hdr_t)) {
+00292 
+00293                 lib_printf(15,NULL, "SPAN %i Read Len = %i\n",span->span_no+1,err);
+00294 
+00295                 if (rx_event->event_type) {
+00296 
+00297                         if (span->span_reg.rx_event && span->span_reg.p) {
+00298                                 span->span_reg.rx_event(span->span_reg.p, rx_event);
+00299                         }
+00300 
+00301                 } else {
+00302 
+00303                         if (err % span->chunk_sz) {
+00304                                 lib_printf(0,NULL, "Error: SPAN %i Read Len = %i Block not chunk %i aligned! \n",span->span_no+1,err,span->chunk_sz);
+00305                                 /* Received chunk size is not aligned drop it for now */
+00306                                 return 0;
+00307                         }
+00308 
+00309                         sangoma_hp_tdm_push_rx_data(span);
+00310                 }
+00311 
+00312                 err=0;
+00313 
+00314         } else {
+00315                 if (errno == EAGAIN) {
+00316                         err = 0;
+00317                 } else {
+00318                         err=-1;
+00319                 }
+00320         }
+00321 
+00322         return err;
+00323 }
+00324 
+00325 
+00331 int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span)
+00332 {
+00333         int i=0,x=0,err=0;
+00334         sangoma_hptdm_chan_t *chan;
+00335         hp_tmd_chunk_t *chunk;
+00336         int chan_no_hw=0;
+00337         char *tx_data = &span->tx_data[sizeof(api_tx_hdr_t)];
+00338 
+00339         memset(&span->tx_data,span->idle,sizeof(span->tx_data));
+00340 
+00341 
+00342         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00343                 chan = &span->chan_idx[i].chan;
+00344                 if (!chan->init) {
+00345                         /* This channel is not open */
+00346                         continue;
+00347                 }
+00348                 chan_no_hw=span->chan_idx[i].chan_no_hw;
+00349 
+00350                 chunk = &chan->tx_idx[chan->tx_idx_out];
+00351                 if (!chunk->init) {
+00352                         lib_printf(15,NULL,"span write s%ic%i tx chunk underrun out %i \n",
+00353                                         chan->span_no+1,chan->chan_no+1,chan->tx_idx_out);
+00354                         /* There is no tx data for this channel */
+00355                         continue;
+00356                 }
+00357 
+00358                 for (x=0;x<span->chunk_sz;x++) {
+00359 
+00360                         tx_data[(span->max_chans*x)+chan_no_hw] = chunk->data[chunk->offset];
+00361                         chunk->offset++;
+00362 
+00363                         if (chunk->offset >= chunk->len) {
+00364                                 chunk->init=0;
+00365 
+00366                                 lib_printf(15,NULL,"span write s%ic%i tx chunk out %i \n",
+00367                                         chan->span_no+1,chan->chan_no+1,chan->tx_idx_out);
+00368 
+00369                                 chan->tx_idx_out++;
+00370                                 if (chan->tx_idx_out >= SMG_HP_TDM_CHUNK_IDX_SZ) {
+00371                                         chan->tx_idx_out=0;
+00372                                 }
+00373                                 chunk=&chan->tx_idx[chan->tx_idx_out];
+00374                                 if (!chunk->init) {
+00375                                         /* We are out of tx data on this channel */
+00376                                         break;
+00377                                 }
+00378                         }
+00379                 }
+00380         }
+00381 
+00382 
+00383         err = sangoma_writemsg_hp_tdm(span->sock,
+00384                                      span->tx_data,sizeof(api_tx_hdr_t),
+00385                                      tx_data, span->tx_size,
+00386                                      0);
+00387 
+00388         lib_printf(15, NULL, "SPAN %i TX Len %i Expecting %i\n",
+00389                         span->span_no+1, err, span->tx_size+sizeof(api_tx_hdr_t));
+00390 
+00391         if (err < span->tx_size) {
+00392                 if (errno == EAGAIN) {
+00393                         return 0;
+00394                 } else {
+00395                         return -1;
+00396                 }
+00397         } else {
+00398                 err=0;
+00399         }
+00400 
+00401         return err;
+00402 
+00403 }
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8h-source.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8h-source.html.svn-base new file mode 100644 index 0000000..275d62f --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/libhpsangoma__priv_8h-source.html.svn-base @@ -0,0 +1,77 @@ + + +libhpsangoma: libhpsangoma_priv.h Source File + + + + + +

libhpsangoma_priv.h

00001 /*****************************************************************************
+00002  * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  */
+00014 
+00015 #ifndef _LIB_HP_SANGOMA_PRIV_H
+00016 #define _LIB_HP_SANGOMA_PRIV_H
+00017 
+00018 #include "libhpsangoma.h"
+00019 
+00020 
+00025 #define lib_printf(level, fp, fmt, ...) if (lib_log) lib_log(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+00026 
+00027 extern void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00028 
+00029 
+00030 /*---------------------------------------------------------
+00031  * PRIVATE - FUNCTIONS
+00032  */
+00033 
+00044 int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag);
+00045 
+00046 
+00057 int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag);
+00058 
+00064 int do_wanpipemon_cmd(sangoma_hptdm_span_t *span);
+00065 
+00066 
+00072 unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span);
+00073 
+00074 
+00080 int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span);
+00081 
+00082 
+00088 int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span);
+00089 
+00090 
+00096 int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span);
+00097 
+00098 
+00104 int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span);
+00105 
+00106 
+00112 int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span);
+00113 
+00114 
+00115 
+00116 
+00117 #endif
+00118 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk-members.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk-members.html.svn-base new file mode 100644 index 0000000..5cfba24 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk-members.html.svn-base @@ -0,0 +1,28 @@ + + +libhpsangoma: Member List + + + + + + +

hp_tdm_chunk Member List

This is the complete list of members for hp_tdm_chunk, including all inherited members.

+ + + + +
datahp_tdm_chunk
inithp_tdm_chunk
lenhp_tdm_chunk
offsethp_tdm_chunk


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk.html.svn-base new file mode 100644 index 0000000..d8e5afb --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structhp__tdm__chunk.html.svn-base @@ -0,0 +1,116 @@ + + +libhpsangoma: hp_tdm_chunk Struct Reference + + + + + + +

hp_tdm_chunk Struct Reference

A chunk structure used to implement a chunk buffer. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + + + +

Public Attributes

int init
int len
int offset
char data [SMG_HP_MAX_CHAN_DATA]
+


Detailed Description

+A chunk structure used to implement a chunk buffer. +

+ +

+Definition at line 86 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
char hp_tdm_chunk::data[SMG_HP_MAX_CHAN_DATA]
+
+
+ +

+chunk data location +

+Definition at line 95 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::init
+
+
+ +

+chunk init flag used to determine if chunk is being used +

+Definition at line 89 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::len
+
+
+ +

+length of the current data chunk +

+Definition at line 91 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::offset
+
+
+ +

+current offset to write/read to/from the chunk data structure. +

+Definition at line 93 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan-members.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan-members.html.svn-base new file mode 100644 index 0000000..c4d72a9 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan-members.html.svn-base @@ -0,0 +1,34 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan Member List

This is the complete list of members for sangoma_hptdm_chan, including all inherited members.

+ + + + + + + + + + +
chan_nosangoma_hptdm_chan
chan_regsangoma_hptdm_chan
initsangoma_hptdm_chan
pushsangoma_hptdm_chan
rx_chunksangoma_hptdm_chan
spansangoma_hptdm_chan
span_nosangoma_hptdm_chan
tx_idxsangoma_hptdm_chan
tx_idx_insangoma_hptdm_chan
tx_idx_outsangoma_hptdm_chan


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan.html.svn-base new file mode 100644 index 0000000..8685c84 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan.html.svn-base @@ -0,0 +1,233 @@ + + +libhpsangoma: sangoma_hptdm_chan Struct Reference + + + + + + +

sangoma_hptdm_chan Struct Reference

Channel structure, describes a single timeslot/channel in a span. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_chan:

Collaboration graph
+ + + + +
[legend]
List of all members. + + + + + + + + + + + + + + + + + + + + + + +

Public Attributes

int init
int chan_no
int span_no
void * span
hp_tmd_chunk_t rx_chunk
hp_tmd_chunk_t tx_idx [SMG_HP_TDM_CHUNK_IDX_SZ]
int tx_idx_in
int tx_idx_out
int(* push )(struct sangoma_hptdm_chan *, char *data, int len)
sangoma_hptdm_chan_reg_t chan_reg
+

Detailed Description

+Channel structure, describes a single timeslot/channel in a span. +

+ +

+Definition at line 115 of file libhpsangoma.h.


Member Data Documentation

+ +
+ +
+ +

+channel number: starting from 0 +

+Definition at line 121 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Channel registration struct used to store user data, cfg and callbacks +

+Definition at line 145 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_chan::init
+
+
+ +

+channel init flag used to determine if chan is being used +

+Definition at line 118 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan::push)(struct sangoma_hptdm_chan *, char *data, int len)
+
+
+ +

+Callback func called by user to push chunk of data into the channel +

+

+ +

+ +
+ +

+Rx chunk buffer used to rx data from the span +

+Definition at line 130 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
void* sangoma_hptdm_chan::span
+
+
+ +

+span object pointer the current channel belongs +

+Definition at line 127 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span number the current channel belongs to: starting from 0 +

+Definition at line 124 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
hp_tmd_chunk_t sangoma_hptdm_chan::tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ]
+
+
+ +

+Circular buffer of tx data chunks used to tx data to span +

+Definition at line 133 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Circular buffer index for user to chan tx +

+Definition at line 136 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Circular buffer index for chan to span tx +

+Definition at line 139 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.map.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.map.svn-base new file mode 100644 index 0000000..4c991a4 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.map.svn-base @@ -0,0 +1,3 @@ +base referer +rect $structsangoma__hptdm__chan__reg.html 5,7 200,33 +rect $structhp__tdm__chunk.html 224,7 339,33 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.md5.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.md5.svn-base new file mode 100644 index 0000000..0875531 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.md5.svn-base @@ -0,0 +1 @@ +b71c119d6e01aec1dbb8e5a6536607e2 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__coll__graph.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..7224d327d1bd7653944f6745ef0b8c6aa87205e6 GIT binary patch literal 8480 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 + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan_map Member List

This is the complete list of members for sangoma_hptdm_chan_map, including all inherited members.

+ + +
chansangoma_hptdm_chan_map
chan_no_hwsangoma_hptdm_chan_map


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map.html.svn-base new file mode 100644 index 0000000..a734751 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map.html.svn-base @@ -0,0 +1,86 @@ + + +libhpsangoma: sangoma_hptdm_chan_map Struct Reference + + + + + + +

sangoma_hptdm_chan_map Struct Reference

Structure describing a array index of a channel inside the span structure. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_chan_map:

Collaboration graph
+ + + + + +
[legend]
List of all members. + + + + + + +

Public Attributes

int chan_no_hw
sangoma_hptdm_chan_t chan
+

Detailed Description

+Structure describing a array index of a channel inside the span structure. +

+Structure describing a array index of a channel inside the span structure. Furthermore the index * also servers as a map from hardware channels to library channels. Hardware might be configured for channels 1-15.17-31, however library always provides all 31 channels +

+ +

+Definition at line 157 of file libhpsangoma.h.


Member Data Documentation

+ +
+ +
+ +

+A channel structure +

+Definition at line 165 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+A hardware channel number that is mapped to the current channel structure. Hardware might be configured for channels 1-15.17-31, however library always provides all 31 channels +

+Definition at line 162 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.map.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.map.svn-base new file mode 100644 index 0000000..a832cee --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.map.svn-base @@ -0,0 +1,4 @@ +base referer +rect $structsangoma__hptdm__chan.html 108,119 276,145 +rect $structsangoma__hptdm__chan__reg.html 5,7 200,33 +rect $structhp__tdm__chunk.html 224,7 339,33 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.md5.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.md5.svn-base new file mode 100644 index 0000000..6a57549 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.md5.svn-base @@ -0,0 +1 @@ +40aa88a5db6369be91695855bbf43d42 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__map__coll__graph.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..1a523d961c6c06adad4d0ce25e734ae96064f514 GIT binary patch literal 11233 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 + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan_reg Member List

This is the complete list of members for sangoma_hptdm_chan_reg, including all inherited members.

+ + + +
psangoma_hptdm_chan_reg
rx_datasangoma_hptdm_chan_reg
rx_eventsangoma_hptdm_chan_reg


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__reg.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__reg.html.svn-base new file mode 100644 index 0000000..c02d1db --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__chan__reg.html.svn-base @@ -0,0 +1,93 @@ + + +libhpsangoma: sangoma_hptdm_chan_reg Struct Reference + + + + + + +

sangoma_hptdm_chan_reg Struct Reference

Chan registration structure. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + +

Public Attributes

void * p
int(* rx_data )(void *p, char *data, int len)
int(* rx_event )(void *p, hp_tdmapi_rx_event_t *data)
+


Detailed Description

+Chan registration structure. +

+ +

+Definition at line 101 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
void* sangoma_hptdm_chan_reg::p
+
+
+ +

+pointer to user object used with callback functions +

+Definition at line 104 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan_reg::rx_data)(void *p, char *data, int len)
+
+
+ +

+callback function used to pass rx chunk to user application +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan_reg::rx_event)(void *p, hp_tdmapi_rx_event_t *data)
+
+
+ +

+callback function used to pass channel specific event to user application +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span-members.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span-members.html.svn-base new file mode 100644 index 0000000..5f6e4d6 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span-members.html.svn-base @@ -0,0 +1,49 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_span Member List

This is the complete list of members for sangoma_hptdm_span, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
chan_idxsangoma_hptdm_span
chunk_szsangoma_hptdm_span
close_chansangoma_hptdm_span
close_spansangoma_hptdm_span
event_ctrlsangoma_hptdm_span
get_cfgsangoma_hptdm_span
hwcodingsangoma_hptdm_span
idlesangoma_hptdm_span
if_namesangoma_hptdm_span
initsangoma_hptdm_span
is_chan_closedsangoma_hptdm_span
max_chanssangoma_hptdm_span
open_chansangoma_hptdm_span
run_spansangoma_hptdm_span
rx_datasangoma_hptdm_span
rx_lensangoma_hptdm_span
socksangoma_hptdm_span
span_cfgsangoma_hptdm_span
span_nosangoma_hptdm_span
span_regsangoma_hptdm_span
timeslot_cfgsangoma_hptdm_span
tx_datasangoma_hptdm_span
tx_lensangoma_hptdm_span
tx_sizesangoma_hptdm_span
wan_udpsangoma_hptdm_span


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span.html.svn-base new file mode 100644 index 0000000..ac474e0 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span.html.svn-base @@ -0,0 +1,570 @@ + + +libhpsangoma: sangoma_hptdm_span Struct Reference + + + + + + +

sangoma_hptdm_span Struct Reference

Span structure. Structure describing a single span. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_span:

Collaboration graph
+ + + + + + + +
[legend]
List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Attributes

int init
int span_no
char if_name [100]
int sock
int chunk_sz
int max_chans
int tx_size
unsigned char idle
unsigned int timeslot_cfg
unsigned int hwcoding
sangoma_hptdm_chan_map_t chan_idx [SMG_HP_TDM_MAX_CHANS]
char rx_data [SMG_HP_MAX_SPAN_DATA]
int rx_len
char tx_data [SMG_HP_MAX_SPAN_DATA]
int tx_len
sangoma_hptdm_span_reg_t span_reg
wan_if_cfg_t span_cfg
wan_udp_hdr_t wan_udp
int(* open_chan )(struct sangoma_hptdm_span *span, sangoma_hptdm_chan_reg_t *chan_reg, unsigned int chan_no, sangoma_hptdm_chan_t **chan_ptr)
 Method: open a channel inside a span.
int(* close_chan )(sangoma_hptdm_chan_t *chan)
 Method: close a channel inside the span.
int(* is_chan_closed )(sangoma_hptdm_chan_t *chan)
 Method: check if channel is closed.
int(* run_span )(struct sangoma_hptdm_span *span)
 Method: run main span execution logic: rx/tx/oob.
int(* close_span )(struct sangoma_hptdm_span *span)
 Method: close span.
int(* event_ctrl )(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event)
 Method: used by user app to execute events on current span.
int(* get_cfg )(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg)
 Method: request full span configuration from a current span.
+

Detailed Description

+Span structure. Structure describing a single span. +

+ +

+Definition at line 173 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
sangoma_hptdm_chan_map_t sangoma_hptdm_span::chan_idx[SMG_HP_TDM_MAX_CHANS]
+
+
+ +

+array of maximum number of channels in a span +

+Definition at line 206 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+chunk size for each channel inside the span +

+Definition at line 188 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Method: close a channel inside the span. +

+

Parameters:
+ + +
chan chan object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::close_span)(struct sangoma_hptdm_span *span)
+
+
+ +

+Method: close span. +

+

Parameters:
+ + +
span span object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event)
+
+
+ +

+Method: used by user app to execute events on current span. +

+

Parameters:
+ + + +
span span object
event event object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg)
+
+
+ +

+Method: request full span configuration from a current span. +

+

Parameters:
+ + + +
span span object
cfg configuratoin object to be filled by span
+
+ +
+

+ +

+
+ + + + +
unsigned int sangoma_hptdm_span::hwcoding
+
+
+ +

+hw data encoding: ULAW/ALAW obtained from hw interface +

+Definition at line 203 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
unsigned char sangoma_hptdm_span::idle
+
+
+ +

+idle flag used to fill an unused channel +

+Definition at line 197 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
char sangoma_hptdm_span::if_name[100]
+
+
+ +

+span hw interface name to which span is bounded to +

+Definition at line 182 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_span::init
+
+
+ +

+span init flag used to determine if span is being used +

+Definition at line 176 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Method: check if channel is closed. +

+

Parameters:
+ + +
chan chan object
+
+ +
+

+ +

+ +
+ +

+total number of channels configured in the span +

+Definition at line 191 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::open_chan)(struct sangoma_hptdm_span *span, sangoma_hptdm_chan_reg_t *chan_reg, unsigned int chan_no, sangoma_hptdm_chan_t **chan_ptr)
+
+
+ +

+Method: open a channel inside a span. +

+

Parameters:
+ + + + + +
span span object
chan_reg channel registration structure: callbacks and cfg
chan_no channel number - integer starting from 0
chan_ptr user container for channel object passed up to the user.
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::run_span)(struct sangoma_hptdm_span *span)
+
+
+ +

+Method: run main span execution logic: rx/tx/oob. +

+

Parameters:
+ + +
span span object
+
+Run main span execution logic. This function peforms all socket operations on a hw interface. Rx/Tx/Oob. Receives data and demultiplexes it to channels. Receives oob data and passes user events global to all channels. Multiplexes all channel tx data into a single tx data block and passes it to hw iface. +
+

+ +

+
+ + + + +
char sangoma_hptdm_span::rx_data[SMG_HP_MAX_SPAN_DATA]
+
+
+ +

+span rx data block: used to receive a block of data from hw interface: recv() +

+Definition at line 209 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span rx data len, obtained after a recv() call to hw interface +

+Definition at line 212 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_span::sock
+
+
+ +

+span socket file descriptor used to rx/tx data to and from hw interface +

+Definition at line 185 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
wan_if_cfg_t sangoma_hptdm_span::span_cfg
+
+
+ +

+span config structure obtained from hw interface via managment ioctl call. +

+Definition at line 224 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span number - integer starting from 0 +

+Definition at line 179 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span registration functions: contains user callback functions +

+Definition at line 221 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
unsigned int sangoma_hptdm_span::timeslot_cfg
+
+
+ +

+bit map of configured timeslots obtained from hw interface +

+Definition at line 200 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
char sangoma_hptdm_span::tx_data[SMG_HP_MAX_SPAN_DATA]
+
+
+ +

+span tx data block: used to transmit a block of data to hw interface: send() +

+Definition at line 215 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span tx data block len: passed to send() function +

+Definition at line 218 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+total tx data size to hw interface. tx_size = max_chans * chunk_sz +

+Definition at line 194 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
wan_udp_hdr_t sangoma_hptdm_span::wan_udp
+
+
+ +

+span managment structure used to execute mgmnt ioctl commands to hw interface +

+Definition at line 227 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.map.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.map.svn-base new file mode 100644 index 0000000..5cef49e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.map.svn-base @@ -0,0 +1,6 @@ +base referer +rect $structsangoma__hptdm__span__reg.html 5,215 200,241 +rect $structsangoma__hptdm__chan__map.html 224,215 427,241 +rect $structsangoma__hptdm__chan.html 241,119 409,145 +rect $structsangoma__hptdm__chan__reg.html 139,7 333,33 +rect $structhp__tdm__chunk.html 357,7 472,33 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.md5.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.md5.svn-base new file mode 100644 index 0000000..3b36353 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.md5.svn-base @@ -0,0 +1 @@ +dbfe10cc718b1da1aa9b9afb65255814 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.png.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__coll__graph.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..38b15ef145265c43014f398c81895a35d832bc9f GIT binary patch literal 17583 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 JU()c!{{bo<10eta literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg-members.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg-members.html.svn-base new file mode 100644 index 0000000..afb81a6 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg-members.html.svn-base @@ -0,0 +1,27 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_span_reg Member List

This is the complete list of members for sangoma_hptdm_span_reg, including all inherited members.

+ + + +
logsangoma_hptdm_span_reg
psangoma_hptdm_span_reg
rx_eventsangoma_hptdm_span_reg


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg.html.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg.html.svn-base new file mode 100644 index 0000000..6649464 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/structsangoma__hptdm__span__reg.html.svn-base @@ -0,0 +1,93 @@ + + +libhpsangoma: sangoma_hptdm_span_reg Struct Reference + + + + + + +

sangoma_hptdm_span_reg Struct Reference

Span registration structure. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + +

Public Attributes

void * p
void(* log )(int level, FILE *fp, char *file, const char *func, int line, char *fmt,...)
int(* rx_event )(void *p, hp_tdmapi_rx_event_t *data)
+


Detailed Description

+Span registration structure. +

+ +

+Definition at line 72 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
void(* sangoma_hptdm_span_reg::log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt,...)
+
+
+ +

+callback function to implement library logging +

+

+ +

+
+ + + + +
void* sangoma_hptdm_span_reg::p
+
+
+ +

+pointer to user object used with callback functions +

+Definition at line 75 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_span_reg::rx_event)(void *p, hp_tdmapi_rx_event_t *data)
+
+
+ +

+callback function to span global events for all channels in a span +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..0d623483ffdf5f9f96900108042a7ab0643fe2a3 GIT binary patch literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..9b1e6337c9299a700401a2a78a2c6ffced475216 GIT binary patch literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..ce9dd9f533cb5486d6941844f442b59d4a9e9175 GIT binary patch literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/.svn/text-base/tabs.css.svn-base b/api/libsangoma/docs/doxygen/html/.svn/text-base/tabs.css.svn-base new file mode 100644 index 0000000..a61552a --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/.svn/text-base/tabs.css.svn-base @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/api/libsangoma/docs/doxygen/html/annotated.html b/api/libsangoma/docs/doxygen/html/annotated.html new file mode 100644 index 0000000..f7c233e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/annotated.html @@ -0,0 +1,31 @@ + + +libhpsangoma: Class List + + + + + + +

libhpsangoma Class List

Here are the classes, structs, unions and interfaces with brief descriptions: + + + + + + +
hp_tdm_chunkA chunk structure used to implement a chunk buffer
sangoma_hptdm_chanChannel structure, describes a single timeslot/channel in a span
sangoma_hptdm_chan_mapStructure describing a array index of a channel inside the span structure
sangoma_hptdm_chan_regChan registration structure
sangoma_hptdm_spanSpan structure. Structure describing a single span
sangoma_hptdm_span_regSpan registration structure
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/doxygen.css b/api/libsangoma/docs/doxygen/html/doxygen.css new file mode 100644 index 0000000..5d58369 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/doxygen.css @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } + diff --git a/api/libsangoma/docs/doxygen/html/doxygen.png b/api/libsangoma/docs/doxygen/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..f0a274bbaffdd67f6d784c894d9cf28729db0e14 GIT binary patch literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/files.html b/api/libsangoma/docs/doxygen/html/files.html new file mode 100644 index 0000000..6396ef7 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/files.html @@ -0,0 +1,24 @@ + + +libhpsangoma: File Index + + + + + +

libhpsangoma File List

Here is a list of all documented files with brief descriptions: + + + + +
libhpsangoma.c [code]
libhpsangoma.h [code]
libhpsangoma_priv.c [code]
libhpsangoma_priv.h [code]
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/functions.html b/api/libsangoma/docs/doxygen/html/functions.html new file mode 100644 index 0000000..b5a617c --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/functions.html @@ -0,0 +1,120 @@ + + +libhpsangoma: Class Members + + + + + + +
+ +
+
+ +
+ +

+Here is a list of all documented class members with links to the class documentation for each member: +

+

- c -

+

- d -

+

- e -

+

- g -

+

- h -

+

- i -

+

- l -

+

- m -

+

- o -

+

- p -

+

- r -

+

- s -

+

- t -

+

- w -

+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/functions_vars.html b/api/libsangoma/docs/doxygen/html/functions_vars.html new file mode 100644 index 0000000..069284a --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/functions_vars.html @@ -0,0 +1,120 @@ + + +libhpsangoma: Class Members - Variables + + + + + + +
+ +
+
+ +
+ +

+  +

+

- c -

+

- d -

+

- e -

+

- g -

+

- h -

+

- i -

+

- l -

+

- m -

+

- o -

+

- p -

+

- r -

+

- s -

+

- t -

+

- w -

+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/graph_legend.dot b/api/libsangoma/docs/doxygen/html/graph_legend.dot new file mode 100644 index 0000000..4a1a09c --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/graph_legend.dot @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="FreeSans.ttf",fontsize=10,labelfontname="FreeSans.ttf",labelfontsize=10]; + node [fontname="FreeSans.ttf",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",fillcolor="grey75",style="filled" fontcolor="black"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="FreeSans.ttf"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="FreeSans.ttf"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classUsed.html"]; +} diff --git a/api/libsangoma/docs/doxygen/html/graph_legend.html b/api/libsangoma/docs/doxygen/html/graph_legend.html new file mode 100644 index 0000000..91e5a73 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/graph_legend.html @@ -0,0 +1,80 @@ + + +libhpsangoma: Graph Legend + + + + + +

Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

+Consider the following example:

/*! Invisible class because of truncation */
+class Invisible { };
+
+/*! Truncated class, inheritance relation is hidden */
+class Truncated : public Invisible { };
+
+/* Class not documented with doxygen comments */
+class Undocumented { };
+
+/*! Class that is inherited using public inheritance */
+class PublicBase : public Truncated { };
+
+/*! A template class */
+template<class T> class Templ { };
+
+/*! Class that is inherited using protected inheritance */
+class ProtectedBase { };
+
+/*! Class that is inherited using private inheritance */
+class PrivateBase { };
+
+/*! Class that is used by the Inherited class */
+class Used { };
+
+/*! Super class that inherits a number of other classes */
+class Inherited : public PublicBase,
+                  protected ProtectedBase,
+                  private PrivateBase,
+                  public Undocumented
+                  public Templ<int>
+{
+  private:
+    Used *m_usedClass;
+};
+
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

+

+graph_legend.png +
+

+The boxes in the above graph have the following meaning:

    +
  • +A filled black box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a grey border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+The arrows have the following meaning:
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/graph_legend.png b/api/libsangoma/docs/doxygen/html/graph_legend.png new file mode 100644 index 0000000000000000000000000000000000000000..f937e8510ff86b63eb7e4bccafa42ce692df9689 GIT binary patch literal 21232 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 literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/index.html b/api/libsangoma/docs/doxygen/html/index.html new file mode 100644 index 0000000..17484bf --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/index.html @@ -0,0 +1,20 @@ + + +libhpsangoma: Main Page + + + + + +

libhpsangoma Documentation

+

+

1


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/libhpsangoma_8c-source.html b/api/libsangoma/docs/doxygen/html/libhpsangoma_8c-source.html new file mode 100644 index 0000000..ace7165 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/libhpsangoma_8c-source.html @@ -0,0 +1,412 @@ + + +libhpsangoma: libhpsangoma.c Source File + + + + + +

libhpsangoma.c

00001 /*****************************************************************************
+00002  * libhpsangoma.c:  Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  *
+00014  */
+00015 
+00016 #include "libhpsangoma.h"
+00017 #include "libhpsangoma_priv.h"
+00018 
+00019 /*---------------------------------------------------------
+00020   PRIVATE STRUCTURES
+00021  ----------------------------------------------------------*/
+00022 
+00023 void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)=NULL;
+00024 
+00025 
+00034 static int sangoma_hp_tdm_chan_push(struct sangoma_hptdm_chan *chan, char *data, int len)
+00035 {
+00036         hp_tmd_chunk_t *tx_chunk;
+00037         int free_slots;
+00038 
+00039         if (!chan->init) {
+00040                 return -2;
+00041         }
+00042 
+00043         if (len >= SMG_HP_MAX_CHAN_DATA) {
+00044                 /* Data Too Big */
+00045                 lib_printf(0,NULL,"chan_push c%i tx chunk len %i too big\n",
+00046                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in,len);
+00047                 return -1;
+00048         }
+00049 
+00050         /* Lock */
+00051         if (chan->tx_idx_in >= chan->tx_idx_out) {
+00052                 free_slots=SMG_HP_TDM_CHUNK_IDX_SZ-(chan->tx_idx_in-chan->tx_idx_out);
+00053         } else {
+00054                 free_slots=chan->tx_idx_out-chan->tx_idx_in;
+00055         }
+00056         /* Un Lock */
+00057 
+00058         if (!free_slots) {
+00059                 /* We have just overruned the tx buffer */
+00060                 lib_printf(0,NULL,"chan_push c%i failed no free slots in %i out %i\n",
+00061                                 chan->span_no+1,chan->chan_no+1, chan->tx_idx_in,chan->tx_idx_out);
+00062                 return 1;
+00063         }
+00064 
+00065         tx_chunk = &chan->tx_idx[chan->tx_idx_in];
+00066         if (tx_chunk->init) {
+00067                 /* This should NEVER happen the chunk should be free */
+00068                 lib_printf(15,NULL,"chan_push s%ic%i tx chunk overrun in %i \n",
+00069                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
+00070                 return 1;
+00071         }
+00072 
+00073         memset(tx_chunk,0,sizeof(hp_tmd_chunk_t));
+00074         memcpy(&tx_chunk->data,data,len);
+00075         tx_chunk->len=len;
+00076         tx_chunk->init=1;
+00077 
+00078         lib_printf(15,NULL,"chan_push s%ic%i tx chunk in %i \n",
+00079                                 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
+00080 
+00081         chan->tx_idx_in++;
+00082         if (chan->tx_idx_in >= SMG_HP_TDM_CHUNK_IDX_SZ) {
+00083                 chan->tx_idx_in=0;
+00084         }
+00085 
+00086         return 0;
+00087 }
+00088 
+00089 /*-------------------------------------------------
+00090   Internal Span Methods
+00091  -------------------------------------------------*/
+00092 
+00093 
+00103 static int sangoma_hp_tdm_open_chan(sangoma_hptdm_span_t *span,
+00104                               sangoma_hptdm_chan_reg_t *cfg,
+00105                               unsigned int chan_no,
+00106                               sangoma_hptdm_chan_t **chan_ptr)
+00107 {
+00108         sangoma_hptdm_chan_t *chan;
+00109 
+00110         if (!span->init) {
+00111                 return -1;
+00112         }
+00113 
+00114         if (chan_no >= SMG_HP_TDM_MAX_CHANS) {
+00115                 lib_printf(0,NULL,"open_chan failed chan_no %i >= max chans %i\n",
+00116                                 chan_no, SMG_HP_TDM_MAX_CHANS);
+00117                 return -1;
+00118         }
+00119 
+00120         if (!cfg->rx_data || !cfg->p) {
+00121                 return -1;
+00122         }
+00123 
+00124         if (span->chan_idx[chan_no].chan_no_hw < 0) {
+00125                 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is not mapped to hardware\n",
+00126                                 span->span_no+1,chan_no+1);
+00127                 return -1;
+00128         }
+00129 
+00130         chan = &span->chan_idx[chan_no].chan;
+00131         if (chan->init) {
+00132                 /* Chan Busy */
+00133                 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is busy\n",
+00134                                 span->span_no+1,chan_no+1);
+00135                 return 1;
+00136         }
+00137 
+00138         memset(chan,0,sizeof(sangoma_hptdm_chan_t));
+00139 
+00140         chan->chan_no = chan_no;
+00141         chan->span = span;
+00142         memcpy(&chan->chan_reg, cfg, sizeof(sangoma_hptdm_chan_reg_t));
+00143 
+00144         chan->push = sangoma_hp_tdm_chan_push;
+00145 
+00146         chan->init=1;
+00147         lib_printf(15,NULL,"open_chan chan_no s%ic%i ok\n",
+00148                                 span->span_no+1,chan_no+1);
+00149 
+00150         *chan_ptr = chan;
+00151 
+00152         return 0;
+00153 
+00154 }
+00155 
+00156 
+00163 static int sangoma_hp_tdm_close_chan(sangoma_hptdm_chan_t *chan)
+00164 {
+00165         chan->init=0;
+00166         chan->chan_reg.p=NULL;
+00167         lib_printf(15,NULL,"close_chan chan_no s%ic%i ok\n",
+00168                                 chan->span_no+1,chan->chan_no+1);
+00169         return 0;
+00170 }
+00171 
+00172 
+00178 static int sangoma_hp_tdm_is_chan_closed (sangoma_hptdm_chan_t *chan)
+00179 {
+00180         return (chan->init == 0) ? 1:0;
+00181 }
+00182 
+00188 static int sangoma_hp_tdm_close_span(sangoma_hptdm_span_t *span)
+00189 {
+00190         int i;
+00191         sangoma_hptdm_chan_t *chan=NULL;
+00192 
+00193         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00194                 chan = &span->chan_idx[i].chan;
+00195                 if (chan->init) {
+00196                         chan->init=0;
+00197                 }
+00198         }
+00199 
+00200         close(span->sock);
+00201         span->sock=-1;
+00202 
+00203         return 0;
+00204 }
+00205 
+00211 static int sangoma_hp_tdm_event_ctrl_span(sangoma_hptdm_span_t *span, hp_tdmapi_tx_event_t *event)
+00212 {
+00213         int err;
+00214 
+00215         if (!span->init || span->sock < 0) {
+00216                 return -1;
+00217         }
+00218 
+00219         err = ioctl(span->sock,SIOC_WANPIPE_API,event);
+00220         if (err < 0){
+00221                 lib_printf(0,NULL,"Error: SPAN %i Failed to execute event!\n",
+00222                                 span->span_no+1);
+00223                 return -1;
+00224         }
+00225 
+00226         return 0;
+00227 }
+00228 
+00234 static int sangoma_hp_tdm_event_get_cfg(sangoma_hptdm_span_t *span, wan_if_cfg_t *if_cfg)
+00235 {
+00236         memcpy(if_cfg,&span->span_cfg,sizeof(if_cfg));
+00237         return 0;
+00238 }
+00239 
+00245 static int sangoma_hp_tdm_run_span(sangoma_hptdm_span_t *span)
+00246 {
+00247         int err=0;
+00248         fd_set  sock_read,sock_write,sock_oob;
+00249 
+00250         if (!span->init) {
+00251                 lib_printf(0, NULL, "Span %i not initialized %i\n",span->span_no+1);
+00252                 return -1;
+00253         }
+00254 
+00255         lib_printf(15, NULL, "Starting RUN SPAN %i Sock=%i\n",span->span_no+1, span->sock);
+00256 
+00257         if (span->sock < 0) {
+00258                 err=sangoma_hptdm_span_open(span);
+00259                 if (err) {
+00260                         usleep(500000);
+00261                         err=-2;
+00262                         goto sangoma_hp_tdm_run_span_exit;
+00263                 }
+00264         }
+00265 
+00266         /* Initialize all select() descriptors */
+00267         FD_ZERO(&sock_read);
+00268         FD_ZERO(&sock_write);
+00269         FD_ZERO(&sock_oob);
+00270 
+00271         FD_SET(span->sock,&sock_oob);
+00272         FD_SET(span->sock,&sock_read);
+00273         FD_SET(span->sock,&sock_write);
+00274 
+00275         err=select(span->sock + 1,&sock_read, NULL, &sock_oob, NULL);
+00276 
+00277         if (err > 0) {
+00278 
+00279                 if (FD_ISSET(span->sock,&sock_oob)){
+00280                         err=sangoma_hp_tdm_handle_oob_event(span);
+00281                         if (err) {
+00282                                 lib_printf(0, NULL, "RUN SPAN: %i oob err %i\n",
+00283                                         span->span_no+1, err);
+00284                                 err=-3;
+00285                                 goto sangoma_hp_tdm_run_span_exit;
+00286                         }
+00287                 }
+00288                 if (FD_ISSET(span->sock,&sock_read)){
+00289                         err=sangoma_hp_tdm_handle_read_event(span);
+00290                         if (err) {
+00291                                 lib_printf(0, NULL, "RUN SPAN: %i read err %i\n",
+00292                                         span->span_no+1, err);
+00293                                 err=-4;
+00294                                 goto sangoma_hp_tdm_run_span_exit;
+00295                         }
+00296 
+00297                         err=sangoma_hp_tdm_handle_write_event(span);
+00298                         if (err) {
+00299                                 lib_printf(0, NULL, "RUN SPAN: %i write err %i\n",
+00300                                         span->span_no+1, err);
+00301                                 err=-5;
+00302                                 goto sangoma_hp_tdm_run_span_exit;
+00303                         }
+00304                 }
+00305 
+00306         } else if (err==0) {
+00307                 /* Timeout continue */
+00308                 return 0;
+00309 
+00310         } else {
+00311                 /* Error */
+00312                 if (errno == EAGAIN) {
+00313                         goto sangoma_hp_tdm_run_span_exit;
+00314                 }
+00315 
+00316                 err=-6;
+00317         }
+00318 
+00319 sangoma_hp_tdm_run_span_exit:
+00320 
+00321         if (err < 0) {
+00322                 if (span->sock) {
+00323                         close(span->sock);
+00324                         span->sock=-1;
+00325                 }
+00326         }
+00327 
+00328         return err;
+00329 }
+00330 
+00331 
+00332 
+00333 /*---------------------------------------------------------
+00334   PUBLIC STRUCTURES
+00335  ----------------------------------------------------------*/
+00336 
+00337 
+00338 /*
+00339   \brief Initialize and Configure Span - private functions not to be used directly!
+00340   \param span_no span number - integer
+00341   \param cfg span registration struct
+00342   \param version library version number added by the macro
+00343   \return NULL: fail,  Span Object: pass
+00344  *
+00345  * The __sangoma_hptdm_api_span_init() function must NOT be called directly!
+00346  *  One MUST use defined sangoma_hptdm_api_span_init() macro instead
+00347  */
+00348 
+00349 sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version)
+00350 {
+00351         int err,i,ch=0;
+00352         sangoma_hptdm_span_t *span;
+00353 
+00354         span = malloc(sizeof(sangoma_hptdm_span_t));
+00355         if (!span) {
+00356                 return NULL;
+00357         }
+00358 
+00359         memset(span,0,sizeof(sangoma_hptdm_span_t));
+00360 
+00361         span->span_no=span_no;
+00362         sprintf(span->if_name,"w%ig1",span_no+1);
+00363 
+00364         if (cfg) {
+00365                 memcpy(&span->span_reg,cfg,sizeof(sangoma_hptdm_span_reg_t));
+00366                 if (!lib_log) {
+00367                         lib_log=cfg->log;
+00368                 }
+00369         }
+00370 
+00371         err=sangoma_hptdm_span_open(span);
+00372         if (err) {
+00373                 free(span);
+00374                 return NULL;
+00375         }
+00376 
+00377         if (span->span_cfg.media == WAN_MEDIA_E1) {
+00378                 span->span_cfg.active_ch = span->span_cfg.active_ch >> 1;
+00379         }
+00380 
+00381         lib_printf(0,NULL,"Span %i Configuration\n",span->span_no+1);
+00382         lib_printf(0,NULL,"Used By\t:%i\n",span->span_cfg.usedby);
+00383         lib_printf(0,NULL,"Media\t:%i\n",span->span_cfg.media);
+00384         lib_printf(0,NULL,"Active Ch\t:0x%08X\n",span->span_cfg.active_ch);
+00385         lib_printf(0,NULL,"Chunk Sz\t:%i\n",span->span_cfg.chunk_sz);
+00386         lib_printf(0,NULL,"HW Coding\t:%i\n",span->span_cfg.hw_coding);
+00387         lib_printf(0,NULL,"If Number\t:%i\n",span->span_cfg.interface_number);
+00388 
+00389 
+00390         /* Map all channels to the actually configued on hardware */
+00391         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00392                 span->chan_idx[i].chan_no_hw=-1;
+00393                 if (span->span_cfg.active_ch & (1<<i)) {
+00394                         span->chan_idx[i].chan_no_hw=ch;
+00395                         lib_printf(0,NULL,"Chan %i Mapped to %i",i,ch);
+00396                         ch++;
+00397                         span->max_chans++;
+00398                 } else {
+00399                         lib_printf(0,NULL,"Chan %i Not Mapped",i);
+00400                 }
+00401         }
+00402 
+00403         lib_printf(0,NULL,"Total Chans\t:%i\n",span->max_chans);
+00404 
+00405         /* Must be configurable */
+00406         span->chunk_sz=span->span_cfg.chunk_sz;
+00407         span->tx_size=span->max_chans*span->chunk_sz;
+00408 
+00409         span->init=1;
+00410         span->idle=0xFF;
+00411 
+00412         span->open_chan = sangoma_hp_tdm_open_chan;
+00413         span->close_chan = sangoma_hp_tdm_close_chan;
+00414         span->is_chan_closed = sangoma_hp_tdm_is_chan_closed;
+00415         span->run_span =sangoma_hp_tdm_run_span;
+00416         span->close_span = sangoma_hp_tdm_close_span;
+00417         span->event_ctrl = sangoma_hp_tdm_event_ctrl_span;
+00418         span->get_cfg = sangoma_hp_tdm_event_get_cfg;
+00419 
+00420         lib_printf(5, NULL, "Span %i Initialized\n",span->span_no+1);
+00421 
+00422         return span;
+00423 }
+00424 
+00425 /*
+00426   \brief Free, Un-Initialize Span
+00427   \param span_no span object
+00428   \return 0 = pass, non zero fail
+00429  */
+00430 
+00431 int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span)
+00432 {
+00433         if (span->sock >= 0) {
+00434                 span->close_span(span);
+00435         }
+00436 
+00437         free(span);
+00438         span=NULL;
+00439 
+00440         return 0;
+00441 }
+00442 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/libhpsangoma_8h-source.html b/api/libsangoma/docs/doxygen/html/libhpsangoma_8h-source.html new file mode 100644 index 0000000..6d27991 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/libhpsangoma_8h-source.html @@ -0,0 +1,223 @@ + + +libhpsangoma: libhpsangoma.h Source File + + + + + +

libhpsangoma.h

00001 /*****************************************************************************
+00002  * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  */
+00014 
+00015 #ifndef _LIB_HP_SNAGOMA_H
+00016 #define _LIB_HP_SNAGOMA_H
+00017 
+00018 
+00019 #ifdef WIN32
+00020 
+00021 #error "WINDOWS NOT DEFINED"
+00022 
+00023 #else
+00024 /* L I N U X */
+00025 #include <stdio.h>
+00026 #include <stdlib.h>
+00027 #include <ctype.h>
+00028 #include <unistd.h>
+00029 #include <sys/time.h>
+00030 #include <sys/socket.h>
+00031 #include <sys/ioctl.h>
+00032 #include <sys/types.h>
+00033 #include <sys/signal.h>
+00034 #include <sys/select.h>
+00035 #include <sys/wait.h>
+00036 #include <sys/resource.h>
+00037 #include <netinet/in.h>
+00038 #include <string.h>
+00039 #include <errno.h>
+00040 #include <fcntl.h>
+00041 #include <linux/if.h>
+00042 #include <poll.h>
+00043 #include <signal.h>
+00044 
+00045 
+00046 #include <linux/wanpipe_defines.h>
+00047 #include <linux/wanpipe_common.h>
+00048 #include <linux/wanpipe_cfg.h>
+00049 #include <linux/wanpipe.h>
+00050 #include <linux/if_wanpipe.h>
+00051 #include <linux/sdla_aft_te1.h>
+00052 #endif
+00053 
+00054 #define SMG_HP_MAX_CHAN_DATA 1024
+00055 #define SMG_HP_TDM_CHUNK_IDX_SZ 16
+00056 #define SMG_HP_TDM_MAX_CHANS 31
+00057 #define SMG_HP_MAX_SPAN_DATA (31*160)+32
+00058 
+00059 #define hp_tdmapi_rx_event_t api_rx_hdr_t
+00060 #define hp_tdmapi_tx_event_t api_tx_hdr_t
+00061 
+00062 #define SANGOMA_HPTDM_VERSION 1
+00063 
+00064 /*---------------------------------------------------------
+00065  * PUBLIC DEFINITIONS
+00066  */
+00067 
+00068 
+00072 typedef struct sangoma_hptdm_span_reg
+00073 {
+00075         void *p;
+00077         void (*log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00079         int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data);
+00080 }sangoma_hptdm_span_reg_t;
+00081 
+00082 
+00086 typedef struct hp_tdm_chunk
+00087 {
+00089         int init;
+00091         int len;
+00093         int offset;
+00095         char data[SMG_HP_MAX_CHAN_DATA];
+00096 }hp_tmd_chunk_t;
+00097 
+00101 typedef struct sangoma_hptdm_chan_reg
+00102 {
+00104         void *p;
+00106         int (*rx_data)(void *p, char *data, int len);
+00108         int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data);
+00109 
+00110 }sangoma_hptdm_chan_reg_t;
+00111 
+00115 typedef struct sangoma_hptdm_chan
+00116 {
+00118         int init;
+00119 
+00121         int chan_no;
+00122 
+00124         int span_no;
+00125 
+00127         void *span;
+00128 
+00130         hp_tmd_chunk_t rx_chunk;
+00131 
+00133         hp_tmd_chunk_t tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ];
+00134 
+00136         int tx_idx_in;
+00137 
+00139         int tx_idx_out;
+00140 
+00142         int (*push)(struct sangoma_hptdm_chan *, char *data, int len);
+00143 
+00145         sangoma_hptdm_chan_reg_t chan_reg;
+00146 
+00147 }sangoma_hptdm_chan_t;
+00148 
+00157 typedef struct sangoma_hptdm_chan_map
+00158 {
+00162         int chan_no_hw;
+00163 
+00165         sangoma_hptdm_chan_t chan;
+00166 
+00167 }sangoma_hptdm_chan_map_t;
+00168 
+00169 
+00173 typedef struct sangoma_hptdm_span
+00174 {
+00176         int init;
+00177 
+00179         int span_no;
+00180 
+00182         char if_name[100];
+00183 
+00185         int sock;
+00186 
+00188         int chunk_sz;
+00189 
+00191         int max_chans;
+00192 
+00194         int tx_size;
+00195 
+00197         unsigned char idle;
+00198 
+00200         unsigned int timeslot_cfg;
+00201 
+00203         unsigned int hwcoding;
+00204 
+00206         sangoma_hptdm_chan_map_t chan_idx[SMG_HP_TDM_MAX_CHANS];
+00207 
+00209         char rx_data[SMG_HP_MAX_SPAN_DATA];
+00210 
+00212         int rx_len;
+00213 
+00215         char tx_data[SMG_HP_MAX_SPAN_DATA];
+00216 
+00218         int tx_len;
+00219 
+00221         sangoma_hptdm_span_reg_t span_reg;
+00222 
+00224         wan_if_cfg_t span_cfg;
+00225 
+00227         wan_udp_hdr_t wan_udp;
+00228 
+00235         int (*open_chan)(struct sangoma_hptdm_span *span,
+00236                               sangoma_hptdm_chan_reg_t *chan_reg,
+00237                               unsigned int chan_no,
+00238                               sangoma_hptdm_chan_t **chan_ptr);
+00239 
+00243         int (*close_chan)(sangoma_hptdm_chan_t *chan);
+00244 
+00247         int (*is_chan_closed)(sangoma_hptdm_chan_t *chan);
+00248 
+00259         int (*run_span)(struct sangoma_hptdm_span *span);
+00260 
+00263         int (*close_span)(struct sangoma_hptdm_span *span);
+00264 
+00269         int (*event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event);
+00270 
+00275         int (*get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg);
+00276 
+00277 
+00278 }sangoma_hptdm_span_t;
+00279 
+00280 /*---------------------------------------------------------
+00281  * PUBLIC FUNCTIONS
+00282  */
+00283 
+00291 /* Initialize and Configure a Span  */
+00292 #define sangoma_hptdm_api_span_init(span,cfg) __sangoma_hptdm_api_span_init(span, cfg, SANGOMA_HPTDM_VERSION);
+00293 
+00305  /*
+00306   * The __sangoma_hptdm_api_span_init() function must NOT be called directly!
+00307   * One MUST use defined sangoma_hptdm_api_span_init() macro instead
+00308   */
+00309 extern sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version);
+00310 
+00311 
+00317 extern int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span);
+00318 
+00319 
+00320 
+00321 
+00322 
+00323 #endif
+00324 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8c-source.html b/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8c-source.html new file mode 100644 index 0000000..fc7572b --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8c-source.html @@ -0,0 +1,362 @@ + + +libhpsangoma: libhpsangoma_priv.c Source File + + + + + +

libhpsangoma_priv.c

00001 /*****************************************************************************
+00002  * libhpsangoma_priv.c:  Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  *
+00014  */
+00015 
+00016 #include "libhpsangoma.h"
+00017 #include "libhpsangoma_priv.h"
+00018 #define DFT_CARD "wanpipe1"
+00019 
+00020 
+00031 int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
+00032 {
+00033         int rx_len=0;
+00034 
+00035 #if defined(WIN32)
+00036 
+00037 #error "WINDOWS HP TDMAPI NOT DEFINED"
+00038 
+00039 #else
+00040         struct msghdr msg;
+00041         struct iovec iov[2];
+00042 
+00043         memset(&msg,0,sizeof(struct msghdr));
+00044 
+00045         iov[0].iov_len=hdrlen;
+00046         iov[0].iov_base=hdrbuf;
+00047 
+00048         iov[1].iov_len=datalen;
+00049         iov[1].iov_base=databuf;
+00050 
+00051         msg.msg_iovlen=2;
+00052         msg.msg_iov=iov;
+00053 
+00054         rx_len = recvmsg(fd,&msg,0);
+00055 
+00056         if (rx_len <= sizeof(api_rx_hdr_t)){
+00057                 return -EINVAL;
+00058         }
+00059 
+00060         rx_len-=sizeof(api_rx_hdr_t);
+00061 #endif
+00062 
+00063         return rx_len;
+00064 }
+00065 
+00066 
+00067 
+00078 int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
+00079 {
+00080         int bsent;
+00081 
+00082 #if defined(WIN32)
+00083 
+00084 #error "Windows TX not implemented"
+00085 
+00086 #else
+00087         struct msghdr msg;
+00088         struct iovec iov[2];
+00089 
+00090         memset(&msg,0,sizeof(struct msghdr));
+00091 
+00092         iov[0].iov_len=hdrlen;
+00093         iov[0].iov_base=hdrbuf;
+00094 
+00095         iov[1].iov_len=datalen;
+00096         iov[1].iov_base=databuf;
+00097 
+00098         msg.msg_iovlen=2;
+00099         msg.msg_iov=iov;
+00100 
+00101         bsent = sendmsg(fd,&msg,0);
+00102         if (bsent > 0){
+00103                 bsent-=sizeof(api_tx_hdr_t);
+00104         }
+00105 #endif
+00106         return bsent;
+00107 }
+00108 
+00114 int do_wanpipemon_cmd(sangoma_hptdm_span_t *span)
+00115 {
+00116         struct ifreq ifr;
+00117         memset(&ifr,0,sizeof(ifr));
+00118         ifr.ifr_data = (void*)&span->wan_udp;
+00119         sprintf (ifr.ifr_name, "%s", span->if_name);
+00120         return ioctl(span->sock,SIOC_WANPIPE_PIPEMON,&ifr);
+00121 }
+00122 
+00128 unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span)
+00129 {
+00130         span->wan_udp.wan_udphdr_command = READ_CONFIGURATION;
+00131         span->wan_udp.wan_udphdr_data_len = 0;
+00132         span->wan_udp.wan_udphdr_return_code = 0xaa;
+00133         do_wanpipemon_cmd(span);
+00134         if (span->wan_udp.wan_udphdr_return_code != 0){
+00135                 lib_printf(0,NULL,"Error: SPAN %i management command failed 0x02Xs (%s)",
+00136                         span->span_no+1, span->wan_udp.wan_udphdr_return_code,strerror(errno));
+00137                 return -1;
+00138         }
+00139 
+00140         memcpy(&span->span_cfg,&span->wan_udp.wan_udphdr_data[0],sizeof(span->span_cfg));
+00141 
+00142         return 0;
+00143 }
+00144 
+00145 
+00152 int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span)
+00153 {
+00154         struct wan_sockaddr_ll  sa;
+00155         char if_name[100];
+00156         int sock=-1;
+00157         int err;
+00158 
+00159         memset(&sa,0,sizeof(struct wan_sockaddr_ll));
+00160         sock = socket(AF_WANPIPE, SOCK_RAW, 0);
+00161         if( sock < 0 ) {
+00162                 perror("Socket");
+00163                 return -1;
+00164         } /* if */
+00165 
+00166         sprintf(if_name, "w%ig1", span->span_no+1);
+00167 
+00168         strcpy( (char*)sa.sll_device, if_name);
+00169         strcpy( (char*)sa.sll_card, DFT_CARD);
+00170         sa.sll_protocol = htons(PVC_PROT);
+00171         sa.sll_family=AF_WANPIPE;
+00172 
+00173         if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
+00174         lib_printf(0,NULL,"bind failed on span span %i %s\n",
+00175                 span->span_no+1,strerror(errno));
+00176                         return -1;
+00177         }
+00178 
+00179         span->sock=sock;
+00180 
+00181         err= sangoma_get_cfg(span);
+00182         if (err) {
+00183                 goto sangoma_hptdm_span_open_error;
+00184         }
+00185 
+00186         lib_printf(0,NULL,"libhp: span %i opened\n",
+00187                         span->span_no+1);
+00188 
+00189         return 0;
+00190 
+00191 sangoma_hptdm_span_open_error:
+00192 
+00193         if (span->sock) {
+00194                 close(span->sock);
+00195                 span->sock=-1;
+00196         }
+00197 
+00198         return err;
+00199 }
+00200 
+00201 
+00208 int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span)
+00209 {
+00210         int err;
+00211         hp_tdmapi_rx_event_t *rx_event;
+00212 
+00213         err = recv(span->sock, span->rx_data, sizeof(span->rx_data), MSG_OOB);
+00214         if (err > 0) {
+00215                 rx_event=(hp_tdmapi_rx_event_t*)&span->rx_data;
+00216                 if (span->span_reg.rx_event && span->span_reg.p) {
+00217                         span->span_reg.rx_event(span->span_reg.p, rx_event);
+00218                 }
+00219         }
+00220         /* For now treat all err as socket reload */
+00221         return 1;
+00222 }
+00223 
+00230 int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span)
+00231 {
+00232         int i=0,x=0,err=0;
+00233         sangoma_hptdm_chan_t *chan=NULL;
+00234         hp_tmd_chunk_t *chunk=NULL;
+00235         int chan_no_hw;
+00236         char *rx_data = &span->rx_data[sizeof(api_rx_hdr_t)];
+00237 
+00238 
+00239         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00240                 chan = &span->chan_idx[i].chan;
+00241                 if (!chan->init) {
+00242                         continue;
+00243                 }
+00244                 chan_no_hw = span->chan_idx[i].chan_no_hw;
+00245 
+00246                 lib_printf(15,NULL, "SPAN %i Chan %i Chunk %i Channelizing\n",
+00247                                 span->span_no+1, chan->chan_no+1, span->chunk_sz);
+00248 
+00249                 chunk = &chan->rx_chunk;
+00250 
+00251                 for (x=0;x<span->chunk_sz;x++) {
+00252                         chunk->data[x] = rx_data[(span->max_chans*x)+chan_no_hw];
+00253                 }
+00254 
+00255                 chunk->len = span->chunk_sz;
+00256                 if (chan->chan_reg.p && chan->chan_reg.rx_data) {
+00257                         err=chan->chan_reg.rx_data(chan->chan_reg.p,chunk->data,chunk->len);
+00258                 } else {
+00259                         err=1;
+00260                 }
+00261 
+00262                 if (err) {
+00263                         chan->init=0;
+00264                         chan->chan_reg.p=NULL;
+00265                 }
+00266 
+00267         }
+00268 
+00269         return err;
+00270 
+00271 
+00272 }
+00273 
+00280 int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span)
+00281 {
+00282         int err;
+00283         hp_tdmapi_rx_event_t *rx_event = (hp_tdmapi_rx_event_t*)&span->rx_data[0];
+00284 
+00285         err = sangoma_readmsg_hp_tdm(span->sock,
+00286                                      &span->rx_data[0],sizeof(api_rx_hdr_t),
+00287                                      &span->rx_data[sizeof(api_rx_hdr_t)],
+00288                                      sizeof(span->rx_data) - sizeof(api_rx_hdr_t),
+00289                                      0);
+00290 
+00291         if (err >  sizeof(api_rx_hdr_t)) {
+00292 
+00293                 lib_printf(15,NULL, "SPAN %i Read Len = %i\n",span->span_no+1,err);
+00294 
+00295                 if (rx_event->event_type) {
+00296 
+00297                         if (span->span_reg.rx_event && span->span_reg.p) {
+00298                                 span->span_reg.rx_event(span->span_reg.p, rx_event);
+00299                         }
+00300 
+00301                 } else {
+00302 
+00303                         if (err % span->chunk_sz) {
+00304                                 lib_printf(0,NULL, "Error: SPAN %i Read Len = %i Block not chunk %i aligned! \n",span->span_no+1,err,span->chunk_sz);
+00305                                 /* Received chunk size is not aligned drop it for now */
+00306                                 return 0;
+00307                         }
+00308 
+00309                         sangoma_hp_tdm_push_rx_data(span);
+00310                 }
+00311 
+00312                 err=0;
+00313 
+00314         } else {
+00315                 if (errno == EAGAIN) {
+00316                         err = 0;
+00317                 } else {
+00318                         err=-1;
+00319                 }
+00320         }
+00321 
+00322         return err;
+00323 }
+00324 
+00325 
+00331 int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span)
+00332 {
+00333         int i=0,x=0,err=0;
+00334         sangoma_hptdm_chan_t *chan;
+00335         hp_tmd_chunk_t *chunk;
+00336         int chan_no_hw=0;
+00337         char *tx_data = &span->tx_data[sizeof(api_tx_hdr_t)];
+00338 
+00339         memset(&span->tx_data,span->idle,sizeof(span->tx_data));
+00340 
+00341 
+00342         for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
+00343                 chan = &span->chan_idx[i].chan;
+00344                 if (!chan->init) {
+00345                         /* This channel is not open */
+00346                         continue;
+00347                 }
+00348                 chan_no_hw=span->chan_idx[i].chan_no_hw;
+00349 
+00350                 chunk = &chan->tx_idx[chan->tx_idx_out];
+00351                 if (!chunk->init) {
+00352                         lib_printf(15,NULL,"span write s%ic%i tx chunk underrun out %i \n",
+00353                                         chan->span_no+1,chan->chan_no+1,chan->tx_idx_out);
+00354                         /* There is no tx data for this channel */
+00355                         continue;
+00356                 }
+00357 
+00358                 for (x=0;x<span->chunk_sz;x++) {
+00359 
+00360                         tx_data[(span->max_chans*x)+chan_no_hw] = chunk->data[chunk->offset];
+00361                         chunk->offset++;
+00362 
+00363                         if (chunk->offset >= chunk->len) {
+00364                                 chunk->init=0;
+00365 
+00366                                 lib_printf(15,NULL,"span write s%ic%i tx chunk out %i \n",
+00367                                         chan->span_no+1,chan->chan_no+1,chan->tx_idx_out);
+00368 
+00369                                 chan->tx_idx_out++;
+00370                                 if (chan->tx_idx_out >= SMG_HP_TDM_CHUNK_IDX_SZ) {
+00371                                         chan->tx_idx_out=0;
+00372                                 }
+00373                                 chunk=&chan->tx_idx[chan->tx_idx_out];
+00374                                 if (!chunk->init) {
+00375                                         /* We are out of tx data on this channel */
+00376                                         break;
+00377                                 }
+00378                         }
+00379                 }
+00380         }
+00381 
+00382 
+00383         err = sangoma_writemsg_hp_tdm(span->sock,
+00384                                      span->tx_data,sizeof(api_tx_hdr_t),
+00385                                      tx_data, span->tx_size,
+00386                                      0);
+00387 
+00388         lib_printf(15, NULL, "SPAN %i TX Len %i Expecting %i\n",
+00389                         span->span_no+1, err, span->tx_size+sizeof(api_tx_hdr_t));
+00390 
+00391         if (err < span->tx_size) {
+00392                 if (errno == EAGAIN) {
+00393                         return 0;
+00394                 } else {
+00395                         return -1;
+00396                 }
+00397         } else {
+00398                 err=0;
+00399         }
+00400 
+00401         return err;
+00402 
+00403 }
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8h-source.html b/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8h-source.html new file mode 100644 index 0000000..275d62f --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/libhpsangoma__priv_8h-source.html @@ -0,0 +1,77 @@ + + +libhpsangoma: libhpsangoma_priv.h Source File + + + + + +

libhpsangoma_priv.h

00001 /*****************************************************************************
+00002  * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library
+00003  *
+00004  * Author(s):   Nenad Corbic <ncorbic@sangoma.com>
+00005  *
+00006  * Copyright:   (c) 2008 Nenad Corbic <ncorbic@sangoma.com>
+00007  *
+00008  *              This program is free software; you can redistribute it and/or
+00009  *              modify it under the terms of the GNU General Public License
+00010  *              as published by the Free Software Foundation; either version
+00011  *              2 of the License, or (at your option) any later version.
+00012  * ============================================================================
+00013  */
+00014 
+00015 #ifndef _LIB_HP_SANGOMA_PRIV_H
+00016 #define _LIB_HP_SANGOMA_PRIV_H
+00017 
+00018 #include "libhpsangoma.h"
+00019 
+00020 
+00025 #define lib_printf(level, fp, fmt, ...) if (lib_log) lib_log(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+00026 
+00027 extern void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00028 
+00029 
+00030 /*---------------------------------------------------------
+00031  * PRIVATE - FUNCTIONS
+00032  */
+00033 
+00044 int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag);
+00045 
+00046 
+00057 int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag);
+00058 
+00064 int do_wanpipemon_cmd(sangoma_hptdm_span_t *span);
+00065 
+00066 
+00072 unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span);
+00073 
+00074 
+00080 int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span);
+00081 
+00082 
+00088 int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span);
+00089 
+00090 
+00096 int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span);
+00097 
+00098 
+00104 int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span);
+00105 
+00106 
+00112 int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span);
+00113 
+00114 
+00115 
+00116 
+00117 #endif
+00118 
+

Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk-members.html b/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk-members.html new file mode 100644 index 0000000..5cfba24 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk-members.html @@ -0,0 +1,28 @@ + + +libhpsangoma: Member List + + + + + + +

hp_tdm_chunk Member List

This is the complete list of members for hp_tdm_chunk, including all inherited members.

+ + + + +
datahp_tdm_chunk
inithp_tdm_chunk
lenhp_tdm_chunk
offsethp_tdm_chunk


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk.html b/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk.html new file mode 100644 index 0000000..d8e5afb --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structhp__tdm__chunk.html @@ -0,0 +1,116 @@ + + +libhpsangoma: hp_tdm_chunk Struct Reference + + + + + + +

hp_tdm_chunk Struct Reference

A chunk structure used to implement a chunk buffer. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + + + +

Public Attributes

int init
int len
int offset
char data [SMG_HP_MAX_CHAN_DATA]
+


Detailed Description

+A chunk structure used to implement a chunk buffer. +

+ +

+Definition at line 86 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
char hp_tdm_chunk::data[SMG_HP_MAX_CHAN_DATA]
+
+
+ +

+chunk data location +

+Definition at line 95 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::init
+
+
+ +

+chunk init flag used to determine if chunk is being used +

+Definition at line 89 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::len
+
+
+ +

+length of the current data chunk +

+Definition at line 91 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int hp_tdm_chunk::offset
+
+
+ +

+current offset to write/read to/from the chunk data structure. +

+Definition at line 93 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan-members.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan-members.html new file mode 100644 index 0000000..c4d72a9 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan-members.html @@ -0,0 +1,34 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan Member List

This is the complete list of members for sangoma_hptdm_chan, including all inherited members.

+ + + + + + + + + + +
chan_nosangoma_hptdm_chan
chan_regsangoma_hptdm_chan
initsangoma_hptdm_chan
pushsangoma_hptdm_chan
rx_chunksangoma_hptdm_chan
spansangoma_hptdm_chan
span_nosangoma_hptdm_chan
tx_idxsangoma_hptdm_chan
tx_idx_insangoma_hptdm_chan
tx_idx_outsangoma_hptdm_chan


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan.html new file mode 100644 index 0000000..8685c84 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan.html @@ -0,0 +1,233 @@ + + +libhpsangoma: sangoma_hptdm_chan Struct Reference + + + + + + +

sangoma_hptdm_chan Struct Reference

Channel structure, describes a single timeslot/channel in a span. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_chan:

Collaboration graph
+ + + + +
[legend]
List of all members. + + + + + + + + + + + + + + + + + + + + + + +

Public Attributes

int init
int chan_no
int span_no
void * span
hp_tmd_chunk_t rx_chunk
hp_tmd_chunk_t tx_idx [SMG_HP_TDM_CHUNK_IDX_SZ]
int tx_idx_in
int tx_idx_out
int(* push )(struct sangoma_hptdm_chan *, char *data, int len)
sangoma_hptdm_chan_reg_t chan_reg
+

Detailed Description

+Channel structure, describes a single timeslot/channel in a span. +

+ +

+Definition at line 115 of file libhpsangoma.h.


Member Data Documentation

+ +
+ +
+ +

+channel number: starting from 0 +

+Definition at line 121 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Channel registration struct used to store user data, cfg and callbacks +

+Definition at line 145 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_chan::init
+
+
+ +

+channel init flag used to determine if chan is being used +

+Definition at line 118 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan::push)(struct sangoma_hptdm_chan *, char *data, int len)
+
+
+ +

+Callback func called by user to push chunk of data into the channel +

+

+ +

+ +
+ +

+Rx chunk buffer used to rx data from the span +

+Definition at line 130 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
void* sangoma_hptdm_chan::span
+
+
+ +

+span object pointer the current channel belongs +

+Definition at line 127 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span number the current channel belongs to: starting from 0 +

+Definition at line 124 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
hp_tmd_chunk_t sangoma_hptdm_chan::tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ]
+
+
+ +

+Circular buffer of tx data chunks used to tx data to span +

+Definition at line 133 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Circular buffer index for user to chan tx +

+Definition at line 136 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Circular buffer index for chan to span tx +

+Definition at line 139 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.map b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.map new file mode 100644 index 0000000..4c991a4 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.map @@ -0,0 +1,3 @@ +base referer +rect $structsangoma__hptdm__chan__reg.html 5,7 200,33 +rect $structhp__tdm__chunk.html 224,7 339,33 diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.md5 b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.md5 new file mode 100644 index 0000000..0875531 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.md5 @@ -0,0 +1 @@ +b71c119d6e01aec1dbb8e5a6536607e2 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.png b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..7224d327d1bd7653944f6745ef0b8c6aa87205e6 GIT binary patch literal 8480 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 + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan_map Member List

This is the complete list of members for sangoma_hptdm_chan_map, including all inherited members.

+ + +
chansangoma_hptdm_chan_map
chan_no_hwsangoma_hptdm_chan_map


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map.html new file mode 100644 index 0000000..a734751 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map.html @@ -0,0 +1,86 @@ + + +libhpsangoma: sangoma_hptdm_chan_map Struct Reference + + + + + + +

sangoma_hptdm_chan_map Struct Reference

Structure describing a array index of a channel inside the span structure. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_chan_map:

Collaboration graph
+ + + + + +
[legend]
List of all members. + + + + + + +

Public Attributes

int chan_no_hw
sangoma_hptdm_chan_t chan
+

Detailed Description

+Structure describing a array index of a channel inside the span structure. +

+Structure describing a array index of a channel inside the span structure. Furthermore the index * also servers as a map from hardware channels to library channels. Hardware might be configured for channels 1-15.17-31, however library always provides all 31 channels +

+ +

+Definition at line 157 of file libhpsangoma.h.


Member Data Documentation

+ +
+ +
+ +

+A channel structure +

+Definition at line 165 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+A hardware channel number that is mapped to the current channel structure. Hardware might be configured for channels 1-15.17-31, however library always provides all 31 channels +

+Definition at line 162 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.map b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.map new file mode 100644 index 0000000..a832cee --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.map @@ -0,0 +1,4 @@ +base referer +rect $structsangoma__hptdm__chan.html 108,119 276,145 +rect $structsangoma__hptdm__chan__reg.html 5,7 200,33 +rect $structhp__tdm__chunk.html 224,7 339,33 diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.md5 b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.md5 new file mode 100644 index 0000000..6a57549 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.md5 @@ -0,0 +1 @@ +40aa88a5db6369be91695855bbf43d42 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.png b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__map__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..1a523d961c6c06adad4d0ce25e734ae96064f514 GIT binary patch literal 11233 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 + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_chan_reg Member List

This is the complete list of members for sangoma_hptdm_chan_reg, including all inherited members.

+ + + +
psangoma_hptdm_chan_reg
rx_datasangoma_hptdm_chan_reg
rx_eventsangoma_hptdm_chan_reg


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__reg.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__reg.html new file mode 100644 index 0000000..c02d1db --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__chan__reg.html @@ -0,0 +1,93 @@ + + +libhpsangoma: sangoma_hptdm_chan_reg Struct Reference + + + + + + +

sangoma_hptdm_chan_reg Struct Reference

Chan registration structure. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + +

Public Attributes

void * p
int(* rx_data )(void *p, char *data, int len)
int(* rx_event )(void *p, hp_tdmapi_rx_event_t *data)
+


Detailed Description

+Chan registration structure. +

+ +

+Definition at line 101 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
void* sangoma_hptdm_chan_reg::p
+
+
+ +

+pointer to user object used with callback functions +

+Definition at line 104 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan_reg::rx_data)(void *p, char *data, int len)
+
+
+ +

+callback function used to pass rx chunk to user application +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_chan_reg::rx_event)(void *p, hp_tdmapi_rx_event_t *data)
+
+
+ +

+callback function used to pass channel specific event to user application +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span-members.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span-members.html new file mode 100644 index 0000000..5f6e4d6 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span-members.html @@ -0,0 +1,49 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_span Member List

This is the complete list of members for sangoma_hptdm_span, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
chan_idxsangoma_hptdm_span
chunk_szsangoma_hptdm_span
close_chansangoma_hptdm_span
close_spansangoma_hptdm_span
event_ctrlsangoma_hptdm_span
get_cfgsangoma_hptdm_span
hwcodingsangoma_hptdm_span
idlesangoma_hptdm_span
if_namesangoma_hptdm_span
initsangoma_hptdm_span
is_chan_closedsangoma_hptdm_span
max_chanssangoma_hptdm_span
open_chansangoma_hptdm_span
run_spansangoma_hptdm_span
rx_datasangoma_hptdm_span
rx_lensangoma_hptdm_span
socksangoma_hptdm_span
span_cfgsangoma_hptdm_span
span_nosangoma_hptdm_span
span_regsangoma_hptdm_span
timeslot_cfgsangoma_hptdm_span
tx_datasangoma_hptdm_span
tx_lensangoma_hptdm_span
tx_sizesangoma_hptdm_span
wan_udpsangoma_hptdm_span


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span.html new file mode 100644 index 0000000..ac474e0 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span.html @@ -0,0 +1,570 @@ + + +libhpsangoma: sangoma_hptdm_span Struct Reference + + + + + + +

sangoma_hptdm_span Struct Reference

Span structure. Structure describing a single span. +More... +

+#include <libhpsangoma.h> +

+Collaboration diagram for sangoma_hptdm_span:

Collaboration graph
+ + + + + + + +
[legend]
List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Attributes

int init
int span_no
char if_name [100]
int sock
int chunk_sz
int max_chans
int tx_size
unsigned char idle
unsigned int timeslot_cfg
unsigned int hwcoding
sangoma_hptdm_chan_map_t chan_idx [SMG_HP_TDM_MAX_CHANS]
char rx_data [SMG_HP_MAX_SPAN_DATA]
int rx_len
char tx_data [SMG_HP_MAX_SPAN_DATA]
int tx_len
sangoma_hptdm_span_reg_t span_reg
wan_if_cfg_t span_cfg
wan_udp_hdr_t wan_udp
int(* open_chan )(struct sangoma_hptdm_span *span, sangoma_hptdm_chan_reg_t *chan_reg, unsigned int chan_no, sangoma_hptdm_chan_t **chan_ptr)
 Method: open a channel inside a span.
int(* close_chan )(sangoma_hptdm_chan_t *chan)
 Method: close a channel inside the span.
int(* is_chan_closed )(sangoma_hptdm_chan_t *chan)
 Method: check if channel is closed.
int(* run_span )(struct sangoma_hptdm_span *span)
 Method: run main span execution logic: rx/tx/oob.
int(* close_span )(struct sangoma_hptdm_span *span)
 Method: close span.
int(* event_ctrl )(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event)
 Method: used by user app to execute events on current span.
int(* get_cfg )(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg)
 Method: request full span configuration from a current span.
+

Detailed Description

+Span structure. Structure describing a single span. +

+ +

+Definition at line 173 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
sangoma_hptdm_chan_map_t sangoma_hptdm_span::chan_idx[SMG_HP_TDM_MAX_CHANS]
+
+
+ +

+array of maximum number of channels in a span +

+Definition at line 206 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+chunk size for each channel inside the span +

+Definition at line 188 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Method: close a channel inside the span. +

+

Parameters:
+ + +
chan chan object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::close_span)(struct sangoma_hptdm_span *span)
+
+
+ +

+Method: close span. +

+

Parameters:
+ + +
span span object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event)
+
+
+ +

+Method: used by user app to execute events on current span. +

+

Parameters:
+ + + +
span span object
event event object
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg)
+
+
+ +

+Method: request full span configuration from a current span. +

+

Parameters:
+ + + +
span span object
cfg configuratoin object to be filled by span
+
+ +
+

+ +

+
+ + + + +
unsigned int sangoma_hptdm_span::hwcoding
+
+
+ +

+hw data encoding: ULAW/ALAW obtained from hw interface +

+Definition at line 203 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
unsigned char sangoma_hptdm_span::idle
+
+
+ +

+idle flag used to fill an unused channel +

+Definition at line 197 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
char sangoma_hptdm_span::if_name[100]
+
+
+ +

+span hw interface name to which span is bounded to +

+Definition at line 182 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_span::init
+
+
+ +

+span init flag used to determine if span is being used +

+Definition at line 176 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+Method: check if channel is closed. +

+

Parameters:
+ + +
chan chan object
+
+ +
+

+ +

+ +
+ +

+total number of channels configured in the span +

+Definition at line 191 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::open_chan)(struct sangoma_hptdm_span *span, sangoma_hptdm_chan_reg_t *chan_reg, unsigned int chan_no, sangoma_hptdm_chan_t **chan_ptr)
+
+
+ +

+Method: open a channel inside a span. +

+

Parameters:
+ + + + + +
span span object
chan_reg channel registration structure: callbacks and cfg
chan_no channel number - integer starting from 0
chan_ptr user container for channel object passed up to the user.
+
+ +
+

+ +

+
+ + + + +
int(* sangoma_hptdm_span::run_span)(struct sangoma_hptdm_span *span)
+
+
+ +

+Method: run main span execution logic: rx/tx/oob. +

+

Parameters:
+ + +
span span object
+
+Run main span execution logic. This function peforms all socket operations on a hw interface. Rx/Tx/Oob. Receives data and demultiplexes it to channels. Receives oob data and passes user events global to all channels. Multiplexes all channel tx data into a single tx data block and passes it to hw iface. +
+

+ +

+
+ + + + +
char sangoma_hptdm_span::rx_data[SMG_HP_MAX_SPAN_DATA]
+
+
+ +

+span rx data block: used to receive a block of data from hw interface: recv() +

+Definition at line 209 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span rx data len, obtained after a recv() call to hw interface +

+Definition at line 212 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int sangoma_hptdm_span::sock
+
+
+ +

+span socket file descriptor used to rx/tx data to and from hw interface +

+Definition at line 185 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
wan_if_cfg_t sangoma_hptdm_span::span_cfg
+
+
+ +

+span config structure obtained from hw interface via managment ioctl call. +

+Definition at line 224 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span number - integer starting from 0 +

+Definition at line 179 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span registration functions: contains user callback functions +

+Definition at line 221 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
unsigned int sangoma_hptdm_span::timeslot_cfg
+
+
+ +

+bit map of configured timeslots obtained from hw interface +

+Definition at line 200 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
char sangoma_hptdm_span::tx_data[SMG_HP_MAX_SPAN_DATA]
+
+
+ +

+span tx data block: used to transmit a block of data to hw interface: send() +

+Definition at line 215 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+span tx data block len: passed to send() function +

+Definition at line 218 of file libhpsangoma.h. +

+

+ +

+ +
+ +

+total tx data size to hw interface. tx_size = max_chans * chunk_sz +

+Definition at line 194 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
wan_udp_hdr_t sangoma_hptdm_span::wan_udp
+
+
+ +

+span managment structure used to execute mgmnt ioctl commands to hw interface +

+Definition at line 227 of file libhpsangoma.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.map b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.map new file mode 100644 index 0000000..5cef49e --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.map @@ -0,0 +1,6 @@ +base referer +rect $structsangoma__hptdm__span__reg.html 5,215 200,241 +rect $structsangoma__hptdm__chan__map.html 224,215 427,241 +rect $structsangoma__hptdm__chan.html 241,119 409,145 +rect $structsangoma__hptdm__chan__reg.html 139,7 333,33 +rect $structhp__tdm__chunk.html 357,7 472,33 diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.md5 b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.md5 new file mode 100644 index 0000000..3b36353 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.md5 @@ -0,0 +1 @@ +dbfe10cc718b1da1aa9b9afb65255814 \ No newline at end of file diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.png b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..38b15ef145265c43014f398c81895a35d832bc9f GIT binary patch literal 17583 zcmd741z1&U`!~30q%kOIB&0!58bnHwMvyLPrKB5?5&;1bBn2dtlJ1rUkyg3{>F%0) zpL726)_Ldq=9+7+8ANpNwfA0YJ^8Df5M@PKd>jfK1OkD7UrtIDfk2snzmKso;TaMM zCJguo(^y_s3UPt_^Px5?8lJ&&yssdQ^#l7d8W;A$<8>Ycf);UK>aMzL;@X6pr_(+>T{|&=4u9BPe8xtNqefuM|8#Z`3bF#GBkJFHv~jzq{jI>sl-MZU5+3Vzg~< zhhTj=kt8+|F|kUyS|^onaBz0HVILzsebE&XJ$ib2VWWS3U>_rl*u%pKkX*->B4E6E z^Aav8XUURCbaZr~MIU{_x9ItiT_!pby`s@vt>UNWjQ0kw^d#IV&{@3blcjN5IqeXO zijLmuU`}~l)0QT$A^-59l(BKzI8SgQ^}(&h@9>rTd;89Rp7&oa;@=-E%PcJ|DYIP7 z&dXaH+T4O3>Mm|Fyri(7mU_=&WA16-4EU#W~PLrRQO>&vM`{c=un%dgFa$AG$L_sx*%poft%l;ea=;#s| zs&ryv)Y^F@4N5*nOw7zC-#^^l+}>`=R!O&8>SqjH%2G_iiFpt((;Q^7_$`UV$DWjg z#Q0mH;O5rWT?q+90LEY;`xDb<&V3ul!nJ2r+9OHV-ehon&!er1&web<{ zU0wHdbt%Y?xlZ|>VQ#MxCrXtg>>5UD-Fd6?0`Pj6~%vO4NoiRnF!Jp4^I7Gdwt(W9Vmm=L{ z%d6Qm^J#^IC~WJFG9UdMYf6*99UBu9kaBUl_@mUC)XK{0O?0$BslMx7ihO03&HXXk z^oj~HEiEmC@2{>{o$k5KndZZV1Y2bdjX*y%EaR3}*ZRM-gpxK-P0>h8OA9!!lI^cg zSo5qk1>hR-QAEbZ2EBfbmnh~%QBbq}szu;rf35kGT9&f5_A8_2z?rQ!n%GG;HnwK? zSdMp=3JYbcQ}s0Fy~)y+mX^i)2nlU%in@z)kMRn7v{+8PsO@ACx624+eSLx?MJ&YQ zq9>P*cbEK|nj}4se#IV6`xC}<6r`_NcWwXbij0qc1zqslQ3(0w=ZoJ;tGx8|rq%@E z5;^s2f;&4OtN6;syshCk@rar z3`ty=;IJjZqfl?K_!z=`ir|T}8Y}NWi5-Zw;ryh1mlm{%B|MUe-Y46W-G5 zwO#eH(X!G0E9Ju0C3ns;6%yXW#RUgZySFd9l?6%1R<)E^4%qGfR(bpOEv=ZCz7WUT zl$40CU!`*OYbo5^+_JN?8&dBDAsRl1-tHE*v$4tF)gPGB@b~veLHzvrv)==LkO+Ir zI`J3t$1n7BbVSzSt$T;tTd%EfrlzJsb5}U8X=i1Yx0#!poj=Xjt$eY)?eI1>Ha#s3 z)xDPbK}ONUvo@{LvS+0kS+*|J)YJ&tBnqtWpTuwX_xIb)w-cW(Yt}EThrj#sJF4f` z!oqBOB*XWWJv$edpoj>!(Vq%-SyHbjZ1h;L*E%s{eNlJ3t&q_W0 z@dX9W15@!womVxVh=2fDG_z7`mD7r{o?aMCl$x#9>w50ou9~-W=3t$Xc5>o>_3G6Z zrxlH*$`*<+Oo_Qz#_vDse*Acxt5Z(E&(F`o!qQOoZ0u=##!Vj|A9k%G^j`4`5g5cM zeBO~sVqT-4m)5p^zQ@48FdEL)dR*=co5Z3^we-gM+aXg`99?!zmj(W7v#%-wTOER2RbilZVMXovb0hd-pD^ zwQ>(0NIrOggP>()#nCBy+Ss2V-Z`?qKb-Kl$P%Ky>;kHwiXj%Js^5LQD*RNk`VS&9Dh!?pnBP(mt zmnKan=2@{TU18o!jqEyudT-d5B#T4kpFSJO*Nfvd#hIO*{h*OUOhpxjhDGq0KTlMw zI@5V$5}$^K29HYUDvbXKk!|d{vwa;)SC6sqTUO7;tmKuZ)N~;I@5(Q@6qw)=`(U2M3C0LJw;Rs+O9Fbq-eyE?8f@crhQ|cauYJ^X~q@ z&u3ZH`$6HlazoTMI@@yr>ho6}o5jzilU$6vU{yTAL2TuK+)4eb7SrJ{?K?O2pYZC9;l<>oFgF>z$lm*1C(iGN-S z<@}cikykz!+@7tTz~Cl75>YQAj8>V32iXN>`QqD?uQa)$he$ZI2Q${McGP*_a=k)3;L zOWV+tPr|r95N*EV2x$A^@WI?GR=C7|u9c3Ry*qQK``fqH%IAwug?eomeXDHwzNc)W zy+lnmVVf4Le7vqsz|6y=;@*=cKmXCuWqE6)jSCHN^#QG6@Ev1=P+z7dwS_11c%8N* zvtO&mSn9OVw&tEANIWUfoPw)s8YwA#1{fVwmx){s@t=BTe&R-99N87v96UI*vGv_s@sw zPewWt!`kMeA?`> zIpDZ48uv=f#6=q_Pb%uWvC*BRXI(i%^T~&yqaJ8yrcbn1|mWDDw5{1S0B!!?U?$N;y9&*7Vo}Bf@GbJpPS7pL0o2x6Y8cx)m9}X860yGqs zUdf7!$;YYq^fvfHjjuItol9@&;YY_uhU3fU$Y;jYJ4wp%mj-$7T+e|w?4c4D_9*eN zy~SbCy%x7MDe+QaGv+3_VAYpPb#X_Fe#%v>AC$ET+l-~Rk(44 zG`DUemgG5g>aBcKJ+rc=Ek@?2&Fs6gG42;sz!um;_(fo1HB*)T$y@COUr}7-`#v~6 zl9Mf780eTYz>yx`XSu5Psj*Ug3zgOCXU4qbd}99B`5t1|-x(nj;T67jIkTRwE-qMYo~#VxXP|C%Rqvf-Kf=3o5+ zrkY)RnKLgIYn8{Hg3Wlbv9CJD*i)bWF?80qA!h4YxzDuBdPL-a zs%X>wqEL}`zcknkgVf@5E)1i54tfv!0Vzi2(~uYD2AYFchq|bOo@l6z`_AU@$L+eK z*PLqCwTa=zCFN^%iS7w$>|AV#wV@SLG9uKv0O1*>1zv}+Iuuna* z2a(U9`&1HaytM**HO_p;pT{`J(&=1j5ZA8_GpVm)bcxdUmyQh{b=+_imr@*>KHRXm z=Mr?VDHJW=5m4b(gUW+@(m|Cm0(2?OS@ihC&h?~vX2aUHN!dI~nBb>GqqLq$eP@m& z5%1@SaeH@sxIU}coUF_CKEaZvid5g8c0>vjI7QYC`kK_&1$^HUbDe%~SUI=L3e)<@ zwG$xC z#pe2is0i4V2d((m$1D8-m3eM9V)YBKY2-FE6N-GoT*(v(1;;HKXM>R5L~F>dbdNgEl_eg6EJ+oToG z^0Ay;aL>Cr7I!l%ditoLw>Q6x(^F4Mac@d;a&o{1 z@a+l&U~5oK>8GP$_{%>=mzqYt?xj49(6~6VhY7dynghPpVk~qdQc_X+S$#mJ@^ClDHx1d{m;iL07yb0Nm6^e z9HL>Rpgvru+=fn6l!}x~|LgA30FU$P*n?v315>rKM{1VZ;(}R=(Pl^&&p8k}Bt5hKn_6eeI`T5R{cwQ_jK9$Jfx)qcDue zLCoaWt2rgH6sFyM@q|ow+|BbBO9fMKI}?RR?yIkapG+$fb$?{I4ULSLoE`54zkdA^ z#;u_tEdW0g9z`oF)>Fm5lrHr z-M&Gd-0qLC>&{I$x4*fZlh<^`a>>F4sj8`^4lLQtwc>{kgd@H{6DEp!kYr?JkO|n) zYUDnq!&hUu>Uy$PuA-~^IyaZyGFgF2%#&=&a|ge(vol^{D%qqhd}g*KG&?uQ9UK*5T;P#zsV18a<`3GoHu6`dYWFap@Ryr~ORtQQYPV_ilCX zF#-3}`*|AW#|0x-q@>E8T%PSRn7CS)H)7Hlh@Cs7y?jv?)3R~yo=H_cE@2iDg+q6LnI>pjl+ z2i@Z0=2mvk)5tO6Ci|#XhDAvI^>Ax$W^obAz`y_yw?x5+j^mH1;oUVJmv8@-j@>^< z-QSoph<9%AMbY3$Pp7bYeRv{&XXg5PNRZEjXxE2)6HurUp6{s}kM6Uuyv0!`<#V(c z{r(+*JC1I(bDmn)x87b^V`F-a0{t*pebm*}r@yD(Ll{OAoFwp0nY;h$yoLnmu*zJ! zb`5BfGHVPrj@7CI&z(D(@vWz0MR`d+%!J3hXtQO~cbCjs(*5N~V2K{&INm*ISQWiD zeSNYptK;zG#01tM*Yl%AXw6HA?@NvXUdJVm21W)48!Y&m+S;&^lat#!IvQKUt_vql zQ2-%{ewTRd$ zeSBP3x55qu@do4|Q2tEzSAX(mAtkmpZ=bAiWKUT&4Ijh}4-FYLzQ9n<8LGHAKe4|! zJ1~I-?zZBDAcxbwJ^YtbRG^NHDxqYsCF@Akzw!G_xB`*}|Nd=JbF`3-y{m~=jv?Q5}6TZE*yZaUBV4-mf4$SW1<(h?Xh0*wPkYyg%xbjST zpFF$4#H1~{VZ*$l*CaK#GJaU2UL$_26X{f>yUrr2x_&2S_It6Wv|dbV*G^S+aYQC? zYL@ld1O1t~IR>$d)8{!0BSYZ|f2btImJ}2exyjxj5z^ndA%)Z;KacN!9q5vJqNy@) zY&<>ZE$8v;Hfz!0#}DDzoq27AQ{yjKzf-NVj_I8}U0+TA^i4!yl7uSZaeD32ooAyj zL46R}{eDlQcR(M|Q~Nsg(K9kW;^f2GfQ0N3^05?O!)*SUP*PioprC-${ ziedtFIaCR*u6&aN6T4S^U`PfnM!$O($RHa&tyzEkD9gc-8DLA1a7F^ETDf$pzPZ#W zTRC0T0db9J3gUe0gnjVp9aTOcFprJgW1~ClZ*#-Bq5@dIEx5N-6@%>EoZ%lY4 z{i^VbBom^@Twd{;jU5VFuCqRv40aU{)&&Td7awAX89cv2Soed5M+u`$97T|Cl2=Nq zh(e@`X4zw0%T7l{@4IiK(qZwm&?V#mj~p6ZzVUVVKtPz`FSHq;E(J3J6i_LtC(N)a z%ztsc;1s+LM;+vjNF5JdC$9~@6Kp+;ndo_PwO!bN(FJeW4Eee@$1)y`PlygrMiaRC z1upiImp0~Sb_^zc>q=ZsBl~m!n?~N--n73vPLrk_rR87j(;g|TSl%h9<`-IxySdqg zHvOw@{YoM^aAiUEdXHM76D#z(iz#E>vyYG01t!v}K2S3cn;T7EY&CyC_W{Ir2RZ$M zfbjW8isLrE=MZG6c+BBKnZQeq9)7lPTjZq5xXHF@KK!0@1KbXQ?cgh-m*EGEvDUWm zS$Ee3Za-g-sAM^>!&EDmX&MSOXsbmT;UyLn!{A;j#YV^5lkqBjF5+|0x@cNaQ$SRB zy}9qssQkLX6XsRSs9-tFy+<-nl5!gw$h`q(3j?J?dJM_>On+xJEcdVh>r6TC&7jOJu zgbG#8J-R!j_yqEm;X+P~(aQ=h%I|f8+Rk_MUH5;bAOHSiZ1BO1balKZkngSf zx@MPEi}%#Ti)8zoCf&JG-zNDqojj(4?x{j-aH67$4FB;&R+Q;aO+u1p=0UWB*Gmjt z+Z}~)qey*3iR;QgWRlGyp)_iC0LP&u98toUDhY>d3ra`=+#pNib;AWc&FnAJrJbrd z6$BPRKUgd(8Ho4?zJG5>^B_IX{GY-5FC+QCKNw`o$jZ8xs{8>Ez1o1enVE6Z%S+r8 zVQZYthTM*~&9a4@X`A`q`D6VLgU!jSeod9$VS}>CrHPj$!&Gt>IGU08!c)(?)ZVWqWRd!yW?Z`T!VV*$jC_8&9L$CzQ*%g=UN$fq$KgL07aFK%_i;W z>}=}wIe)%7T8ax=C=vtUa@Ek{YyJypL^Ockz_DO|xM}3M({qOf{EP-aG~{+<`Qtyp zVQHN6Oj7`~Inwiyk-=0<5ew7QcWW_D^g7v}fn}A2gQMk(QS;{ET!j2aOiT=t1(0-= zFg@1+G!+3fDy^iXM9Tv~%fW#^<#QowGhX2*AIo{)O(|LA5`u+`D@ZX54S^JDy^eS9 z0<)?+-Ihm^x}J9ur9?GURil2l+vNWL z&)O*G7pn5w#}w&jT$VmQ*x;ff2S)h6G9&{2Uo|Au7GYNI@eX7vH20;;s;H{I06}@l z@rk#$81S<~_dTomU%yg8`wt?ZLN%P&QSJ#~0Bq`Buwi~tF9LI z^z{6oe%l*=@NeL1Ub2gv95$0;Vle*o+W_0sv$L_s%57rzAky@59A4Q?tju|=z22w--5BlcKn+V_RY?h}#i!fjaOQ(o=y?OJ-SMd3Qqs2K8 zDQRd&Fs_KMUk`QLS-6|3+|bg3fq3)wExLcBFSt}lt({QpkoNYo(ZQwtAN0>XX6NRJ zVUoi-g-6aS)p`9NL|PSPve=xkv#YDGz(D+A9CzwZX@#;f>k-a}?|Cuo?d@R=2o4W# z1yeIOewaFiia(1;Btl})gb|!#umlJ^gt!46Sr6w%dT*@W?;jZ8G3zD+&&$=_y^|_S z)?s(8JK~Pn|6~Ew2w<4fCv^1mv;^RiBKRhgOW@8y#n4$$mkMuww2qLP7g=6j{$kjO zYEi0PQBh$Cj@yqar<|v5-ANiHUp;N}7*>{!K0$xe7rloz(yeuWv`!Y4e>D?ET9>!> z+kl~?|0ccj8+}ih50_AU4f4-#*;aQyTjzx`ae5Wztz}bsW;+-0hCxBX_u12p-1BUdk@M&)3_JH6U zBr7!Ubm1PxeJQ>iYH2IoMHP}r1Y$Tns-18is?5DP9=UJt9}H@09f;_sg(HIrsGH4^ zm*adWNSXYA9RI?XQVfCXbFUqBKy&C_q5bHugOTs0&1!zbK@~~TRwho1@RUy--9ou9 z&0nYm#YbV1t3}=d_>rc+aXh2i@WgE_M)K15Y1+d~srg*Es%*`HiBGadGET+JIG3Uu z_83H39+tHLBB~t?>+OO$vY{)5{o&9G|Fgr&6FKQ`uaKuNUHQbw{a$-LUt%e(fl$`% z)%&Ml6b8HJ6(y9iRIA{Y^h>|#ptU<2xO@^wpVf-|wBfMy4CSh_30o&=XQ~H2-^Xqe z3koA~PATW9APv*K6VaK;!`E4H9k&nP($O!+SiPbkBF^zk9Y%L4#YITO8bma84F$)K zYEl%GH5ooKVk*K!Qli~-n(%k@YcAzm8yA!}U9LK)iqt;*3!MJ`6dN|MjvzPCt95GL=?WN4+vqAPZ3nAeyj#7Mk@?gxaeC z@p}4$8}@&bzc%&%w*S9{RLNiaKYv1UA}Qe9KD~Eb2I1hxf6UC3%o>;hCLJg2k`IA^ zgN?SI#pWsy2>72o0e66;U-^{x^_G^F_Rh|zg`a~E$=K?-GxZ@iH}~i6e9aGrYs7sK z-U8aMlzg0sxpd=SfMkNasGipQN=j{UJSIpI`{fHaq5k@XncCOwYjt7Ur@kx z`SN9;^^j@Ei~sYMRIYeUya29kw>Da;sF3ovJ~Be2P!8F`3fa0|g-<#zi(H)Uw0C!- zBOsOlp$PC!t*xvK`6z&AqA4jUfhTG>*BUlK{@$Gk##34~5_hO&KD-Or5a^1u^mO~_ z29%u4uvf2|-f`%Baa>Xb#S!b$rAu+Q%oXo2XC}WORV5}q`yG^?A$KzI?DRxjwv#F# z@#>$h+<#jx{?oSm9}n-W{ZvFRZT%l4>F#7YgfhEKiEA0R8^-F-tqBq*hB``x>Cd6qk3NmQh2OJ z?0>iFQ+W8W#GHUWXa{mmjwigZ-c=S5Yc*1zq>FC;-^@0Zrta=Kf{ryfJnU?B+}-^U zwj30h^uh^KGQ7ZVtv8nY61~J%tWMg27zn-jGt`7BiCvj4PyzvuN(N=Z*0b01PomRK zz6oz2{b|S%{T?gl0=j$?f556Vj?eNkY>h}zOG87Lr-3`2RsZ{c19#U;;Ns%)n17=@ zJUpbOrA6du8T#S{Dv!;$0Ez@3A0IZ|OUMDdl9Q7|emv-J2ID>#XR{fx`bBXU zputI5T7H6Cx+edQoftGMW01`HJ-}ipaXp*~%Ih3|w?Aq^E#|VW3+l9#w|5;GkMT>_ ztrk*_z=ScTmqd`+AOWOLB9x>EdcG{QzbZvm@!Cpv)l;r&j$tQ{l$Fz?9k`1CeIMC-J}deaK6O>#FPVsz$|%%Z5!oe(Ll` zI!%!5l#CP@Kvs;E^)gOClkwQ$YH_cWgoH0q+S#)-D@Xj=>r=YB$i6G^8y z`X$AL+xW5()YA9wUjop}149WBcK!L^h~-1lcndL!2?=bqBfED}rl$=N63)(LyZZ2> zrM2&$SVs~F1CL*iXrEN6S+5jj{JPU)6VaP@bI1Jo-{|aXHo~IB2gTv`gJ0-YH%YtMv5FG1fuA3VcDIIoQcK)8_> z7HWts_4V}$*iHLB8t8;Ym0rnuC4HpwM0PS}F6Av}|m+33qH;SAQ0pDoTr@ zlvAy271I|HYF46^WaZ}*;F7TWYUDtY5*H~31KsR=*XDW4OCC%Cs%XdX^o5OZ-SDzC z0bbdYTuLY5(svAtF7r=o{hCQ9{)repeG7uoyV{k?Zwnjis}qIA!lPw#?UZZ9%Xug7 zMSlny>P zzPCMb79BOWZNJk-6X@ed<49UK7xXCm*3z%=dA_RZoT~ZxCpVaxT~>G#{Zvz>;zpG5 zmTqAZ9x>DYxJ79YxsH<+0mWlQfP>`VwkSt z`q(4fB>Fns;(b}diGY#EXbk&IE;T%!C%9KeN@3&H9Jhwi_rX{4Chfy8Ec80A$(K!G z#&)qse!`@V*&MedQq@lda$^b@F}N*F(AUqzy`3LEcp@x<=WyBU z*yDq3bp5FUrbO(Nuab{5J|vC;Qojwh4odB3DWhVL=Gd>e3R-nh&;)WmOdEQUZ&3oS>cHndodJc(vbFPM<28DlzjJ0R zR%AIb5E-GD2g+o(C@_|{DlmkJFYfBY?UoC4Ke;&9ZPxdx4#%! z6cHlBx~u#q4hFZqmw;!p+sxHHPdFiyRea_U7uScvLyd*OneVsWv)9ZMc^~Fp)kopn z9IUu4+>`65V)%O%A*HmzrX)ar-K5WnHxi;zC9>rU1dRI5YHoqR0rfvt^DB=n7N#=BVIBmx-;;E~mX=!o$VXAtA z?Hf|0)k!tJZD~R8QQ=&Hj%@9q2&6QQO~-KE*7|xBk*~Gv16n-aemy_Sv2@7!n4mdO zkH;symb@gTSSr%;biIGz&N!OVsVO%uXGdn$2NcreDp$x; zWCMq_)G6+0%Afl@|m-;dL#g zP5TqIn}MRRx%A4qV$Za4TqT&2gzMvS#*1@>fC`^b5cUO8j8J*SSic@6xouwBlSomX zjFK6oKq>|$5c5MeZIk?vtDzRR3_EU_YyUN3Eu_jpaD@pu{Q9SQ{B2)inXOTyUNq`E zw9z}bBIOaIi(`4Qy0Z;ovaMo6kuQ7|JwZ>2`jlL|h=`pY>tzrR1?+8B$I6yVQ9*Q% z1d@#^?s^elLh8W6p?46fF%4#aLe1I;=A>j_3`J!+5wRc@RDWK)`S;F_i)4WV|UH#&o%Cq zb3}sINc5~)o7*r3T%^)ry@Aw$@rZY=TnE3Xm{wGX&lw{PLo)76acsy_(5JNLArA1# zR%RB=r^At;BZy1cm{}1WLdIjWBPz#kN7Y!dQyI^I5?dOpo(^O;h({^w=!}Wp9Ruoz z0sGqE&`_zscw&zs_YXmGXn+*X($5zHG_QSlu0nXy_&c7D>%sGAVb!cZaxQs`3mb|p zn%0{U_*zJlse=E^e(E%wR7aNE_$xNha#;FHKVhwFKT$dm9U@d(zdmZ#=(U*SLPSn} z38>KS+8F6A^Ka;oVri+~s0#&^0lByCbl)P8y$g6Pnn^(tibbH315g<h!N)0RXsXz^GnZxUF<@ezNgbT}NqYY4+#O|6aneki}M7s?Cx4FGVSeK8}tKCbwbA zBLjiKTHn1J^9l;uj`vnFdilAzi9nt#Bx43}+Z>4RUtaD~>@+;FGG62L>pz&7{l-6~ zy*&O(d#w(x#8djxF24YY7#A@c%2fviMi5+L45twXv^oo%1JxI)+dxDD$$22>Bw2Gf z8`{6Cou}am6)uw4bdVuM1d-zaXo<_9#u^WOe$?+6A$FV{cgHpvKpqJM%#ES=0M*yR z!s5$M^92j52g?E6TH@zO;wckG!3Ze>dWgjo6{$j+`~kMngwV>mQ~ts`DsI=n`3jqMeKbXo;7SsYFoL z)bEkvwf`P$E@)2V1)ww-A3{k*Qr&N7secr3w9F)FnV0D=y4UJ!$10T9LXCpiiUa6D zvy&bh*T5&6-RTv#bs?A1YZ>SoWIQ`L_$%QAbwz=YcAohfa)o5>Wl)fOL32}+va&Mm z*~Q;gX^@49PcTsYL+sK>LB+$zkI`RTSdhf_D>P}7Oz)FO?=w6Nh5 z$!)_1#EMw3zGTi2ysXh5t6WfDXC=3KL=a)AcY9(#zV5b8r2`{afKbE4{cMykXHjWT z3mVe&U+t0ZB;gTbS0n`yVrG^-mhAc4j1Qs@zcv~YbZCgbDWbRxkRCx1TKxW~yfwL7 z*<3QC>=&E6Fzde%5$(kVrwPX~>*LXynyeIWih(R8S!d_l(3YYJ94XoSaAlT582IfV z(MK}Kg0?razD@uEewLVb2}3yrb+49}t*&0XW(1j*#}#&T2+$4xqwwO#GdKSiFSxCT z*>m-(k+Cu`Ny-Ev7lA;Q8~kS)NQc@3totxD+`6`qz4B+g;{R4s@lU2n-VRVTWF^DD zk{F(Ee?<;t6*EcBO2+ z_ZhcQ6ME<^ZYcT!3xo}PPC}@Y3!?ERL+a4LX<6CWsu>B18?x|JnBP;Nt7_^6an@58 zi&3KX*7evPDgLSYBKvS@>E^x8e0gXXaC1LSVSBs~o?5nZFdbZ;dgDDe%^U*_oRj2f?fn5 zkP&-@6hWYJnRlDtp!R2uScBM9Sx;UAd`MVxy7PahW<=TeYYxwN|Z*h zy9=FGhQG;_uz7t#(YnZn2p&DRU0}+%eU-FJ?sIyN*(KBEqE)qP$nXzY^)dB$y@1@h zKy7>nE#$}Bsr-Yr8)5338bur$ulkJp+d9wF9q7hDM46vNm%goapzFz%1FlOiLaQ(P zH9z`er+*9{!l1uJ{b#BAlbV^C=K9zWcY4TfETb&vygqEp(K=jR6rYC8*P)FrO>s7o zGt$2caQ#3+u@NuginlO=IGWEvmL3iXveIKc(zI;Q^!Yw}9H}~f5=TSrF8DSpCd6F; z0vCcG5^u!_99fZkKu0E+nwX9|sX~IE`qnS0mVf57Xo$QvqVnD(A!~e>q}Bb3B+Yi? zctl{~^kqR}YIp_jVEkse=?Lv>)LR!K*z3#5d(#MddL6hPCpLf^vlnFe&}7WRQ-R!D zwj%V)wT~S?jeUAC&b^k$GM||D^~hx#;xAG+Aih%++AzcV(36ppRGg)O@Kc6ETVzsQ z3CdKR57xAwxJp6O31Pbprr3H=|8@67Pmb$iM%37^my+~k&NsDgeyjTw;6cNP$&4;> zZJr4R3bL5CD5tQ#0xM=z2pG{pRho|4ps!j&airI0)aJ`4NSN8&lfax1?0!YR_Tdw( z5iyR&k+IUvP5YLwdo$SNL&wjJLfYN7ZwExh&;X;|CZuJLDJzOT# zj$3xKL?mYEsh?XZH|0pj7L7s-GiLz<(8GR;C4ZQ zVM4Ro?lkGpH;IYtE_i7g9J&?AVohi@2MYEo-setEEgRkk!T|I5caB#Ix~Tlxm%jY& zT!k`c>8DR~p`tln5YnIH#KDOKKI{ztmsZ5T7g{ezLR}oP-gt0i#Kr13F_H3gmbBit z^@LqOSIFXBq1XyNaD?iA1MOC;=%eU}EZOuz>|T(k9I z!$;Qja`_y|i)?+p5+~**gv^^l$QU6`RSK8{52WS0u$&`(HCX7iA6@`nGlp{5$7N5+ z38+OZ>_2LPFa$^hvfkvbvmwlzS>k7xAQDWnBkr_(HQ8%l>tTu*6%zV^69dXD=WCQQdGNI_IO0<1|i7=^~Vn%5W>!@4FD{IL9Cfgj}ViDDsn#E zROM;X`a=u?DxsHvu22wVwo^7d$gIn3{rO709RzD$1_sXNl}|*kWm+i99=#?T@=@O{Twh_&Ds8#faf7MRF`ZfOr2uF zHq-9`wgbug+>Y^guuB_4nDcOK>U=m?6oF(Fo*>f80c?kM`B(!Nj6irEFJ&Pm=a2gy z9v*YiN@9)BO!iO}XV!(RR2`VCddgN^nxdn#5+6L@m^OBQe<>G%Ko>;*UI2eUkrJQO z>4k-_gI9noIS(dg_&9?M?7n)1iU7eG8Lv1TsXsU6iMYn5A(5xiJTXB9u3m-v9xLKQ zNy$}YZNc+iQ7kB-1#6@`Mcg1hAD*7_KH-4=CxDV;Brgdi<+9O;)6CZm0ay!>e*9Zz z-4XzmiVvWM`h>vLM&5dj$7BDeIqZ@lptk>US}1weNmK$26j_0|nCw9SS!b|3n_pny z#)lyTLz%UpC+_FxTGK}n(zt&2hgy0=z(j|?(<3&KB!-?I6*-2`2t^PG0T@`Ss;W>P zftKEfO@|H%2X;=9eha>SYq&N|pd#j%igoS}|e*>U>YHn^fy~$La zSH=hw#d6e{>t}|B$|t;!>D<3ydYUJyaO?K7-iiOv(kC=H>6i6I`qzwPBB;aeOnF}M zIT@Sch7yd^^MiVQJRC3wbNC)6IK1i)&C40Ok2KG@hF%&@j_(V_cgcv9a2vtsWfdjmisn#HLo4^8Xj z69~LmN?g$&Q&Ulp3j+|b59+L2-|rC`!S5?5`o-g--FJDXwlq99Ymu3L3=HS{5R!uW zT@Dw#`0|*9eqKFIw-cuiq5VAzi$L_Us_Qr JU()c!{{bo<10eta literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg-members.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg-members.html new file mode 100644 index 0000000..afb81a6 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg-members.html @@ -0,0 +1,27 @@ + + +libhpsangoma: Member List + + + + + + +

sangoma_hptdm_span_reg Member List

This is the complete list of members for sangoma_hptdm_span_reg, including all inherited members.

+ + + +
logsangoma_hptdm_span_reg
psangoma_hptdm_span_reg
rx_eventsangoma_hptdm_span_reg


Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg.html b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg.html new file mode 100644 index 0000000..6649464 --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/structsangoma__hptdm__span__reg.html @@ -0,0 +1,93 @@ + + +libhpsangoma: sangoma_hptdm_span_reg Struct Reference + + + + + + +

sangoma_hptdm_span_reg Struct Reference

Span registration structure. +More... +

+#include <libhpsangoma.h> +

+List of all members. + + + + + + + + +

Public Attributes

void * p
void(* log )(int level, FILE *fp, char *file, const char *func, int line, char *fmt,...)
int(* rx_event )(void *p, hp_tdmapi_rx_event_t *data)
+


Detailed Description

+Span registration structure. +

+ +

+Definition at line 72 of file libhpsangoma.h.


Member Data Documentation

+ +
+
+ + + + +
void(* sangoma_hptdm_span_reg::log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt,...)
+
+
+ +

+callback function to implement library logging +

+

+ +

+
+ + + + +
void* sangoma_hptdm_span_reg::p
+
+
+ +

+pointer to user object used with callback functions +

+Definition at line 75 of file libhpsangoma.h. +

+

+ +

+
+ + + + +
int(* sangoma_hptdm_span_reg::rx_event)(void *p, hp_tdmapi_rx_event_t *data)
+
+
+ +

+callback function to span global events for all channels in a span +

+

+


The documentation for this struct was generated from the following file: +
Generated on Sun Aug 17 23:56:55 2008 for libhpsangoma by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/docs/doxygen/html/tab_b.gif b/api/libsangoma/docs/doxygen/html/tab_b.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d623483ffdf5f9f96900108042a7ab0643fe2a3 GIT binary patch literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/tab_l.gif b/api/libsangoma/docs/doxygen/html/tab_l.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b1e6337c9299a700401a2a78a2c6ffced475216 GIT binary patch literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/tab_r.gif b/api/libsangoma/docs/doxygen/html/tab_r.gif new file mode 100644 index 0000000000000000000000000000000000000000..ce9dd9f533cb5486d6941844f442b59d4a9e9175 GIT binary patch literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo literal 0 HcmV?d00001 diff --git a/api/libsangoma/docs/doxygen/html/tabs.css b/api/libsangoma/docs/doxygen/html/tabs.css new file mode 100644 index 0000000..a61552a --- /dev/null +++ b/api/libsangoma/docs/doxygen/html/tabs.css @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/api/libsangoma/doxygen.config b/api/libsangoma/doxygen.config new file mode 100644 index 0000000..de802b0 --- /dev/null +++ b/api/libsangoma/doxygen.config @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libhpsangoma + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = libhpsangoma.c libhpsangoma_priv.c libhpsangoma.h libhpsangoma_priv.h + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/api/libsangoma/examples/.svn/all-wcprops b/api/libsangoma/examples/.svn/all-wcprops index c22dd3c..f9fa9b2 100644 --- a/api/libsangoma/examples/.svn/all-wcprops +++ b/api/libsangoma/examples/.svn/all-wcprops @@ -1,35 +1,5 @@ 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 +V 42 +/svn/libsangoma/!svn/ver/22/trunk/examples END diff --git a/api/libsangoma/examples/.svn/entries b/api/libsangoma/examples/.svn/entries index 2c2c8b6..3568358 100644 --- a/api/libsangoma/examples/.svn/entries +++ b/api/libsangoma/examples/.svn/entries @@ -1,15 +1,15 @@ 8 dir -11 +22 https://www.sangomapbx.com/svn/libsangoma/trunk/examples https://www.sangomapbx.com/svn/libsangoma -2008-02-28T18:51:53.196120Z -1 -root +2008-09-17T21:25:40.156211Z +22 +ncorbic svn:special svn:externals svn:needs-lock @@ -26,64 +26,9 @@ svn:special svn:externals svn:needs-lock 8fe45b59-3c47-0410-bdf9-e5d932a076a6 -sound.raw -file - - - - -2008-05-22T23:06:17.000000Z -da36acc78b83d5047481df0cca63d969 -2008-02-28T18:51:53.196120Z -1 -root -has-props +priserver +dir -priserver.c -file - - - - -2008-05-22T23:06:17.000000Z -9f83030c20158d91b7ec6bb7a9392dcb -2008-02-28T18:51:53.196120Z -1 -root - -librc -file - - - - -2008-05-22T23:06:17.000000Z -5c222b74d68b1c7df3f937a9d6321d40 -2008-02-28T18:51:53.196120Z -1 -root - -Makefile -file - - - - -2008-05-22T23:06:17.000000Z -b58ee42eeb2d5e921bdab940a9fda738 -2008-02-28T18:51:53.196120Z -1 -root - -README -file - - - - -2008-05-22T23:06:17.000000Z -40538792592cd766e4941d9b37dbaf56 -2008-02-28T18:51:53.196120Z -1 -root +hptdm_api +dir diff --git a/api/libsangoma/examples/hptdm_api/.svn/all-wcprops b/api/libsangoma/examples/hptdm_api/.svn/all-wcprops new file mode 100644 index 0000000..0abceab --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/libsangoma/!svn/ver/22/trunk/examples/hptdm_api +END +rebuild.sh +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/rebuild.sh +END +doxygen.config +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/doxygen.config +END +aft_tdm_hp.c +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/libsangoma/!svn/ver/22/trunk/examples/hptdm_api/aft_tdm_hp.c +END +aft_tdm_hp.h +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/aft_tdm_hp.h +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/libsangoma/!svn/ver/22/trunk/examples/hptdm_api/Makefile +END diff --git a/api/libsangoma/examples/hptdm_api/.svn/entries b/api/libsangoma/examples/hptdm_api/.svn/entries new file mode 100644 index 0000000..e10f5d0 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/entries @@ -0,0 +1,92 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples/hptdm_api +https://www.sangomapbx.com/svn/libsangoma + + + +2008-09-17T21:25:40.156211Z +22 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +rebuild.sh +file + + + + +2008-08-18T04:42:48.000000Z +81a3f7cc906c1a95c63c8bbb05655f30 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +doxygen.config +file + + + + +2008-08-18T04:42:48.000000Z +f71df7ce5278594373b87a592d826719 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +aft_tdm_hp.c +file + + + + +2008-09-17T20:41:56.000000Z +b8ef9830437ad25ebd95d62434ed9530 +2008-09-17T21:25:40.156211Z +22 +ncorbic + +docs +dir + +aft_tdm_hp.h +file + + + + +2008-08-18T04:42:48.000000Z +7f0a6424997adf454bbb3c88fb608622 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +Makefile +file + + + + +2008-09-11T18:33:30.000000Z +1432ab687de350b6a988bdbc553bdbe7 +2008-09-17T21:25:40.156211Z +22 +ncorbic + diff --git a/api/libsangoma/examples/hptdm_api/.svn/format b/api/libsangoma/examples/hptdm_api/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/hptdm_api/.svn/prop-base/rebuild.sh.svn-base b/api/libsangoma/examples/hptdm_api/.svn/prop-base/rebuild.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/prop-base/rebuild.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/api/libsangoma/examples/hptdm_api/.svn/text-base/Makefile.svn-base b/api/libsangoma/examples/hptdm_api/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..dc80a0f --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/text-base/Makefile.svn-base @@ -0,0 +1,34 @@ +# ============================================================================ +# 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 + +# Tools options. +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib +CFLAGS += -I/usr/include/wanpipe -I/usr/include -I../../patches/kdrivers/include/ + +TARGETS = aft_tdm_hp + +####### RULES ################################################################ + +all: $(TARGETS) + @echo "Ok." + +install: + for x in $(TARGETS); do \ + install -D -m 755 $$x /usr/bin/$$x; \ + done; + + +aft_tdm_hp: aft_tdm_hp.c + $(CC) $(CFLAGS) -o $@ $^ -lpthread -lsangoma -lm + +clean: + rm -f $(TARGETS) diff --git a/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.c.svn-base b/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.c.svn-base new file mode 100644 index 0000000..fb7b67a --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.c.svn-base @@ -0,0 +1,484 @@ +/***************************************************************************** +* aft_tdm_hp.c: Example code for HP TDM API Library +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 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. +* ============================================================================ +* Description: +* +*/ + +#include "aft_tdm_hp.h" + + +/* + * Global flags used by this program + */ +static int system_flag=0; +static int system_threads=0; +static int system_debug=10; + +/* + * Global defines for our program. Create an array of spans and chans. + */ +span_idx_t span_list[MAX_SPANS]; +chan_idx_t chan_list[MAX_SPANS][MAX_CHANS]; + +/*------------------------------------------ + Utilites + *-----------------------------------------*/ + +/* + * Utility used to print packets + */ +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ | "); + for (x=0;x system_debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) smg_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 + if (fp) { + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); + } +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + +void sig_end(int sigid) +{ + printf("%d: Got Signal %i\n",getpid(),sigid); + aft_clear_flag(system_flag,SYSTEM_RUNNING); +} + + + +/* + * Main pthread thread used to implement a span->run_span() thread. + * All this thread does is call span->run_span() method. + * span->run-span method is defined in libsangoma library and it + * implements rx/tx/oob on span hw interface. + */ +static void *hp_tdmapi_span_run(void *obj) +{ + span_idx_t *span_idx = (span_idx_t*)obj; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + span_idx->init = 1; + + log_printf(0,NULL,"Starting span %i!\n",span->span_no+1); + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + log_printf(0,NULL,"Span %i run_span exited err=%i!\n",span->span_no+1,err); + usleep(5000); + continue; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + span_idx->init = 0; + + /* Arbitrary delay - implementation specific */ + sleep(3); + log_printf(0,NULL,"Stopping span %i!\n",span->span_no+1); + + pthread_exit(NULL); +} + +/* + * Span Thrad Launcher. + * Spawn a span thread, give the thread span object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_span_thread(pthread_t *threadid, void *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(threadid, &attr, hp_tdmapi_span_run, span); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +/* + * Channel callback function. When channel has a chunk of data + * ready for us, this function will be called to deliver the + * rx chunk. The user should implement the logic here of + * what to do with that rx chunk. + * + * If we return 0 - channel will continue to operate normally. + * If we return -1 - channel will get closed and we will not + * receive any more data on this channel until + * channel is opened again. + */ + +static int media_rx_ready(void *p, char *data, int len) +{ + chan_idx_t *chan_idx = (chan_idx_t *)p; + + if (!chan_idx->init) { + return -1; + } + + log_printf(15,NULL,"Chan s%ic%i Rx Data Len %i \n", + chan_idx->span_no+1,chan_idx->chan_no+1,len); + +#if 0 + print_packet((unsigned char*)data,len); +#endif + + /* FIXME: ADD CODE HERE + Do something with rx chunk of data for this channel + */ + + + /* If we return -1 here the library will close the channel */ + + return 0; +} + + +/* + * Main pthread thread used to implement a channel thread. + * Since this is a channel TX thread, user would wait on + * some UDP socket for data to be transmitted to this channel. + * + * The channel thread opens the channel on a span using + * the library span->open_chan method. Once the channel + * object is obtained, this thread can start pushing + * arbitrary data chunks into the channel. + * + */ +static void *hp_tdmapi_chan_run(void *obj) +{ + chan_idx_t *chan_idx = (chan_idx_t*)obj; + int err; + char data[1024]; + int len=160; /* 20ms worth of ulaw/alaw */ + + sangoma_hptdm_span_t *span; + sangoma_hptdm_chan_reg_t channel_reg; + + /* Grab a span based on the span_no - integer starting from 0 */ + span_idx_t *span_idx = &span_list[chan_idx->span_no]; + span = span_idx->span; + + log_printf(0,NULL,"Starting chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + + /* Configure channel registration structure */ + memset(&channel_reg,0,sizeof(channel_reg)); + channel_reg.p = (void*)chan_idx; + channel_reg.rx_data = media_rx_ready; + + /* Set the local channel index to configured */ + chan_idx->init = 1; + + /* Open a channel based on chan_no integer starting from 0, on a specific span */ + err = span->open_chan(span, &channel_reg, chan_idx->chan_no, &chan_idx->chan); + if (err){ + log_printf(0,NULL,"Error openeing chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + pthread_exit(NULL); + } + + + memset(data,0,sizeof(data)); + + + while (aft_test_flag(system_flag,SYSTEM_RUNNING)) { + + /* FIXME: Wait for AUDIO from a UDP socket here + once you receive data to tx to a channel + use the push() funciton to pass the chunk + into the channel. The size can be of any length + up to the MAX CHUNK SIZE */ + + /* In this example we dont have a socket to wait on + so we just use a delay */ + usleep(1000); + + err=chan_idx->chan->push(chan_idx->chan, + data,len); + /* + -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok + */ + switch (err) { + case 0: + /* Data tx ok */ + break; + case -1: + /* packet too large */ + break; + case -2: + /* channel closed */ + break; + case 1: + /* failed to tx, channel busy - try again later - in 20ms or so */ + break; + } + } + + /* Once we are done, close the channel */ + span->close_chan(chan_idx->chan); + + /* Set the local channel index to free */ + chan_idx->init = 0; + + pthread_exit(NULL); +} + +/* + * Channel Thrad Launcher. + * Spawn a channel thread, give the thread chan object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_chan_thread(pthread_t *threadid, void *chan) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 1; + 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(threadid, &attr, hp_tdmapi_chan_run, chan); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(result)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +int hptdm_rx_event(void *p, hp_tdmapi_rx_event_t *event) +{ + span_idx_t *span_idx = (span_idx_t*)p; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + if (!span || !span_idx->init) { + log_printf(0,NULL,"%s: Error Span %i not configured\n",span->span_no); + return -1; + } +#if 0 + switch (event->event_type) { + + case WP_API_EVENT_NONE: + + case WP_API_EVENT_DTMF: + + case WP_API_EVENT_RM_DTMF: + + case WP_API_EVENT_RXHOOK: + + case WP_API_EVENT_RING: + + case WP_API_EVENT_TONE: + + case WP_API_EVENT_RING_DETECT: + + case WP_API_EVENT_ONHOOKTRANSFER: + + case WP_API_EVENT_SETPOLARITY: + + case WP_API_EVENT_BRI_CHAN_LOOPBACK: + + } +#endif + +} + + + +/* + * Start all spans and channels. + * + * This exmaple codes automatically starts all spans and channels together. + * The real world application would start all spans on startup. + * Jowever the channels would only get started once the signalling stack indicates + * a call on that specific channel. + * + * This implementation should be user specific. + */ +int smg_init_spans(void) +{ + int span,i; + int err=-1; + sangoma_hptdm_span_reg_t lib_callback; + lib_callback.log=__log_printf; + + for (span=0;span<1;span++) { + span_list[span].span_no=span; + + lib_callback.rx_event = hptdm_rx_event; + lib_callback.p = (void*)&span_list[span]; + + span_list[span].span = sangoma_hptdm_api_span_init(span, &lib_callback); + if (!span_list[span].span) { + log_printf(0, NULL, "Error: Failed to initialize span %i\n", + span+1); + break; + } else { + log_printf(0, NULL, "HP TDM API Span: %d configured...\n", + span+1); + + err=launch_hptdm_api_span_thread(&span_list[span].thread,&span_list[span]); + if (err) { + return err; + } + + for (i=0;i<31;i++) { + chan_list[span][i].chan_no=i; + chan_list[span][i].span_no=span; + + err=launch_hptdm_api_chan_thread(&chan_list[span][i].thread, + &chan_list[span][i]); + if (err) { + return err; + } + } + } + } + + return err; +} + +/* + * Applicatoin Main Function + * + * This implementation should be user specific! + * + * Configure and initialize application + * Set a global sytem flag indicating that app is running. + * + * Start all SPANS by calling span init function and + * launching a thread per span. In span thread calling run_span(). + * + * Start all channels by launching a thread per channel and + * calling span->chan_open. Every 20ms send chunk down each channel. + * + * This implementation should be user specific! + */ + +int main(int argc, char* argv[]) +{ + int err=0; + + nice(-10); + + signal(SIGINT,&sig_end); + signal(SIGTERM,&sig_end); + + aft_set_flag(system_flag,SYSTEM_RUNNING); + + log_printf(0, NULL, "HP TDM API MAIN Process Starting\n"); + + err=smg_init_spans(); + if (err) { + aft_clear_flag(system_flag,SYSTEM_RUNNING); + } + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + sleep(1); + } + + sleep(5); + log_printf(0, NULL, "HP TDM API MAIN Process Exiting\n"); + + return 0; +}; diff --git a/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.h.svn-base b/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.h.svn-base new file mode 100644 index 0000000..cbfc908 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/text-base/aft_tdm_hp.h.svn-base @@ -0,0 +1,127 @@ +/***************************************************************************** +* aft_tdm_hp.c: Example code for HP TDM API Library +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 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. +* ============================================================================ +* Description: +* +*/ + +#ifndef __AFT_TDM_HP_H_ +#define __AFT_TDM_HP_H_ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! Define maximum spans and chans */ +#define MAX_SPANS 16 +#define MAX_CHANS 31 + +/*! Use the syslog in debug output */ +#define USE_SYSLOG 1 + +/*! Set the pthread stack to something normal */ +#define MGD_STACK_SIZE 1024 * 240 + +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__) + +/*! + * Indicates that sytem is running. If not set stop program. + * Set the pthread stack to something normal */ +enum { + SYSTEM_RUNNING=1, +}; + +/*! + * Span index structure. Defines the program span structure along with + * supporting variables needed to operate span + */ +typedef struct span_idx +{ + /*! init flag used to determine if span is being used*/ + int init; + /*! span number - integer starting from 0 */ + int span_no; + /*! pthread id - because each span will have its own thread */ + pthread_t thread; + /*! span object - returned by sangoma_hptdm_api_span_init() function */ + sangoma_hptdm_span_t *span; + + /* Other private span variables insert here */ +} span_idx_t; + + +/*! + * Channel index structure. Defines the program channel structure along with + * supporting variables needed to operate a chan. + */ +typedef struct chan_idx +{ + /*! init flag used to determine if span is being used*/ + int init; + /*! channel number - integer starting from 0 */ + int chan_no; + /*! span number - owner of the current channel - integer starting from 0 */ + int span_no; + /*! pthread id for this channel, because every channel will have its own thread */ + pthread_t thread; + + /*! channel object obtaind by span->open_chan() method */ + sangoma_hptdm_chan_t *chan; + + /* Other private channel variables insert here */ +} chan_idx_t; + + +/*! Miscallaneous bit utilities - + * not thread safe should use pthread lock arount bit set/clear operations + */ + +#define aft_test_flag(p,flag) ({ \ + (p & (flag)); \ + }) + +#define aft_set_flag(p,flag) do { \ + (p |= (flag)); \ + } while (0) + +#define aft_clear_flag(p,flag) do { \ + (p &= ~(flag)); \ + } while (0) + + +#endif + + diff --git a/api/libsangoma/examples/hptdm_api/.svn/text-base/doxygen.config.svn-base b/api/libsangoma/examples/hptdm_api/.svn/text-base/doxygen.config.svn-base new file mode 100644 index 0000000..0ec845b --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/text-base/doxygen.config.svn-base @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = hptdm_api + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = aft_tdm_hp.c aft_tdm_hp.h + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/api/libsangoma/examples/hptdm_api/.svn/text-base/rebuild.sh.svn-base b/api/libsangoma/examples/hptdm_api/.svn/text-base/rebuild.sh.svn-base new file mode 100644 index 0000000..397ff99 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/.svn/text-base/rebuild.sh.svn-base @@ -0,0 +1,13 @@ +#!/bin/sh + +home=$(pwd) + +cd ../libsangoma +make +make install + +cd $home +make clean +make + + diff --git a/api/libsangoma/examples/hptdm_api/Makefile b/api/libsangoma/examples/hptdm_api/Makefile new file mode 100644 index 0000000..dc80a0f --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/Makefile @@ -0,0 +1,34 @@ +# ============================================================================ +# 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 + +# Tools options. +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib +CFLAGS += -I/usr/include/wanpipe -I/usr/include -I../../patches/kdrivers/include/ + +TARGETS = aft_tdm_hp + +####### RULES ################################################################ + +all: $(TARGETS) + @echo "Ok." + +install: + for x in $(TARGETS); do \ + install -D -m 755 $$x /usr/bin/$$x; \ + done; + + +aft_tdm_hp: aft_tdm_hp.c + $(CC) $(CFLAGS) -o $@ $^ -lpthread -lsangoma -lm + +clean: + rm -f $(TARGETS) diff --git a/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c new file mode 100644 index 0000000..fb7b67a --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c @@ -0,0 +1,484 @@ +/***************************************************************************** +* aft_tdm_hp.c: Example code for HP TDM API Library +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 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. +* ============================================================================ +* Description: +* +*/ + +#include "aft_tdm_hp.h" + + +/* + * Global flags used by this program + */ +static int system_flag=0; +static int system_threads=0; +static int system_debug=10; + +/* + * Global defines for our program. Create an array of spans and chans. + */ +span_idx_t span_list[MAX_SPANS]; +chan_idx_t chan_list[MAX_SPANS][MAX_CHANS]; + +/*------------------------------------------ + Utilites + *-----------------------------------------*/ + +/* + * Utility used to print packets + */ +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ | "); + for (x=0;x system_debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) smg_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 + if (fp) { + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); + } +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + +void sig_end(int sigid) +{ + printf("%d: Got Signal %i\n",getpid(),sigid); + aft_clear_flag(system_flag,SYSTEM_RUNNING); +} + + + +/* + * Main pthread thread used to implement a span->run_span() thread. + * All this thread does is call span->run_span() method. + * span->run-span method is defined in libsangoma library and it + * implements rx/tx/oob on span hw interface. + */ +static void *hp_tdmapi_span_run(void *obj) +{ + span_idx_t *span_idx = (span_idx_t*)obj; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + span_idx->init = 1; + + log_printf(0,NULL,"Starting span %i!\n",span->span_no+1); + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + log_printf(0,NULL,"Span %i run_span exited err=%i!\n",span->span_no+1,err); + usleep(5000); + continue; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + span_idx->init = 0; + + /* Arbitrary delay - implementation specific */ + sleep(3); + log_printf(0,NULL,"Stopping span %i!\n",span->span_no+1); + + pthread_exit(NULL); +} + +/* + * Span Thrad Launcher. + * Spawn a span thread, give the thread span object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_span_thread(pthread_t *threadid, void *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(threadid, &attr, hp_tdmapi_span_run, span); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +/* + * Channel callback function. When channel has a chunk of data + * ready for us, this function will be called to deliver the + * rx chunk. The user should implement the logic here of + * what to do with that rx chunk. + * + * If we return 0 - channel will continue to operate normally. + * If we return -1 - channel will get closed and we will not + * receive any more data on this channel until + * channel is opened again. + */ + +static int media_rx_ready(void *p, char *data, int len) +{ + chan_idx_t *chan_idx = (chan_idx_t *)p; + + if (!chan_idx->init) { + return -1; + } + + log_printf(15,NULL,"Chan s%ic%i Rx Data Len %i \n", + chan_idx->span_no+1,chan_idx->chan_no+1,len); + +#if 0 + print_packet((unsigned char*)data,len); +#endif + + /* FIXME: ADD CODE HERE + Do something with rx chunk of data for this channel + */ + + + /* If we return -1 here the library will close the channel */ + + return 0; +} + + +/* + * Main pthread thread used to implement a channel thread. + * Since this is a channel TX thread, user would wait on + * some UDP socket for data to be transmitted to this channel. + * + * The channel thread opens the channel on a span using + * the library span->open_chan method. Once the channel + * object is obtained, this thread can start pushing + * arbitrary data chunks into the channel. + * + */ +static void *hp_tdmapi_chan_run(void *obj) +{ + chan_idx_t *chan_idx = (chan_idx_t*)obj; + int err; + char data[1024]; + int len=160; /* 20ms worth of ulaw/alaw */ + + sangoma_hptdm_span_t *span; + sangoma_hptdm_chan_reg_t channel_reg; + + /* Grab a span based on the span_no - integer starting from 0 */ + span_idx_t *span_idx = &span_list[chan_idx->span_no]; + span = span_idx->span; + + log_printf(0,NULL,"Starting chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + + /* Configure channel registration structure */ + memset(&channel_reg,0,sizeof(channel_reg)); + channel_reg.p = (void*)chan_idx; + channel_reg.rx_data = media_rx_ready; + + /* Set the local channel index to configured */ + chan_idx->init = 1; + + /* Open a channel based on chan_no integer starting from 0, on a specific span */ + err = span->open_chan(span, &channel_reg, chan_idx->chan_no, &chan_idx->chan); + if (err){ + log_printf(0,NULL,"Error openeing chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + pthread_exit(NULL); + } + + + memset(data,0,sizeof(data)); + + + while (aft_test_flag(system_flag,SYSTEM_RUNNING)) { + + /* FIXME: Wait for AUDIO from a UDP socket here + once you receive data to tx to a channel + use the push() funciton to pass the chunk + into the channel. The size can be of any length + up to the MAX CHUNK SIZE */ + + /* In this example we dont have a socket to wait on + so we just use a delay */ + usleep(1000); + + err=chan_idx->chan->push(chan_idx->chan, + data,len); + /* + -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok + */ + switch (err) { + case 0: + /* Data tx ok */ + break; + case -1: + /* packet too large */ + break; + case -2: + /* channel closed */ + break; + case 1: + /* failed to tx, channel busy - try again later - in 20ms or so */ + break; + } + } + + /* Once we are done, close the channel */ + span->close_chan(chan_idx->chan); + + /* Set the local channel index to free */ + chan_idx->init = 0; + + pthread_exit(NULL); +} + +/* + * Channel Thrad Launcher. + * Spawn a channel thread, give the thread chan object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_chan_thread(pthread_t *threadid, void *chan) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 1; + 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(threadid, &attr, hp_tdmapi_chan_run, chan); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(result)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +int hptdm_rx_event(void *p, hp_tdmapi_rx_event_t *event) +{ + span_idx_t *span_idx = (span_idx_t*)p; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + if (!span || !span_idx->init) { + log_printf(0,NULL,"%s: Error Span %i not configured\n",span->span_no); + return -1; + } +#if 0 + switch (event->event_type) { + + case WP_API_EVENT_NONE: + + case WP_API_EVENT_DTMF: + + case WP_API_EVENT_RM_DTMF: + + case WP_API_EVENT_RXHOOK: + + case WP_API_EVENT_RING: + + case WP_API_EVENT_TONE: + + case WP_API_EVENT_RING_DETECT: + + case WP_API_EVENT_ONHOOKTRANSFER: + + case WP_API_EVENT_SETPOLARITY: + + case WP_API_EVENT_BRI_CHAN_LOOPBACK: + + } +#endif + +} + + + +/* + * Start all spans and channels. + * + * This exmaple codes automatically starts all spans and channels together. + * The real world application would start all spans on startup. + * Jowever the channels would only get started once the signalling stack indicates + * a call on that specific channel. + * + * This implementation should be user specific. + */ +int smg_init_spans(void) +{ + int span,i; + int err=-1; + sangoma_hptdm_span_reg_t lib_callback; + lib_callback.log=__log_printf; + + for (span=0;span<1;span++) { + span_list[span].span_no=span; + + lib_callback.rx_event = hptdm_rx_event; + lib_callback.p = (void*)&span_list[span]; + + span_list[span].span = sangoma_hptdm_api_span_init(span, &lib_callback); + if (!span_list[span].span) { + log_printf(0, NULL, "Error: Failed to initialize span %i\n", + span+1); + break; + } else { + log_printf(0, NULL, "HP TDM API Span: %d configured...\n", + span+1); + + err=launch_hptdm_api_span_thread(&span_list[span].thread,&span_list[span]); + if (err) { + return err; + } + + for (i=0;i<31;i++) { + chan_list[span][i].chan_no=i; + chan_list[span][i].span_no=span; + + err=launch_hptdm_api_chan_thread(&chan_list[span][i].thread, + &chan_list[span][i]); + if (err) { + return err; + } + } + } + } + + return err; +} + +/* + * Applicatoin Main Function + * + * This implementation should be user specific! + * + * Configure and initialize application + * Set a global sytem flag indicating that app is running. + * + * Start all SPANS by calling span init function and + * launching a thread per span. In span thread calling run_span(). + * + * Start all channels by launching a thread per channel and + * calling span->chan_open. Every 20ms send chunk down each channel. + * + * This implementation should be user specific! + */ + +int main(int argc, char* argv[]) +{ + int err=0; + + nice(-10); + + signal(SIGINT,&sig_end); + signal(SIGTERM,&sig_end); + + aft_set_flag(system_flag,SYSTEM_RUNNING); + + log_printf(0, NULL, "HP TDM API MAIN Process Starting\n"); + + err=smg_init_spans(); + if (err) { + aft_clear_flag(system_flag,SYSTEM_RUNNING); + } + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + sleep(1); + } + + sleep(5); + log_printf(0, NULL, "HP TDM API MAIN Process Exiting\n"); + + return 0; +}; diff --git a/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c~ b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c~ new file mode 100644 index 0000000..a6c329d --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.c~ @@ -0,0 +1,468 @@ +/***************************************************************************** +* aft_tdm_hp.c: Example code for HP TDM API Library +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 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. +* ============================================================================ +* Description: +* +*/ + +#include "aft_tdm_hp.h" + + +/* + * Global flags used by this program + */ +static int system_flag=0; +static int system_threads=0; +static int system_debug=10; + +/* + * Global defines for our program. Create an array of spans and chans. + */ +span_idx_t span_list[MAX_SPANS]; +chan_idx_t chan_list[MAX_SPANS][MAX_CHANS]; + +/*------------------------------------------ + Utilites + *-----------------------------------------*/ + +/* + * Utility used to print packets + */ +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ | "); + for (x=0;x system_debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) smg_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 + if (fp) { + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); + } +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + +void sig_end(int sigid) +{ + printf("%d: Got Signal %i\n",getpid(),sigid); + aft_clear_flag(system_flag,SYSTEM_RUNNING); +} + + + +/* + * Main pthread thread used to implement a span->run_span() thread. + * All this thread does is call span->run_span() method. + * span->run-span method is defined in libsangoma library and it + * implements rx/tx/oob on span hw interface. + */ +static void *hp_tdmapi_span_run(void *obj) +{ + span_idx_t *span_idx = (span_idx_t*)obj; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + span_idx->init = 1; + + log_printf(0,NULL,"Starting span %i!\n",span->span_no+1); + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + log_printf(0,NULL,"Span %i run_span exited err=%i!\n",span->span_no+1,err); + usleep(5000); + continue; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + span_idx->init = 0; + + /* Arbitrary delay - implementation specific */ + sleep(3); + log_printf(0,NULL,"Stopping span %i!\n",span->span_no+1); + + pthread_exit(NULL); +} + +/* + * Span Thrad Launcher. + * Spawn a span thread, give the thread span object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_span_thread(pthread_t *threadid, void *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(threadid, &attr, hp_tdmapi_span_run, span); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +/* + * Channel callback function. When channel has a chunk of data + * ready for us, this function will be called to deliver the + * rx chunk. The user should implement the logic here of + * what to do with that rx chunk. + * + * If we return 0 - channel will continue to operate normally. + * If we return -1 - channel will get closed and we will not + * receive any more data on this channel until + * channel is opened again. + */ + +static int media_rx_ready(void *p, char *data, int len) +{ + chan_idx_t *chan_idx = (chan_idx_t *)p; + + if (!chan_idx->init) { + return -1; + } + + log_printf(15,NULL,"Chan s%ic%i Rx Data Len %i \n", + chan_idx->span_no+1,chan_idx->chan_no+1,len); + +#if 0 + print_packet((unsigned char*)data,len); +#endif + + /* FIXME: ADD CODE HERE + Do something with rx chunk of data for this channel + */ + + + /* If we return -1 here the library will close the channel */ + + return 0; +} + + +/* + * Main pthread thread used to implement a channel thread. + * Since this is a channel TX thread, user would wait on + * some UDP socket for data to be transmitted to this channel. + * + * The channel thread opens the channel on a span using + * the library span->open_chan method. Once the channel + * object is obtained, this thread can start pushing + * arbitrary data chunks into the channel. + * + */ +static void *hp_tdmapi_chan_run(void *obj) +{ + chan_idx_t *chan_idx = (chan_idx_t*)obj; + int err; + char data[1024]; + int len=160; /* 20ms worth of ulaw/alaw */ + + sangoma_hptdm_span_t *span; + sangoma_hptdm_chan_reg_t channel_reg; + + /* Grab a span based on the span_no - integer starting from 0 */ + span_idx_t *span_idx = &span_list[chan_idx->span_no]; + span = span_idx->span; + + log_printf(0,NULL,"Starting chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + + /* Configure channel registration structure */ + memset(&channel_reg,0,sizeof(channel_reg)); + channel_reg.p = (void*)chan_idx; + channel_reg.rx_data = media_rx_ready; + + /* Set the local channel index to configured */ + chan_idx->init = 1; + + /* Open a channel based on chan_no integer starting from 0, on a specific span */ + err = span->open_chan(span, &channel_reg, chan_idx->chan_no, &chan_idx->chan); + if (err){ + log_printf(0,NULL,"Error openeing chan s%ic%i ...\n", + chan_idx->span_no+1,chan_idx->chan_no+1); + pthread_exit(NULL); + } + + + memset(data,0,sizeof(data)); + + + while (aft_test_flag(system_flag,SYSTEM_RUNNING)) { + + /* FIXME: Wait for AUDIO from a UDP socket here + once you receive data to tx to a channel + use the push() funciton to pass the chunk + into the channel. The size can be of any length + up to the MAX CHUNK SIZE */ + + /* In this example we dont have a socket to wait on + so we just use a delay */ + usleep(1000); + + err=chan_idx->chan->push(chan_idx->chan, + data,len); + /* + -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok + */ + switch (err) { + case 0: + /* Data tx ok */ + break; + case -1: + /* packet too large */ + break; + case -2: + /* channel closed */ + break; + case 1: + /* failed to tx, channel busy - try again later - in 20ms or so */ + break; + } + } + + /* Once we are done, close the channel */ + span->close_chan(chan_idx->chan); + + /* Set the local channel index to free */ + chan_idx->init = 0; + + pthread_exit(NULL); +} + +/* + * Channel Thrad Launcher. + * Spawn a channel thread, give the thread chan object poiner. + * This implementation should be user specific. + */ +static int launch_hptdm_api_chan_thread(pthread_t *threadid, void *chan) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 1; + 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(threadid, &attr, hp_tdmapi_chan_run, chan); + if (result) { + log_printf(0, NULL, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(result)); + } + pthread_attr_destroy(&attr); + + return result; +} + + +int hptdm_rx_event(void *p, hp_tdmapi_rx_event_t *event); +{ + span_idx_t *span_idx = (span_idx_t*)obj; + int err; + sangoma_hptdm_span_t *span = span_idx->span; + + if (!span || !span_idx->init) { + log_printf(0,NULL,"%s: Error Span %i not configured\n",span->span_no); + return -1; + } + + switch (event->event_type) { + + case : + + + } + + + +} + + + +/* + * Start all spans and channels. + * + * This exmaple codes automatically starts all spans and channels together. + * The real world application would start all spans on startup. + * Jowever the channels would only get started once the signalling stack indicates + * a call on that specific channel. + * + * This implementation should be user specific. + */ +int smg_init_spans(void) +{ + int span,i; + int err=-1; + sangoma_hptdm_span_reg_t lib_callback; + lib_callback.log=__log_printf; + + for (span=0;span<1;span++) { + span_list[span].span_no=span; + + lib_callback.rx_event = hptdm_rx_event; + lib_callback.p = (void*)&span_list[span]; + + span_list[span].span = sangoma_hptdm_api_span_init(span, &lib_callback); + if (!span_list[span].span) { + log_printf(0, NULL, "Error: Failed to initialize span %i\n", + span+1); + break; + } else { + log_printf(0, NULL, "HP TDM API Span: %d configured...\n", + span+1); + + err=launch_hptdm_api_span_thread(&span_list[span].thread,&span_list[span]); + if (err) { + return err; + } + + for (i=0;i<31;i++) { + chan_list[span][i].chan_no=i; + chan_list[span][i].span_no=span; + + err=launch_hptdm_api_chan_thread(&chan_list[span][i].thread, + &chan_list[span][i]); + if (err) { + return err; + } + } + } + } + + return err; +} + +/* + * Applicatoin Main Function + * + * This implementation should be user specific! + * + * Configure and initialize application + * Set a global sytem flag indicating that app is running. + * + * Start all SPANS by calling span init function and + * launching a thread per span. In span thread calling run_span(). + * + * Start all channels by launching a thread per channel and + * calling span->chan_open. Every 20ms send chunk down each channel. + * + * This implementation should be user specific! + */ + +int main(int argc, char* argv[]) +{ + int err=0; + + nice(-10); + + signal(SIGINT,&sig_end); + signal(SIGTERM,&sig_end); + + aft_set_flag(system_flag,SYSTEM_RUNNING); + + log_printf(0, NULL, "HP TDM API MAIN Process Starting\n"); + + err=smg_init_spans(); + if (err) { + aft_clear_flag(system_flag,SYSTEM_RUNNING); + } + + while(aft_test_flag(system_flag,SYSTEM_RUNNING)){ + sleep(1); + } + + sleep(5); + log_printf(0, NULL, "HP TDM API MAIN Process Exiting\n"); + + return 0; +}; diff --git a/api/libsangoma/examples/hptdm_api/aft_tdm_hp.h b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.h new file mode 100644 index 0000000..cbfc908 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/aft_tdm_hp.h @@ -0,0 +1,127 @@ +/***************************************************************************** +* aft_tdm_hp.c: Example code for HP TDM API Library +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 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. +* ============================================================================ +* Description: +* +*/ + +#ifndef __AFT_TDM_HP_H_ +#define __AFT_TDM_HP_H_ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! Define maximum spans and chans */ +#define MAX_SPANS 16 +#define MAX_CHANS 31 + +/*! Use the syslog in debug output */ +#define USE_SYSLOG 1 + +/*! Set the pthread stack to something normal */ +#define MGD_STACK_SIZE 1024 * 240 + +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__) + +/*! + * Indicates that sytem is running. If not set stop program. + * Set the pthread stack to something normal */ +enum { + SYSTEM_RUNNING=1, +}; + +/*! + * Span index structure. Defines the program span structure along with + * supporting variables needed to operate span + */ +typedef struct span_idx +{ + /*! init flag used to determine if span is being used*/ + int init; + /*! span number - integer starting from 0 */ + int span_no; + /*! pthread id - because each span will have its own thread */ + pthread_t thread; + /*! span object - returned by sangoma_hptdm_api_span_init() function */ + sangoma_hptdm_span_t *span; + + /* Other private span variables insert here */ +} span_idx_t; + + +/*! + * Channel index structure. Defines the program channel structure along with + * supporting variables needed to operate a chan. + */ +typedef struct chan_idx +{ + /*! init flag used to determine if span is being used*/ + int init; + /*! channel number - integer starting from 0 */ + int chan_no; + /*! span number - owner of the current channel - integer starting from 0 */ + int span_no; + /*! pthread id for this channel, because every channel will have its own thread */ + pthread_t thread; + + /*! channel object obtaind by span->open_chan() method */ + sangoma_hptdm_chan_t *chan; + + /* Other private channel variables insert here */ +} chan_idx_t; + + +/*! Miscallaneous bit utilities - + * not thread safe should use pthread lock arount bit set/clear operations + */ + +#define aft_test_flag(p,flag) ({ \ + (p & (flag)); \ + }) + +#define aft_set_flag(p,flag) do { \ + (p |= (flag)); \ + } while (0) + +#define aft_clear_flag(p,flag) do { \ + (p &= ~(flag)); \ + } while (0) + + +#endif + + diff --git a/api/libsangoma/examples/hptdm_api/docs/.svn/all-wcprops b/api/libsangoma/examples/hptdm_api/docs/.svn/all-wcprops new file mode 100644 index 0000000..dc25aae --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs +END diff --git a/api/libsangoma/examples/hptdm_api/docs/.svn/entries b/api/libsangoma/examples/hptdm_api/docs/.svn/entries new file mode 100644 index 0000000..502c690 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/.svn/entries @@ -0,0 +1,31 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples/hptdm_api/docs +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:26:05.260169Z +17 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +doxygen +dir + diff --git a/api/libsangoma/examples/hptdm_api/docs/.svn/format b/api/libsangoma/examples/hptdm_api/docs/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/all-wcprops b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/all-wcprops new file mode 100644 index 0000000..e02195c --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/entries b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/entries new file mode 100644 index 0000000..cacf58e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/entries @@ -0,0 +1,31 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples/hptdm_api/docs/doxygen +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:26:05.260169Z +17 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +html +dir + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/format b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/all-wcprops b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/all-wcprops new file mode 100644 index 0000000..19f66e9 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/all-wcprops @@ -0,0 +1,125 @@ +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html +END +tabs.css +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/tabs.css +END +annotated.html +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/annotated.html +END +graph_legend.html +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/graph_legend.html +END +structchan__idx.html +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/structchan__idx.html +END +tab_l.gif +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/tab_l.gif +END +tab_r.gif +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/tab_r.gif +END +aft__tdm__hp_8c-source.html +K 25 +svn:wc:ra_dav:version-url +V 98 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8c-source.html +END +doxygen.png +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/doxygen.png +END +graph_legend.png +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/graph_legend.png +END +aft__tdm__hp_8h-source.html +K 25 +svn:wc:ra_dav:version-url +V 98 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8h-source.html +END +doxygen.css +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/doxygen.css +END +graph_legend.dot +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/graph_legend.dot +END +structspan__idx-members.html +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/structspan__idx-members.html +END +files.html +K 25 +svn:wc:ra_dav:version-url +V 81 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/files.html +END +functions_vars.html +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/functions_vars.html +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 81 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/index.html +END +tab_b.gif +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/tab_b.gif +END +functions.html +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/functions.html +END +structspan__idx.html +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/structspan__idx.html +END +structchan__idx-members.html +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/libsangoma/!svn/ver/17/trunk/examples/hptdm_api/docs/doxygen/html/structchan__idx-members.html +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/entries b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/entries new file mode 100644 index 0000000..df80d1d --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/entries @@ -0,0 +1,273 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples/hptdm_api/docs/doxygen/html +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:26:05.260169Z +17 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +annotated.html +file + + + + +2008-08-18T04:42:48.000000Z +1e50523ff3a711b2d7d95974554f1ecd +2008-08-18T04:26:05.260169Z +17 +ncorbic + +tabs.css +file + + + + +2008-08-18T04:42:48.000000Z +86ffb0e311553e43db9ee79414d0ba6c +2008-08-18T04:26:05.260169Z +17 +ncorbic + +graph_legend.html +file + + + + +2008-08-18T04:42:48.000000Z +2f5aa2da23541993ace6b48930b740a7 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +structchan__idx.html +file + + + + +2008-08-18T04:42:48.000000Z +c408f39de9c8e6002df87c25e076f4fa +2008-08-18T04:26:05.260169Z +17 +ncorbic + +tab_l.gif +file + + + + +2008-08-18T04:42:48.000000Z +749f90bcfb2030b4f2c0d274ac3b60ff +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +tab_r.gif +file + + + + +2008-08-18T04:42:48.000000Z +9802233fa0b185ac2242b8dce096cb90 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +aft__tdm__hp_8c-source.html +file + + + + +2008-08-18T04:42:48.000000Z +0a875f06d9ce74db6a0ae344bc476344 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +doxygen.png +file + + + + +2008-08-18T04:42:48.000000Z +33f874b8cd0ceafd80ccad649e6e7846 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +graph_legend.png +file + + + + +2008-08-18T04:42:48.000000Z +e1e4f6546f531182df5312912df3fc06 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +aft__tdm__hp_8h-source.html +file + + + + +2008-08-18T04:42:48.000000Z +71f3426e1da4f3bfcb7eb6ad09d0d339 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +structspan__idx-members.html +file + + + + +2008-08-18T04:42:48.000000Z +68dc267b12ce601f4dff5898aab4fcb5 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +graph_legend.dot +file + + + + +2008-08-18T04:42:48.000000Z +2555cc3d29aaacbea4f702c94774d76b +2008-08-18T04:26:05.260169Z +17 +ncorbic + +doxygen.css +file + + + + +2008-08-18T04:42:48.000000Z +702b19635b285e21fa5697bc643b2ba6 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +files.html +file + + + + +2008-08-18T04:42:48.000000Z +e5660d8451c63106c96d45076cf1069e +2008-08-18T04:26:05.260169Z +17 +ncorbic + +functions_vars.html +file + + + + +2008-08-18T04:42:48.000000Z +7b47a6793c91bb106a8c48d1032ca9f1 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +index.html +file + + + + +2008-08-18T04:42:48.000000Z +6b431a46c8963244e2d82b0ddf7f4c80 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +tab_b.gif +file + + + + +2008-08-18T04:42:48.000000Z +a22ef28753006f7a725a9099ade93548 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +functions.html +file + + + + +2008-08-18T04:42:48.000000Z +98d485b06579e1bc01ebc9cdcf99d723 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +structspan__idx.html +file + + + + +2008-08-18T04:42:48.000000Z +fed4ce1507eaa7a9414cc7d8df0620cc +2008-08-18T04:26:05.260169Z +17 +ncorbic + +structchan__idx-members.html +file + + + + +2008-08-18T04:42:48.000000Z +4c30cc2d5c8427e2deb3f6c232145a08 +2008-08-18T04:26:05.260169Z +17 +ncorbic + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/format b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/doxygen.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/graph_legend.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_b.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_l.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/prop-base/tab_r.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8c-source.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8c-source.html.svn-base new file mode 100644 index 0000000..d5a31c0 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8c-source.html.svn-base @@ -0,0 +1,457 @@ + + +hptdm_api: aft_tdm_hp.c Source File + + + + + +

aft_tdm_hp.c

00001 /*****************************************************************************
+00002 * aft_tdm_hp.c: Example code for HP TDM API Library
+00003 *
+00004 * Author(s):    Nenad Corbic <ncorbic@sangoma.com>
+00005 *
+00006 * Copyright:    (c) 2008 Sangoma Technologies Inc.
+00007 *
+00008 *               This program is free software; you can redistribute it and/or
+00009 *               modify it under the terms of the GNU General Public License
+00010 *               as published by the Free Software Foundation; either version
+00011 *               2 of the License, or (at your option) any later version.
+00012 * ============================================================================
+00013 * Description:
+00014 *
+00015 */
+00016 
+00017 #include "aft_tdm_hp.h"
+00018 
+00019 
+00020 /*
+00021  * Global flags used by this program
+00022  */
+00023 static int system_flag=0;
+00024 static int system_threads=0;
+00025 static int system_debug=10;
+00026 
+00027 /*
+00028  * Global defines for our program.  Create an array of spans and chans.
+00029  */
+00030 span_idx_t span_list[MAX_SPANS];
+00031 chan_idx_t chan_list[MAX_SPANS][MAX_CHANS];
+00032 
+00033 /*------------------------------------------
+00034   Utilites
+00035  *-----------------------------------------*/
+00036 
+00037 /*
+00038  * Utility used to print packets
+00039  */
+00040 void print_packet(unsigned char *buf, int len)
+00041 {
+00042         int x;
+00043         printf("{  | ");
+00044         for (x=0;x<len;x++){
+00045                 if (x && x%24 == 0){
+00046                         printf("\n  ");
+00047                 }
+00048                 if (x && x%8 == 0)
+00049                         printf(" | ");
+00050                 printf("%02x ",buf[x]);
+00051         }
+00052         printf("}\n");
+00053 }
+00054 
+00055 
+00056 /*
+00057  * Utility used to implement print to syslog
+00058  */
+00059 void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)
+00060 {
+00061     char *data;
+00062     int ret = 0;
+00063     va_list ap;
+00064 
+00065     if (socket < 0) {
+00066                 return;
+00067     }
+00068 
+00069     if (level && level > system_debug) {
+00070                 return;
+00071     }
+00072 
+00073     va_start(ap, fmt);
+00074 #ifdef SOLARIS
+00075     data = (char *) smg_malloc(2048);
+00076     vsnprintf(data, 2048, fmt, ap);
+00077 #else
+00078     ret = vasprintf(&data, fmt, ap);
+00079 #endif
+00080     va_end(ap);
+00081     if (ret == -1) {
+00082                 fprintf(stderr, "Memory Error\n");
+00083     } else {
+00084                 char date[80] = "";
+00085                 struct tm now;
+00086                 time_t epoch;
+00087 
+00088                 if (time(&epoch) && localtime_r(&epoch, &now)) {
+00089                         strftime(date, sizeof(date), "%Y-%m-%d %T", &now);
+00090                 }
+00091 
+00092 #ifdef USE_SYSLOG
+00093                 syslog(LOG_DEBUG | LOG_LOCAL2, data);
+00094 #else
+00095                 if (fp) {
+00096                 fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data);
+00097                 }
+00098 #endif
+00099                 free(data);
+00100     }
+00101 #ifndef USE_SYSLOG
+00102     fflush(fp);
+00103 #endif
+00104 }
+00105 
+00106 void sig_end(int sigid)
+00107 {
+00108         printf("%d: Got Signal %i\n",getpid(),sigid);
+00109         aft_clear_flag(system_flag,SYSTEM_RUNNING);
+00110 }
+00111 
+00112 
+00113 
+00114 /*
+00115  * Main pthread thread used to implement a span->run_span() thread.
+00116  * All this thread does is call span->run_span() method.
+00117  * span->run-span method is defined in libsangoma library and it
+00118  * implements rx/tx/oob on span hw interface.
+00119  */
+00120 static void *hp_tdmapi_span_run(void *obj)
+00121 {
+00122         span_idx_t *span_idx = (span_idx_t*)obj;
+00123         int err;
+00124         sangoma_hptdm_span_t *span = span_idx->span;
+00125 
+00126         span_idx->init = 1;
+00127 
+00128         log_printf(0,NULL,"Starting span %i!\n",span->span_no+1);
+00129 
+00130         while(aft_test_flag(system_flag,SYSTEM_RUNNING)){
+00131 
+00132                 if (!span->run_span) {
+00133                         break;
+00134                 }
+00135 
+00136                 err = span->run_span(span);
+00137                 if (err) {
+00138                         log_printf(0,NULL,"Span %i run_span exited err=%i!\n",span->span_no+1,err);
+00139                         usleep(5000);
+00140                         continue;
+00141                 }
+00142 
+00143         }
+00144 
+00145         if (span->close_span) {
+00146                 span->close_span(span);
+00147         }
+00148 
+00149         span_idx->init = 0;
+00150 
+00151         /* Arbitrary delay - implementation specific */
+00152         sleep(3);
+00153         log_printf(0,NULL,"Stopping span %i!\n",span->span_no+1);
+00154 
+00155         pthread_exit(NULL);
+00156 }
+00157 
+00158 /*
+00159  * Span Thrad Launcher.
+00160  * Spawn a span thread, give the thread span object poiner.
+00161  * This implementation should be user specific.
+00162  */
+00163 static int launch_hptdm_api_span_thread(pthread_t *threadid, void *span)
+00164 {
+00165         pthread_attr_t attr;
+00166         int result = 0;
+00167         struct sched_param param;
+00168 
+00169         param.sched_priority = 5;
+00170         result = pthread_attr_init(&attr);
+00171         pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+00172         pthread_attr_setschedpolicy(&attr, SCHED_RR);
+00173         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+00174         pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
+00175 
+00176         result = pthread_attr_setschedparam (&attr, &param);
+00177 
+00178         result = pthread_create(threadid, &attr, hp_tdmapi_span_run, span);
+00179         if (result) {
+00180                 log_printf(0, NULL, "%s: Error: Creating Thread! %s\n",
+00181                            __FUNCTION__,strerror(errno));
+00182         }
+00183         pthread_attr_destroy(&attr);
+00184 
+00185         return result;
+00186 }
+00187 
+00188 
+00189 /*
+00190  * Channel callback function. When channel has a chunk of data
+00191  * ready for us, this function will be called to deliver the
+00192  * rx chunk.  The user should implement the logic here of
+00193  * what to do with that rx chunk.
+00194  *
+00195  * If we return 0 - channel will continue to operate normally.
+00196  * If we return -1 - channel will get closed and we will not
+00197  *                  receive any more data on this channel until
+00198  *                  channel is opened again.
+00199  */
+00200 
+00201 static int media_rx_ready(void *p, char *data, int len)
+00202 {
+00203         chan_idx_t *chan_idx = (chan_idx_t *)p;
+00204 
+00205         if (!chan_idx->init) {
+00206                 return -1;
+00207         }
+00208 
+00209         log_printf(15,NULL,"Chan s%ic%i Rx Data Len %i \n",
+00210                                 chan_idx->span_no+1,chan_idx->chan_no+1,len);
+00211 
+00212 #if 0
+00213         print_packet((unsigned char*)data,len);
+00214 #endif
+00215 
+00216         /* FIXME: ADD CODE HERE
+00217         Do something with rx chunk of data for this channel
+00218         */
+00219 
+00220 
+00221         /* If we return -1 here the library will close the channel */
+00222 
+00223         return 0;
+00224 }
+00225 
+00226 
+00227 /*
+00228  * Main pthread thread used to implement a channel thread.
+00229  * Since this is a channel TX thread, user would wait on
+00230  * some UDP socket for data to be transmitted to this channel.
+00231  *
+00232  * The channel thread opens the channel on a span using
+00233  * the library span->open_chan method.  Once the channel
+00234  * object is obtained, this thread can start pushing
+00235  * arbitrary data chunks into the channel.
+00236  *
+00237  */
+00238 static void *hp_tdmapi_chan_run(void *obj)
+00239 {
+00240         chan_idx_t *chan_idx = (chan_idx_t*)obj;
+00241         int err;
+00242         char data[1024];
+00243         int len=160; /* 20ms worth of ulaw/alaw */
+00244 
+00245         sangoma_hptdm_span_t *span;
+00246         sangoma_hptdm_chan_reg_t channel_reg;
+00247 
+00248         /* Grab a span based on the span_no - integer starting from 0 */
+00249         span_idx_t *span_idx = &span_list[chan_idx->span_no];
+00250         span = span_idx->span;
+00251 
+00252         log_printf(0,NULL,"Starting chan s%ic%i ...\n",
+00253                                 chan_idx->span_no+1,chan_idx->chan_no+1);
+00254 
+00255         /* Configure channel registration structure */
+00256         memset(&channel_reg,0,sizeof(channel_reg));
+00257         channel_reg.p = (void*)chan_idx;
+00258         channel_reg.rx_data = media_rx_ready;
+00259 
+00260         /* Set the local channel index to configured */
+00261         chan_idx->init = 1;
+00262 
+00263         /* Open a channel based on chan_no integer starting from 0, on a specific span */
+00264         err = span->open_chan(span, &channel_reg, chan_idx->chan_no, &chan_idx->chan);
+00265         if (err){
+00266                 log_printf(0,NULL,"Error openeing chan s%ic%i ...\n",
+00267                                 chan_idx->span_no+1,chan_idx->chan_no+1);
+00268                 pthread_exit(NULL);
+00269         }
+00270 
+00271 
+00272         memset(data,0,sizeof(data));
+00273 
+00274 
+00275         while (aft_test_flag(system_flag,SYSTEM_RUNNING)) {
+00276 
+00277                 /* FIXME: Wait for AUDIO from a UDP socket here
+00278                           once you receive data to tx to a channel
+00279                           use the push() funciton to pass the chunk
+00280                           into the channel.  The size can be of any length
+00281                           up to the MAX CHUNK SIZE */
+00282 
+00283                 /* In this example we dont have a socket to wait on
+00284                    so we just use a delay */
+00285                 usleep(1000);
+00286 
+00287                 err=chan_idx->chan->push(chan_idx->chan,
+00288                                          data,len);
+00289                 /*
+00290                 -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok
+00291                 */
+00292                 switch (err) {
+00293                 case 0:
+00294                         /* Data tx ok */
+00295                         break;
+00296                 case -1:
+00297                         /* packet too large */
+00298                         break;
+00299                 case -2:
+00300                         /* channel closed */
+00301                         break;
+00302                 case 1:
+00303                         /* failed to tx, channel busy - try again later - in 20ms or so */
+00304                         break;
+00305                 }
+00306         }
+00307 
+00308         /* Once we are done, close the channel */
+00309         span->close_chan(chan_idx->chan);
+00310 
+00311         /* Set the local channel index to free */
+00312         chan_idx->init = 0;
+00313 
+00314         pthread_exit(NULL);
+00315 }
+00316 
+00317 /*
+00318  * Channel Thrad Launcher.
+00319  * Spawn a channel thread, give the thread chan object poiner.
+00320  * This implementation should be user specific.
+00321  */
+00322 static int launch_hptdm_api_chan_thread(pthread_t *threadid, void *chan)
+00323 {
+00324     pthread_attr_t attr;
+00325     int result = 0;
+00326     struct sched_param param;
+00327 
+00328     param.sched_priority = 1;
+00329     result = pthread_attr_init(&attr);
+00330     pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+00331     pthread_attr_setschedpolicy(&attr, SCHED_RR);
+00332     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+00333     pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
+00334 
+00335     result = pthread_attr_setschedparam (&attr, &param);
+00336 
+00337     result = pthread_create(threadid, &attr, hp_tdmapi_chan_run, chan);
+00338     if (result) {
+00339          log_printf(0, NULL, "%s: Error: Creating Thread! %s\n",
+00340                          __FUNCTION__,strerror(result));
+00341     }
+00342     pthread_attr_destroy(&attr);
+00343 
+00344     return result;
+00345 }
+00346 
+00347 /*
+00348  * Start all spans and channels.
+00349  *
+00350  * This exmaple codes automatically starts all spans and channels together.
+00351  * The real world application would start all spans on startup.
+00352  * Jowever the channels would only get started once the signalling stack indicates
+00353  * a call on that specific channel.
+00354  *
+00355  * This implementation should be user specific.
+00356  */
+00357 int smg_init_spans(void)
+00358 {
+00359         int span,i;
+00360         int err=-1;
+00361         sangoma_hptdm_span_reg_t lib_callback;
+00362         lib_callback.log=__log_printf;
+00363 
+00364         for (span=0;span<16;span++) {
+00365                 span_list[span].span_no=span;
+00366                 span_list[span].span = sangoma_hptdm_api_span_init(span, &lib_callback);
+00367                 if (!span_list[span].span) {
+00368                         log_printf(0, NULL, "Error: Failed to initialize span %i\n",
+00369                                         span+1);
+00370                         break;
+00371                 } else {
+00372                         log_printf(0, NULL, "HP TDM API Span: %d configured...\n",
+00373                                         span+1);
+00374 
+00375                         err=launch_hptdm_api_span_thread(&span_list[span].thread,&span_list[span]);
+00376                         if (err) {
+00377                                 return err;
+00378                         }
+00379 
+00380                         for (i=0;i<31;i++) {
+00381                                 chan_list[span][i].chan_no=i;
+00382                                 chan_list[span][i].span_no=span;
+00383 
+00384                                 err=launch_hptdm_api_chan_thread(&chan_list[span][i].thread,
+00385                                                                  &chan_list[span][i]);
+00386                                 if (err) {
+00387                                         return err;
+00388                                 }
+00389                         }
+00390                 }
+00391         }
+00392 
+00393         return err;
+00394 }
+00395 
+00396 /*
+00397  * Applicatoin Main Function
+00398  *
+00399  * This implementation should be user specific!
+00400  *
+00401  * Configure and initialize application
+00402  * Set a global sytem flag indicating that app is running.
+00403  *
+00404  * Start all SPANS by calling span init function and
+00405  * launching a thread per span. In span thread calling run_span().
+00406  *
+00407  * Start all channels by launching a thread per channel and
+00408  * calling span->chan_open.  Every 20ms send chunk down each channel.
+00409  *
+00410  * This implementation should be user specific!
+00411  */
+00412 
+00413 int main(int argc, char* argv[])
+00414 {
+00415         int err=0;
+00416 
+00417         nice(-10);
+00418 
+00419         signal(SIGINT,&sig_end);
+00420         signal(SIGTERM,&sig_end);
+00421 
+00422         aft_set_flag(system_flag,SYSTEM_RUNNING);
+00423 
+00424         log_printf(0, NULL, "HP TDM API MAIN Process Starting\n");
+00425 
+00426         err=smg_init_spans();
+00427         if (err) {
+00428                 aft_clear_flag(system_flag,SYSTEM_RUNNING);
+00429         }
+00430 
+00431         while(aft_test_flag(system_flag,SYSTEM_RUNNING)){
+00432                 sleep(1);
+00433         }
+00434 
+00435         sleep(5);
+00436         log_printf(0, NULL, "HP TDM API MAIN Process Exiting\n");
+00437 
+00438         return 0;
+00439 };
+

Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8h-source.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8h-source.html.svn-base new file mode 100644 index 0000000..7f19ee9 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/aft__tdm__hp_8h-source.html.svn-base @@ -0,0 +1,118 @@ + + +hptdm_api: aft_tdm_hp.h Source File + + + + + +

aft_tdm_hp.h

00001 /*****************************************************************************
+00002 * aft_tdm_hp.c: Example code for HP TDM API Library
+00003 *
+00004 * Author(s):    Nenad Corbic <ncorbic@sangoma.com>
+00005 *
+00006 * Copyright:    (c) 2008 Sangoma Technologies Inc.
+00007 *
+00008 *               This program is free software; you can redistribute it and/or
+00009 *               modify it under the terms of the GNU General Public License
+00010 *               as published by the Free Software Foundation; either version
+00011 *               2 of the License, or (at your option) any later version.
+00012 * ============================================================================
+00013 * Description:
+00014 *
+00015 */
+00016 
+00017 #ifndef __AFT_TDM_HP_H_
+00018 #define __AFT_TDM_HP_H_
+00019 
+00020 #define _GNU_SOURCE
+00021 #include <stdio.h>
+00022 #include <string.h>
+00023 #include <stdarg.h>
+00024 #include <stdlib.h>
+00025 #include <sys/types.h>
+00026 #include <sys/socket.h>
+00027 #include <netinet/in.h>
+00028 #include <arpa/inet.h>
+00029 #include <netdb.h>
+00030 #include <unistd.h>
+00031 #include <fcntl.h>
+00032 #include <sys/time.h>
+00033 #include <poll.h>
+00034 #include <signal.h>
+00035 #include <pthread.h>
+00036 #include <netinet/tcp.h>
+00037 #include <assert.h>
+00038 #include <sys/mman.h>
+00039 #include <syslog.h>
+00040 
+00041 #include <linux/wanpipe.h>
+00042 #include <libsangoma.h>
+00043 #include <libhpsangoma.h>
+00044 
+00046 #define MAX_SPANS 16
+00047 #define MAX_CHANS 31
+00048 
+00050 #define USE_SYSLOG 1
+00051 
+00053 #define MGD_STACK_SIZE 1024 * 240
+00054 
+00055 void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00056 
+00057 #define ysleep(usec) sched_yield() ; usleep(usec);
+00058 #define log_printf(level, fp, fmt, ...) __log_printf(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+00059 
+00063 enum {
+00064         SYSTEM_RUNNING=1,
+00065 };
+00066 
+00071 typedef struct span_idx
+00072 {
+00074         int init;
+00076         int span_no;
+00078         pthread_t thread;
+00080         sangoma_hptdm_span_t *span;
+00081 
+00082         /* Other private span variables insert here */
+00083 } span_idx_t;
+00084 
+00085 
+00090 typedef struct chan_idx
+00091 {
+00093         int init;
+00095         int chan_no;
+00097         int span_no;
+00099         pthread_t thread;
+00100 
+00102         sangoma_hptdm_chan_t *chan;
+00103 
+00104         /* Other private channel variables insert here */
+00105 } chan_idx_t;
+00106 
+00107 
+00112 #define aft_test_flag(p,flag)           ({ \
+00113                                         (p & (flag)); \
+00114                                         })
+00115 
+00116 #define aft_set_flag(p,flag)            do { \
+00117                                         (p |= (flag)); \
+00118                                         } while (0)
+00119 
+00120 #define aft_clear_flag(p,flag)          do { \
+00121                                         (p &= ~(flag)); \
+00122                                         } while (0)
+00123 
+00124 
+00125 #endif
+00126 
+00127 
+

Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/annotated.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/annotated.html.svn-base new file mode 100644 index 0000000..c4f5579 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/annotated.html.svn-base @@ -0,0 +1,27 @@ + + +hptdm_api: Class List + + + + + + +

hptdm_api Class List

Here are the classes, structs, unions and interfaces with brief descriptions: + + +
chan_idx
span_idx
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base new file mode 100644 index 0000000..5d58369 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.css.svn-base @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/doxygen.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..f0a274bbaffdd67f6d784c894d9cf28729db0e14 GIT binary patch literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/files.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/files.html.svn-base new file mode 100644 index 0000000..cae2c8b --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/files.html.svn-base @@ -0,0 +1,22 @@ + + +hptdm_api: File Index + + + + + +

hptdm_api File List

Here is a list of all documented files with brief descriptions: + + +
aft_tdm_hp.c [code]
aft_tdm_hp.h [code]
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions.html.svn-base new file mode 100644 index 0000000..5f4dce4 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions.html.svn-base @@ -0,0 +1,39 @@ + + +hptdm_api: Class Members + + + + + + +
+ +
+Here is a list of all documented class members with links to the class documentation for each member: +

+

+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base new file mode 100644 index 0000000..bde8898 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/functions_vars.html.svn-base @@ -0,0 +1,39 @@ + + +hptdm_api: Class Members - Variables + + + + + + +
+ +
+  +

+

+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base new file mode 100644 index 0000000..4a1a09c --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.dot.svn-base @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="FreeSans.ttf",fontsize=10,labelfontname="FreeSans.ttf",labelfontsize=10]; + node [fontname="FreeSans.ttf",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",fillcolor="grey75",style="filled" fontcolor="black"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="FreeSans.ttf"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="FreeSans.ttf"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classUsed.html"]; +} diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base new file mode 100644 index 0000000..144f1ff --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.html.svn-base @@ -0,0 +1,80 @@ + + +hptdm_api: Graph Legend + + + + + +

Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

+Consider the following example:

/*! Invisible class because of truncation */
+class Invisible { };
+
+/*! Truncated class, inheritance relation is hidden */
+class Truncated : public Invisible { };
+
+/* Class not documented with doxygen comments */
+class Undocumented { };
+
+/*! Class that is inherited using public inheritance */
+class PublicBase : public Truncated { };
+
+/*! A template class */
+template<class T> class Templ { };
+
+/*! Class that is inherited using protected inheritance */
+class ProtectedBase { };
+
+/*! Class that is inherited using private inheritance */
+class PrivateBase { };
+
+/*! Class that is used by the Inherited class */
+class Used { };
+
+/*! Super class that inherits a number of other classes */
+class Inherited : public PublicBase,
+                  protected ProtectedBase,
+                  private PrivateBase,
+                  public Undocumented
+                  public Templ<int>
+{
+  private:
+    Used *m_usedClass;
+};
+
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

+

+graph_legend.png +
+

+The boxes in the above graph have the following meaning:

    +
  • +A filled black box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a grey border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+The arrows have the following meaning:
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/graph_legend.png.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..66b423efdf8e0dae73a4c98fe12a4ac548c3e20c GIT binary patch literal 21232 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 literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/index.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..0f8a19f --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/index.html.svn-base @@ -0,0 +1,20 @@ + + +hptdm_api: Main Page + + + + + +

hptdm_api Documentation

+

+

1


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx-members.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx-members.html.svn-base new file mode 100644 index 0000000..44b39b1 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx-members.html.svn-base @@ -0,0 +1,29 @@ + + +hptdm_api: Member List + + + + + + +

chan_idx Member List

This is the complete list of members for chan_idx, including all inherited members.

+ + + + + +
chanchan_idx
chan_nochan_idx
initchan_idx
span_nochan_idx
threadchan_idx


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx.html.svn-base new file mode 100644 index 0000000..3e2f79e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structchan__idx.html.svn-base @@ -0,0 +1,132 @@ + + +hptdm_api: chan_idx Struct Reference + + + + + + +

chan_idx Struct Reference

#include <aft_tdm_hp.h> +

+List of all members. + + + + + + + + + + + + +

Public Attributes

int init
int chan_no
int span_no
pthread_t thread
sangoma_hptdm_chan_t * chan
+


Detailed Description

+Channel index structure. Defines the program channel structure along with supporting variables needed to operate a chan. +

+ +

+Definition at line 90 of file aft_tdm_hp.h.


Member Data Documentation

+ +
+
+ + + + +
sangoma_hptdm_chan_t* chan_idx::chan
+
+
+ +

+channel object obtaind by span->open_chan() method +

+Definition at line 102 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::chan_no
+
+
+ +

+channel number - integer starting from 0 +

+Definition at line 95 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::init
+
+
+ +

+init flag used to determine if span is being used +

+Definition at line 93 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::span_no
+
+
+ +

+span number - owner of the current channel - integer starting from 0 +

+Definition at line 97 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
pthread_t chan_idx::thread
+
+
+ +

+pthread id for this channel, because every channel will have its own thread +

+Definition at line 99 of file aft_tdm_hp.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx-members.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx-members.html.svn-base new file mode 100644 index 0000000..670e019 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx-members.html.svn-base @@ -0,0 +1,28 @@ + + +hptdm_api: Member List + + + + + + +

span_idx Member List

This is the complete list of members for span_idx, including all inherited members.

+ + + + +
initspan_idx
spanspan_idx
span_nospan_idx
threadspan_idx


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx.html.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx.html.svn-base new file mode 100644 index 0000000..9018310 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/structspan__idx.html.svn-base @@ -0,0 +1,113 @@ + + +hptdm_api: span_idx Struct Reference + + + + + + +

span_idx Struct Reference

#include <aft_tdm_hp.h> +

+List of all members. + + + + + + + + + + +

Public Attributes

int init
int span_no
pthread_t thread
sangoma_hptdm_span_t * span
+


Detailed Description

+Span index structure. Defines the program span structure along with supporting variables needed to operate span +

+ +

+Definition at line 71 of file aft_tdm_hp.h.


Member Data Documentation

+ +
+
+ + + + +
int span_idx::init
+
+
+ +

+init flag used to determine if span is being used +

+Definition at line 74 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
sangoma_hptdm_span_t* span_idx::span
+
+
+ +

+span object - returned by sangoma_hptdm_api_span_init() function +

+Definition at line 80 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int span_idx::span_no
+
+
+ +

+span number - integer starting from 0 +

+Definition at line 76 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
pthread_t span_idx::thread
+
+
+ +

+pthread id - because each span will have its own thread +

+Definition at line 78 of file aft_tdm_hp.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_b.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..0d623483ffdf5f9f96900108042a7ab0643fe2a3 GIT binary patch literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_l.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..9b1e6337c9299a700401a2a78a2c6ffced475216 GIT binary patch literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tab_r.gif.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..ce9dd9f533cb5486d6941844f442b59d4a9e9175 GIT binary patch literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tabs.css.svn-base b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tabs.css.svn-base new file mode 100644 index 0000000..a61552a --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/.svn/text-base/tabs.css.svn-base @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8c-source.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8c-source.html new file mode 100644 index 0000000..d5a31c0 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8c-source.html @@ -0,0 +1,457 @@ + + +hptdm_api: aft_tdm_hp.c Source File + + + + + +

aft_tdm_hp.c

00001 /*****************************************************************************
+00002 * aft_tdm_hp.c: Example code for HP TDM API Library
+00003 *
+00004 * Author(s):    Nenad Corbic <ncorbic@sangoma.com>
+00005 *
+00006 * Copyright:    (c) 2008 Sangoma Technologies Inc.
+00007 *
+00008 *               This program is free software; you can redistribute it and/or
+00009 *               modify it under the terms of the GNU General Public License
+00010 *               as published by the Free Software Foundation; either version
+00011 *               2 of the License, or (at your option) any later version.
+00012 * ============================================================================
+00013 * Description:
+00014 *
+00015 */
+00016 
+00017 #include "aft_tdm_hp.h"
+00018 
+00019 
+00020 /*
+00021  * Global flags used by this program
+00022  */
+00023 static int system_flag=0;
+00024 static int system_threads=0;
+00025 static int system_debug=10;
+00026 
+00027 /*
+00028  * Global defines for our program.  Create an array of spans and chans.
+00029  */
+00030 span_idx_t span_list[MAX_SPANS];
+00031 chan_idx_t chan_list[MAX_SPANS][MAX_CHANS];
+00032 
+00033 /*------------------------------------------
+00034   Utilites
+00035  *-----------------------------------------*/
+00036 
+00037 /*
+00038  * Utility used to print packets
+00039  */
+00040 void print_packet(unsigned char *buf, int len)
+00041 {
+00042         int x;
+00043         printf("{  | ");
+00044         for (x=0;x<len;x++){
+00045                 if (x && x%24 == 0){
+00046                         printf("\n  ");
+00047                 }
+00048                 if (x && x%8 == 0)
+00049                         printf(" | ");
+00050                 printf("%02x ",buf[x]);
+00051         }
+00052         printf("}\n");
+00053 }
+00054 
+00055 
+00056 /*
+00057  * Utility used to implement print to syslog
+00058  */
+00059 void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)
+00060 {
+00061     char *data;
+00062     int ret = 0;
+00063     va_list ap;
+00064 
+00065     if (socket < 0) {
+00066                 return;
+00067     }
+00068 
+00069     if (level && level > system_debug) {
+00070                 return;
+00071     }
+00072 
+00073     va_start(ap, fmt);
+00074 #ifdef SOLARIS
+00075     data = (char *) smg_malloc(2048);
+00076     vsnprintf(data, 2048, fmt, ap);
+00077 #else
+00078     ret = vasprintf(&data, fmt, ap);
+00079 #endif
+00080     va_end(ap);
+00081     if (ret == -1) {
+00082                 fprintf(stderr, "Memory Error\n");
+00083     } else {
+00084                 char date[80] = "";
+00085                 struct tm now;
+00086                 time_t epoch;
+00087 
+00088                 if (time(&epoch) && localtime_r(&epoch, &now)) {
+00089                         strftime(date, sizeof(date), "%Y-%m-%d %T", &now);
+00090                 }
+00091 
+00092 #ifdef USE_SYSLOG
+00093                 syslog(LOG_DEBUG | LOG_LOCAL2, data);
+00094 #else
+00095                 if (fp) {
+00096                 fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data);
+00097                 }
+00098 #endif
+00099                 free(data);
+00100     }
+00101 #ifndef USE_SYSLOG
+00102     fflush(fp);
+00103 #endif
+00104 }
+00105 
+00106 void sig_end(int sigid)
+00107 {
+00108         printf("%d: Got Signal %i\n",getpid(),sigid);
+00109         aft_clear_flag(system_flag,SYSTEM_RUNNING);
+00110 }
+00111 
+00112 
+00113 
+00114 /*
+00115  * Main pthread thread used to implement a span->run_span() thread.
+00116  * All this thread does is call span->run_span() method.
+00117  * span->run-span method is defined in libsangoma library and it
+00118  * implements rx/tx/oob on span hw interface.
+00119  */
+00120 static void *hp_tdmapi_span_run(void *obj)
+00121 {
+00122         span_idx_t *span_idx = (span_idx_t*)obj;
+00123         int err;
+00124         sangoma_hptdm_span_t *span = span_idx->span;
+00125 
+00126         span_idx->init = 1;
+00127 
+00128         log_printf(0,NULL,"Starting span %i!\n",span->span_no+1);
+00129 
+00130         while(aft_test_flag(system_flag,SYSTEM_RUNNING)){
+00131 
+00132                 if (!span->run_span) {
+00133                         break;
+00134                 }
+00135 
+00136                 err = span->run_span(span);
+00137                 if (err) {
+00138                         log_printf(0,NULL,"Span %i run_span exited err=%i!\n",span->span_no+1,err);
+00139                         usleep(5000);
+00140                         continue;
+00141                 }
+00142 
+00143         }
+00144 
+00145         if (span->close_span) {
+00146                 span->close_span(span);
+00147         }
+00148 
+00149         span_idx->init = 0;
+00150 
+00151         /* Arbitrary delay - implementation specific */
+00152         sleep(3);
+00153         log_printf(0,NULL,"Stopping span %i!\n",span->span_no+1);
+00154 
+00155         pthread_exit(NULL);
+00156 }
+00157 
+00158 /*
+00159  * Span Thrad Launcher.
+00160  * Spawn a span thread, give the thread span object poiner.
+00161  * This implementation should be user specific.
+00162  */
+00163 static int launch_hptdm_api_span_thread(pthread_t *threadid, void *span)
+00164 {
+00165         pthread_attr_t attr;
+00166         int result = 0;
+00167         struct sched_param param;
+00168 
+00169         param.sched_priority = 5;
+00170         result = pthread_attr_init(&attr);
+00171         pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+00172         pthread_attr_setschedpolicy(&attr, SCHED_RR);
+00173         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+00174         pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
+00175 
+00176         result = pthread_attr_setschedparam (&attr, &param);
+00177 
+00178         result = pthread_create(threadid, &attr, hp_tdmapi_span_run, span);
+00179         if (result) {
+00180                 log_printf(0, NULL, "%s: Error: Creating Thread! %s\n",
+00181                            __FUNCTION__,strerror(errno));
+00182         }
+00183         pthread_attr_destroy(&attr);
+00184 
+00185         return result;
+00186 }
+00187 
+00188 
+00189 /*
+00190  * Channel callback function. When channel has a chunk of data
+00191  * ready for us, this function will be called to deliver the
+00192  * rx chunk.  The user should implement the logic here of
+00193  * what to do with that rx chunk.
+00194  *
+00195  * If we return 0 - channel will continue to operate normally.
+00196  * If we return -1 - channel will get closed and we will not
+00197  *                  receive any more data on this channel until
+00198  *                  channel is opened again.
+00199  */
+00200 
+00201 static int media_rx_ready(void *p, char *data, int len)
+00202 {
+00203         chan_idx_t *chan_idx = (chan_idx_t *)p;
+00204 
+00205         if (!chan_idx->init) {
+00206                 return -1;
+00207         }
+00208 
+00209         log_printf(15,NULL,"Chan s%ic%i Rx Data Len %i \n",
+00210                                 chan_idx->span_no+1,chan_idx->chan_no+1,len);
+00211 
+00212 #if 0
+00213         print_packet((unsigned char*)data,len);
+00214 #endif
+00215 
+00216         /* FIXME: ADD CODE HERE
+00217         Do something with rx chunk of data for this channel
+00218         */
+00219 
+00220 
+00221         /* If we return -1 here the library will close the channel */
+00222 
+00223         return 0;
+00224 }
+00225 
+00226 
+00227 /*
+00228  * Main pthread thread used to implement a channel thread.
+00229  * Since this is a channel TX thread, user would wait on
+00230  * some UDP socket for data to be transmitted to this channel.
+00231  *
+00232  * The channel thread opens the channel on a span using
+00233  * the library span->open_chan method.  Once the channel
+00234  * object is obtained, this thread can start pushing
+00235  * arbitrary data chunks into the channel.
+00236  *
+00237  */
+00238 static void *hp_tdmapi_chan_run(void *obj)
+00239 {
+00240         chan_idx_t *chan_idx = (chan_idx_t*)obj;
+00241         int err;
+00242         char data[1024];
+00243         int len=160; /* 20ms worth of ulaw/alaw */
+00244 
+00245         sangoma_hptdm_span_t *span;
+00246         sangoma_hptdm_chan_reg_t channel_reg;
+00247 
+00248         /* Grab a span based on the span_no - integer starting from 0 */
+00249         span_idx_t *span_idx = &span_list[chan_idx->span_no];
+00250         span = span_idx->span;
+00251 
+00252         log_printf(0,NULL,"Starting chan s%ic%i ...\n",
+00253                                 chan_idx->span_no+1,chan_idx->chan_no+1);
+00254 
+00255         /* Configure channel registration structure */
+00256         memset(&channel_reg,0,sizeof(channel_reg));
+00257         channel_reg.p = (void*)chan_idx;
+00258         channel_reg.rx_data = media_rx_ready;
+00259 
+00260         /* Set the local channel index to configured */
+00261         chan_idx->init = 1;
+00262 
+00263         /* Open a channel based on chan_no integer starting from 0, on a specific span */
+00264         err = span->open_chan(span, &channel_reg, chan_idx->chan_no, &chan_idx->chan);
+00265         if (err){
+00266                 log_printf(0,NULL,"Error openeing chan s%ic%i ...\n",
+00267                                 chan_idx->span_no+1,chan_idx->chan_no+1);
+00268                 pthread_exit(NULL);
+00269         }
+00270 
+00271 
+00272         memset(data,0,sizeof(data));
+00273 
+00274 
+00275         while (aft_test_flag(system_flag,SYSTEM_RUNNING)) {
+00276 
+00277                 /* FIXME: Wait for AUDIO from a UDP socket here
+00278                           once you receive data to tx to a channel
+00279                           use the push() funciton to pass the chunk
+00280                           into the channel.  The size can be of any length
+00281                           up to the MAX CHUNK SIZE */
+00282 
+00283                 /* In this example we dont have a socket to wait on
+00284                    so we just use a delay */
+00285                 usleep(1000);
+00286 
+00287                 err=chan_idx->chan->push(chan_idx->chan,
+00288                                          data,len);
+00289                 /*
+00290                 -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok
+00291                 */
+00292                 switch (err) {
+00293                 case 0:
+00294                         /* Data tx ok */
+00295                         break;
+00296                 case -1:
+00297                         /* packet too large */
+00298                         break;
+00299                 case -2:
+00300                         /* channel closed */
+00301                         break;
+00302                 case 1:
+00303                         /* failed to tx, channel busy - try again later - in 20ms or so */
+00304                         break;
+00305                 }
+00306         }
+00307 
+00308         /* Once we are done, close the channel */
+00309         span->close_chan(chan_idx->chan);
+00310 
+00311         /* Set the local channel index to free */
+00312         chan_idx->init = 0;
+00313 
+00314         pthread_exit(NULL);
+00315 }
+00316 
+00317 /*
+00318  * Channel Thrad Launcher.
+00319  * Spawn a channel thread, give the thread chan object poiner.
+00320  * This implementation should be user specific.
+00321  */
+00322 static int launch_hptdm_api_chan_thread(pthread_t *threadid, void *chan)
+00323 {
+00324     pthread_attr_t attr;
+00325     int result = 0;
+00326     struct sched_param param;
+00327 
+00328     param.sched_priority = 1;
+00329     result = pthread_attr_init(&attr);
+00330     pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+00331     pthread_attr_setschedpolicy(&attr, SCHED_RR);
+00332     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+00333     pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
+00334 
+00335     result = pthread_attr_setschedparam (&attr, &param);
+00336 
+00337     result = pthread_create(threadid, &attr, hp_tdmapi_chan_run, chan);
+00338     if (result) {
+00339          log_printf(0, NULL, "%s: Error: Creating Thread! %s\n",
+00340                          __FUNCTION__,strerror(result));
+00341     }
+00342     pthread_attr_destroy(&attr);
+00343 
+00344     return result;
+00345 }
+00346 
+00347 /*
+00348  * Start all spans and channels.
+00349  *
+00350  * This exmaple codes automatically starts all spans and channels together.
+00351  * The real world application would start all spans on startup.
+00352  * Jowever the channels would only get started once the signalling stack indicates
+00353  * a call on that specific channel.
+00354  *
+00355  * This implementation should be user specific.
+00356  */
+00357 int smg_init_spans(void)
+00358 {
+00359         int span,i;
+00360         int err=-1;
+00361         sangoma_hptdm_span_reg_t lib_callback;
+00362         lib_callback.log=__log_printf;
+00363 
+00364         for (span=0;span<16;span++) {
+00365                 span_list[span].span_no=span;
+00366                 span_list[span].span = sangoma_hptdm_api_span_init(span, &lib_callback);
+00367                 if (!span_list[span].span) {
+00368                         log_printf(0, NULL, "Error: Failed to initialize span %i\n",
+00369                                         span+1);
+00370                         break;
+00371                 } else {
+00372                         log_printf(0, NULL, "HP TDM API Span: %d configured...\n",
+00373                                         span+1);
+00374 
+00375                         err=launch_hptdm_api_span_thread(&span_list[span].thread,&span_list[span]);
+00376                         if (err) {
+00377                                 return err;
+00378                         }
+00379 
+00380                         for (i=0;i<31;i++) {
+00381                                 chan_list[span][i].chan_no=i;
+00382                                 chan_list[span][i].span_no=span;
+00383 
+00384                                 err=launch_hptdm_api_chan_thread(&chan_list[span][i].thread,
+00385                                                                  &chan_list[span][i]);
+00386                                 if (err) {
+00387                                         return err;
+00388                                 }
+00389                         }
+00390                 }
+00391         }
+00392 
+00393         return err;
+00394 }
+00395 
+00396 /*
+00397  * Applicatoin Main Function
+00398  *
+00399  * This implementation should be user specific!
+00400  *
+00401  * Configure and initialize application
+00402  * Set a global sytem flag indicating that app is running.
+00403  *
+00404  * Start all SPANS by calling span init function and
+00405  * launching a thread per span. In span thread calling run_span().
+00406  *
+00407  * Start all channels by launching a thread per channel and
+00408  * calling span->chan_open.  Every 20ms send chunk down each channel.
+00409  *
+00410  * This implementation should be user specific!
+00411  */
+00412 
+00413 int main(int argc, char* argv[])
+00414 {
+00415         int err=0;
+00416 
+00417         nice(-10);
+00418 
+00419         signal(SIGINT,&sig_end);
+00420         signal(SIGTERM,&sig_end);
+00421 
+00422         aft_set_flag(system_flag,SYSTEM_RUNNING);
+00423 
+00424         log_printf(0, NULL, "HP TDM API MAIN Process Starting\n");
+00425 
+00426         err=smg_init_spans();
+00427         if (err) {
+00428                 aft_clear_flag(system_flag,SYSTEM_RUNNING);
+00429         }
+00430 
+00431         while(aft_test_flag(system_flag,SYSTEM_RUNNING)){
+00432                 sleep(1);
+00433         }
+00434 
+00435         sleep(5);
+00436         log_printf(0, NULL, "HP TDM API MAIN Process Exiting\n");
+00437 
+00438         return 0;
+00439 };
+

Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8h-source.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8h-source.html new file mode 100644 index 0000000..7f19ee9 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/aft__tdm__hp_8h-source.html @@ -0,0 +1,118 @@ + + +hptdm_api: aft_tdm_hp.h Source File + + + + + +

aft_tdm_hp.h

00001 /*****************************************************************************
+00002 * aft_tdm_hp.c: Example code for HP TDM API Library
+00003 *
+00004 * Author(s):    Nenad Corbic <ncorbic@sangoma.com>
+00005 *
+00006 * Copyright:    (c) 2008 Sangoma Technologies Inc.
+00007 *
+00008 *               This program is free software; you can redistribute it and/or
+00009 *               modify it under the terms of the GNU General Public License
+00010 *               as published by the Free Software Foundation; either version
+00011 *               2 of the License, or (at your option) any later version.
+00012 * ============================================================================
+00013 * Description:
+00014 *
+00015 */
+00016 
+00017 #ifndef __AFT_TDM_HP_H_
+00018 #define __AFT_TDM_HP_H_
+00019 
+00020 #define _GNU_SOURCE
+00021 #include <stdio.h>
+00022 #include <string.h>
+00023 #include <stdarg.h>
+00024 #include <stdlib.h>
+00025 #include <sys/types.h>
+00026 #include <sys/socket.h>
+00027 #include <netinet/in.h>
+00028 #include <arpa/inet.h>
+00029 #include <netdb.h>
+00030 #include <unistd.h>
+00031 #include <fcntl.h>
+00032 #include <sys/time.h>
+00033 #include <poll.h>
+00034 #include <signal.h>
+00035 #include <pthread.h>
+00036 #include <netinet/tcp.h>
+00037 #include <assert.h>
+00038 #include <sys/mman.h>
+00039 #include <syslog.h>
+00040 
+00041 #include <linux/wanpipe.h>
+00042 #include <libsangoma.h>
+00043 #include <libhpsangoma.h>
+00044 
+00046 #define MAX_SPANS 16
+00047 #define MAX_CHANS 31
+00048 
+00050 #define USE_SYSLOG 1
+00051 
+00053 #define MGD_STACK_SIZE 1024 * 240
+00054 
+00055 void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...);
+00056 
+00057 #define ysleep(usec) sched_yield() ; usleep(usec);
+00058 #define log_printf(level, fp, fmt, ...) __log_printf(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+00059 
+00063 enum {
+00064         SYSTEM_RUNNING=1,
+00065 };
+00066 
+00071 typedef struct span_idx
+00072 {
+00074         int init;
+00076         int span_no;
+00078         pthread_t thread;
+00080         sangoma_hptdm_span_t *span;
+00081 
+00082         /* Other private span variables insert here */
+00083 } span_idx_t;
+00084 
+00085 
+00090 typedef struct chan_idx
+00091 {
+00093         int init;
+00095         int chan_no;
+00097         int span_no;
+00099         pthread_t thread;
+00100 
+00102         sangoma_hptdm_chan_t *chan;
+00103 
+00104         /* Other private channel variables insert here */
+00105 } chan_idx_t;
+00106 
+00107 
+00112 #define aft_test_flag(p,flag)           ({ \
+00113                                         (p & (flag)); \
+00114                                         })
+00115 
+00116 #define aft_set_flag(p,flag)            do { \
+00117                                         (p |= (flag)); \
+00118                                         } while (0)
+00119 
+00120 #define aft_clear_flag(p,flag)          do { \
+00121                                         (p &= ~(flag)); \
+00122                                         } while (0)
+00123 
+00124 
+00125 #endif
+00126 
+00127 
+

Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/annotated.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/annotated.html new file mode 100644 index 0000000..c4f5579 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/annotated.html @@ -0,0 +1,27 @@ + + +hptdm_api: Class List + + + + + + +

hptdm_api Class List

Here are the classes, structs, unions and interfaces with brief descriptions: + + +
chan_idx
span_idx
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.css b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.css new file mode 100644 index 0000000..5d58369 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.css @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.png b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..f0a274bbaffdd67f6d784c894d9cf28729db0e14 GIT binary patch literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/files.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/files.html new file mode 100644 index 0000000..cae2c8b --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/files.html @@ -0,0 +1,22 @@ + + +hptdm_api: File Index + + + + + +

hptdm_api File List

Here is a list of all documented files with brief descriptions: + + +
aft_tdm_hp.c [code]
aft_tdm_hp.h [code]
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions.html new file mode 100644 index 0000000..5f4dce4 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions.html @@ -0,0 +1,39 @@ + + +hptdm_api: Class Members + + + + + + +
+ +
+Here is a list of all documented class members with links to the class documentation for each member: +

+

+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions_vars.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions_vars.html new file mode 100644 index 0000000..bde8898 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/functions_vars.html @@ -0,0 +1,39 @@ + + +hptdm_api: Class Members - Variables + + + + + + +
+ +
+  +

+

+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.dot b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.dot new file mode 100644 index 0000000..4a1a09c --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.dot @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="FreeSans.ttf",fontsize=10,labelfontname="FreeSans.ttf",labelfontsize=10]; + node [fontname="FreeSans.ttf",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",fillcolor="grey75",style="filled" fontcolor="black"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="FreeSans.ttf"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="FreeSans.ttf"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="FreeSans.ttf"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="FreeSans.ttf",color="black",URL="$classUsed.html"]; +} diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.html new file mode 100644 index 0000000..144f1ff --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.html @@ -0,0 +1,80 @@ + + +hptdm_api: Graph Legend + + + + + +

Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

+Consider the following example:

/*! Invisible class because of truncation */
+class Invisible { };
+
+/*! Truncated class, inheritance relation is hidden */
+class Truncated : public Invisible { };
+
+/* Class not documented with doxygen comments */
+class Undocumented { };
+
+/*! Class that is inherited using public inheritance */
+class PublicBase : public Truncated { };
+
+/*! A template class */
+template<class T> class Templ { };
+
+/*! Class that is inherited using protected inheritance */
+class ProtectedBase { };
+
+/*! Class that is inherited using private inheritance */
+class PrivateBase { };
+
+/*! Class that is used by the Inherited class */
+class Used { };
+
+/*! Super class that inherits a number of other classes */
+class Inherited : public PublicBase,
+                  protected ProtectedBase,
+                  private PrivateBase,
+                  public Undocumented
+                  public Templ<int>
+{
+  private:
+    Used *m_usedClass;
+};
+
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

+

+graph_legend.png +
+

+The boxes in the above graph have the following meaning:

    +
  • +A filled black box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a grey border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+The arrows have the following meaning:
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.png b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/graph_legend.png new file mode 100644 index 0000000000000000000000000000000000000000..66b423efdf8e0dae73a4c98fe12a4ac548c3e20c GIT binary patch literal 21232 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 literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/index.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/index.html new file mode 100644 index 0000000..0f8a19f --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/index.html @@ -0,0 +1,20 @@ + + +hptdm_api: Main Page + + + + + +

hptdm_api Documentation

+

+

1


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx-members.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx-members.html new file mode 100644 index 0000000..44b39b1 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx-members.html @@ -0,0 +1,29 @@ + + +hptdm_api: Member List + + + + + + +

chan_idx Member List

This is the complete list of members for chan_idx, including all inherited members.

+ + + + + +
chanchan_idx
chan_nochan_idx
initchan_idx
span_nochan_idx
threadchan_idx


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx.html new file mode 100644 index 0000000..3e2f79e --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structchan__idx.html @@ -0,0 +1,132 @@ + + +hptdm_api: chan_idx Struct Reference + + + + + + +

chan_idx Struct Reference

#include <aft_tdm_hp.h> +

+List of all members. + + + + + + + + + + + + +

Public Attributes

int init
int chan_no
int span_no
pthread_t thread
sangoma_hptdm_chan_t * chan
+


Detailed Description

+Channel index structure. Defines the program channel structure along with supporting variables needed to operate a chan. +

+ +

+Definition at line 90 of file aft_tdm_hp.h.


Member Data Documentation

+ +
+
+ + + + +
sangoma_hptdm_chan_t* chan_idx::chan
+
+
+ +

+channel object obtaind by span->open_chan() method +

+Definition at line 102 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::chan_no
+
+
+ +

+channel number - integer starting from 0 +

+Definition at line 95 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::init
+
+
+ +

+init flag used to determine if span is being used +

+Definition at line 93 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int chan_idx::span_no
+
+
+ +

+span number - owner of the current channel - integer starting from 0 +

+Definition at line 97 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
pthread_t chan_idx::thread
+
+
+ +

+pthread id for this channel, because every channel will have its own thread +

+Definition at line 99 of file aft_tdm_hp.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx-members.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx-members.html new file mode 100644 index 0000000..670e019 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx-members.html @@ -0,0 +1,28 @@ + + +hptdm_api: Member List + + + + + + +

span_idx Member List

This is the complete list of members for span_idx, including all inherited members.

+ + + + +
initspan_idx
spanspan_idx
span_nospan_idx
threadspan_idx


Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx.html b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx.html new file mode 100644 index 0000000..9018310 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/structspan__idx.html @@ -0,0 +1,113 @@ + + +hptdm_api: span_idx Struct Reference + + + + + + +

span_idx Struct Reference

#include <aft_tdm_hp.h> +

+List of all members. + + + + + + + + + + +

Public Attributes

int init
int span_no
pthread_t thread
sangoma_hptdm_span_t * span
+


Detailed Description

+Span index structure. Defines the program span structure along with supporting variables needed to operate span +

+ +

+Definition at line 71 of file aft_tdm_hp.h.


Member Data Documentation

+ +
+
+ + + + +
int span_idx::init
+
+
+ +

+init flag used to determine if span is being used +

+Definition at line 74 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
sangoma_hptdm_span_t* span_idx::span
+
+
+ +

+span object - returned by sangoma_hptdm_api_span_init() function +

+Definition at line 80 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
int span_idx::span_no
+
+
+ +

+span number - integer starting from 0 +

+Definition at line 76 of file aft_tdm_hp.h. +

+

+ +

+
+ + + + +
pthread_t span_idx::thread
+
+
+ +

+pthread id - because each span will have its own thread +

+Definition at line 78 of file aft_tdm_hp.h. +

+

+


The documentation for this struct was generated from the following file: +
Generated on Mon Aug 18 00:00:36 2008 for hptdm_api by  + +doxygen 1.4.7
+ + diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_b.gif b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_b.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d623483ffdf5f9f96900108042a7ab0643fe2a3 GIT binary patch literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_l.gif b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_l.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b1e6337c9299a700401a2a78a2c6ffced475216 GIT binary patch literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_r.gif b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tab_r.gif new file mode 100644 index 0000000000000000000000000000000000000000..ce9dd9f533cb5486d6941844f442b59d4a9e9175 GIT binary patch literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo literal 0 HcmV?d00001 diff --git a/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tabs.css b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tabs.css new file mode 100644 index 0000000..a61552a --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/docs/doxygen/html/tabs.css @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/api/libsangoma/examples/hptdm_api/doxygen.config b/api/libsangoma/examples/hptdm_api/doxygen.config new file mode 100644 index 0000000..0ec845b --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/doxygen.config @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = hptdm_api + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = aft_tdm_hp.c aft_tdm_hp.h + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/api/libsangoma/examples/hptdm_api/rebuild.sh b/api/libsangoma/examples/hptdm_api/rebuild.sh new file mode 100755 index 0000000..397ff99 --- /dev/null +++ b/api/libsangoma/examples/hptdm_api/rebuild.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +home=$(pwd) + +cd ../libsangoma +make +make install + +cd $home +make clean +make + + diff --git a/api/libsangoma/examples/priserver/.svn/all-wcprops b/api/libsangoma/examples/priserver/.svn/all-wcprops new file mode 100644 index 0000000..d2927a4 --- /dev/null +++ b/api/libsangoma/examples/priserver/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver +END +sound.raw +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver/sound.raw +END +priserver.c +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver/priserver.c +END +librc +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver/librc +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver/Makefile +END +README +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/libsangoma/!svn/ver/17/trunk/examples/priserver/README +END diff --git a/api/libsangoma/examples/priserver/.svn/entries b/api/libsangoma/examples/priserver/.svn/entries new file mode 100644 index 0000000..15b9b81 --- /dev/null +++ b/api/libsangoma/examples/priserver/.svn/entries @@ -0,0 +1,89 @@ +8 + +dir +22 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples/priserver +https://www.sangomapbx.com/svn/libsangoma + + + +2008-08-18T04:26:05.260169Z +17 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +8fe45b59-3c47-0410-bdf9-e5d932a076a6 + +sound.raw +file + + + + +2008-08-18T04:42:47.000000Z +da36acc78b83d5047481df0cca63d969 +2008-08-18T04:26:05.260169Z +17 +ncorbic +has-props + +priserver.c +file + + + + +2008-08-18T04:42:47.000000Z +9f83030c20158d91b7ec6bb7a9392dcb +2008-08-18T04:26:05.260169Z +17 +ncorbic + +librc +file + + + + +2008-08-18T04:42:47.000000Z +5c222b74d68b1c7df3f937a9d6321d40 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +Makefile +file + + + + +2008-08-18T04:42:47.000000Z +b58ee42eeb2d5e921bdab940a9fda738 +2008-08-18T04:26:05.260169Z +17 +ncorbic + +README +file + + + + +2008-08-18T04:42:47.000000Z +40538792592cd766e4941d9b37dbaf56 +2008-08-18T04:26:05.260169Z +17 +ncorbic + diff --git a/api/libsangoma/examples/priserver/.svn/format b/api/libsangoma/examples/priserver/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/api/libsangoma/examples/priserver/.svn/format @@ -0,0 +1 @@ +8 diff --git a/api/libsangoma/examples/priserver/.svn/prop-base/sound.raw.svn-base b/api/libsangoma/examples/priserver/.svn/prop-base/sound.raw.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/api/libsangoma/examples/priserver/.svn/prop-base/sound.raw.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/api/libsangoma/examples/.svn/text-base/Makefile.svn-base b/api/libsangoma/examples/priserver/.svn/text-base/Makefile.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/text-base/Makefile.svn-base rename to api/libsangoma/examples/priserver/.svn/text-base/Makefile.svn-base diff --git a/api/libsangoma/examples/.svn/text-base/README.svn-base b/api/libsangoma/examples/priserver/.svn/text-base/README.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/text-base/README.svn-base rename to api/libsangoma/examples/priserver/.svn/text-base/README.svn-base diff --git a/api/libsangoma/examples/.svn/text-base/librc.svn-base b/api/libsangoma/examples/priserver/.svn/text-base/librc.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/text-base/librc.svn-base rename to api/libsangoma/examples/priserver/.svn/text-base/librc.svn-base diff --git a/api/libsangoma/examples/.svn/text-base/priserver.c.svn-base b/api/libsangoma/examples/priserver/.svn/text-base/priserver.c.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/text-base/priserver.c.svn-base rename to api/libsangoma/examples/priserver/.svn/text-base/priserver.c.svn-base diff --git a/api/libsangoma/examples/.svn/text-base/sound.raw.svn-base b/api/libsangoma/examples/priserver/.svn/text-base/sound.raw.svn-base similarity index 100% rename from api/libsangoma/examples/.svn/text-base/sound.raw.svn-base rename to api/libsangoma/examples/priserver/.svn/text-base/sound.raw.svn-base diff --git a/api/libsangoma/examples/Makefile b/api/libsangoma/examples/priserver/Makefile similarity index 100% rename from api/libsangoma/examples/Makefile rename to api/libsangoma/examples/priserver/Makefile diff --git a/api/libsangoma/examples/README b/api/libsangoma/examples/priserver/README similarity index 100% rename from api/libsangoma/examples/README rename to api/libsangoma/examples/priserver/README diff --git a/api/libsangoma/examples/librc b/api/libsangoma/examples/priserver/librc similarity index 100% rename from api/libsangoma/examples/librc rename to api/libsangoma/examples/priserver/librc diff --git a/api/libsangoma/examples/priserver.c b/api/libsangoma/examples/priserver/priserver.c similarity index 100% rename from api/libsangoma/examples/priserver.c rename to api/libsangoma/examples/priserver/priserver.c diff --git a/api/libsangoma/examples/sound.raw b/api/libsangoma/examples/priserver/sound.raw similarity index 100% rename from api/libsangoma/examples/sound.raw rename to api/libsangoma/examples/priserver/sound.raw diff --git a/api/libsangoma/libhpsangoma.c b/api/libsangoma/libhpsangoma.c new file mode 100644 index 0000000..3909a90 --- /dev/null +++ b/api/libsangoma/libhpsangoma.c @@ -0,0 +1,442 @@ +/***************************************************************************** + * libhpsangoma.c: Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 "libhpsangoma.h" +#include "libhpsangoma_priv.h" + +/*--------------------------------------------------------- + PRIVATE STRUCTURES + ----------------------------------------------------------*/ + +void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)=NULL; + + +/*! + \brief Channel Method: User tx a chunk into a channel + \param chan channel object + \param data pointer to user voice chunk + \param len size of user voice chunk + \return -1 = packet too large, -2 = channel closed, 1 = busy, 0 = tx ok +*/ + +static int sangoma_hp_tdm_chan_push(struct sangoma_hptdm_chan *chan, char *data, int len) +{ + hp_tmd_chunk_t *tx_chunk; + int free_slots; + + if (!chan->init) { + return -2; + } + + if (len >= SMG_HP_MAX_CHAN_DATA) { + /* Data Too Big */ + lib_printf(0,NULL,"chan_push c%i tx chunk len %i too big\n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in,len); + return -1; + } + + /* Lock */ + if (chan->tx_idx_in >= chan->tx_idx_out) { + free_slots=SMG_HP_TDM_CHUNK_IDX_SZ-(chan->tx_idx_in-chan->tx_idx_out); + } else { + free_slots=chan->tx_idx_out-chan->tx_idx_in; + } + /* Un Lock */ + + if (!free_slots) { + /* We have just overruned the tx buffer */ + lib_printf(0,NULL,"chan_push c%i failed no free slots in %i out %i\n", + chan->span_no+1,chan->chan_no+1, chan->tx_idx_in,chan->tx_idx_out); + return 1; + } + + tx_chunk = &chan->tx_idx[chan->tx_idx_in]; + if (tx_chunk->init) { + /* This should NEVER happen the chunk should be free */ + lib_printf(15,NULL,"chan_push s%ic%i tx chunk overrun in %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in); + return 1; + } + + memset(tx_chunk,0,sizeof(hp_tmd_chunk_t)); + memcpy(&tx_chunk->data,data,len); + tx_chunk->len=len; + tx_chunk->init=1; + + lib_printf(15,NULL,"chan_push s%ic%i tx chunk in %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_in); + + chan->tx_idx_in++; + if (chan->tx_idx_in >= SMG_HP_TDM_CHUNK_IDX_SZ) { + chan->tx_idx_in=0; + } + + return 0; +} + +/*------------------------------------------------- + Internal Span Methods + -------------------------------------------------*/ + + +/*! + \brief Span Method: Open a channel inside of span + \param span span object + \param cfg channel registration structure + \param chan_no channel number + \param chan_ptr pass user the channel pointer reference + \return 0 = pass, non zero fail +*/ + +static int sangoma_hp_tdm_open_chan(sangoma_hptdm_span_t *span, + sangoma_hptdm_chan_reg_t *cfg, + unsigned int chan_no, + sangoma_hptdm_chan_t **chan_ptr) +{ + sangoma_hptdm_chan_t *chan; + + if (!span->init) { + return -1; + } + + if (chan_no >= SMG_HP_TDM_MAX_CHANS) { + lib_printf(0,NULL,"open_chan failed chan_no %i >= max chans %i\n", + chan_no, SMG_HP_TDM_MAX_CHANS); + return -1; + } + + if (!cfg->rx_data || !cfg->p) { + return -1; + } + + if (span->chan_idx[chan_no].chan_no_hw < 0) { + lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is not mapped to hardware\n", + span->span_no+1,chan_no+1); + return -1; + } + + chan = &span->chan_idx[chan_no].chan; + if (chan->init) { + /* Chan Busy */ + lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is busy\n", + span->span_no+1,chan_no+1); + return 1; + } + + memset(chan,0,sizeof(sangoma_hptdm_chan_t)); + + chan->chan_no = chan_no; + chan->span = span; + memcpy(&chan->chan_reg, cfg, sizeof(sangoma_hptdm_chan_reg_t)); + + chan->push = sangoma_hp_tdm_chan_push; + + chan->init=1; + lib_printf(15,NULL,"open_chan chan_no s%ic%i ok\n", + span->span_no+1,chan_no+1); + + *chan_ptr = chan; + + return 0; + +} + + +/*! + \brief Span Method: Close channel + \param chan channel object + \return 0 = pass, non zero fail +*/ + +static int sangoma_hp_tdm_close_chan(sangoma_hptdm_chan_t *chan) +{ + chan->init=0; + chan->chan_reg.p=NULL; + lib_printf(15,NULL,"close_chan chan_no s%ic%i ok\n", + chan->span_no+1,chan->chan_no+1); + return 0; +} + + +/*! + \brief Span Method: Test if channel is closed + \param chan channel object + \return 0 = channel is NOT closed, non zero channel IS closed +*/ +static int sangoma_hp_tdm_is_chan_closed (sangoma_hptdm_chan_t *chan) +{ + return (chan->init == 0) ? 1:0; +} + +/*! + \brief Span Method: Close span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_close_span(sangoma_hptdm_span_t *span) +{ + int i; + sangoma_hptdm_chan_t *chan=NULL; + + for (i=0;ichan_idx[i].chan; + if (chan->init) { + chan->init=0; + } + } + + close(span->sock); + span->sock=-1; + + return 0; +} + +/*! + \brief Span Method: User passes cmd to the span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_event_ctrl_span(sangoma_hptdm_span_t *span, hp_tdmapi_tx_event_t *event) +{ + int err; + + if (!span->init || span->sock < 0) { + return -1; + } + + err = ioctl(span->sock,SIOC_WANPIPE_API,event); + if (err < 0){ + lib_printf(0,NULL,"Error: SPAN %i Failed to execute event!\n", + span->span_no+1); + return -1; + } + + return 0; +} + +/*! + \brief Span Method: User requests full span configuration + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_event_get_cfg(sangoma_hptdm_span_t *span, wan_if_cfg_t *if_cfg) +{ + memcpy(if_cfg,&span->span_cfg,sizeof(if_cfg)); + return 0; +} + +/*! + \brief Span Method: handle the span + \param span span object + \return 0 = pass, non zero fail +*/ +static int sangoma_hp_tdm_run_span(sangoma_hptdm_span_t *span) +{ + int err=0; + fd_set sock_read,sock_write,sock_oob; + + if (!span->init) { + lib_printf(0, NULL, "Span %i not initialized %i\n",span->span_no+1); + return -1; + } + + lib_printf(15, NULL, "Starting RUN SPAN %i Sock=%i\n",span->span_no+1, span->sock); + + if (span->sock < 0) { + err=sangoma_hptdm_span_open(span); + if (err) { + usleep(500000); + err=-2; + goto sangoma_hp_tdm_run_span_exit; + } + } + + /* Initialize all select() descriptors */ + FD_ZERO(&sock_read); + FD_ZERO(&sock_write); + FD_ZERO(&sock_oob); + + FD_SET(span->sock,&sock_oob); + FD_SET(span->sock,&sock_read); + FD_SET(span->sock,&sock_write); + + err=select(span->sock + 1,&sock_read, NULL, &sock_oob, NULL); + + if (err > 0) { + + if (FD_ISSET(span->sock,&sock_oob)){ + err=sangoma_hp_tdm_handle_oob_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i oob err %i\n", + span->span_no+1, err); + err=-3; + goto sangoma_hp_tdm_run_span_exit; + } + } + if (FD_ISSET(span->sock,&sock_read)){ + err=sangoma_hp_tdm_handle_read_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i read err %i\n", + span->span_no+1, err); + err=-4; + goto sangoma_hp_tdm_run_span_exit; + } + + err=sangoma_hp_tdm_handle_write_event(span); + if (err) { + lib_printf(0, NULL, "RUN SPAN: %i write err %i\n", + span->span_no+1, err); + err=-5; + goto sangoma_hp_tdm_run_span_exit; + } + } + + } else if (err==0) { + /* Timeout continue */ + return 0; + + } else { + /* Error */ + if (errno == EAGAIN) { + goto sangoma_hp_tdm_run_span_exit; + } + + err=-6; + } + +sangoma_hp_tdm_run_span_exit: + + if (err < 0) { + if (span->sock) { + close(span->sock); + span->sock=-1; + } + } + + return err; +} + + + +/*--------------------------------------------------------- + PUBLIC STRUCTURES + ----------------------------------------------------------*/ + + +/* + \brief Initialize and Configure Span - private functions not to be used directly! + \param span_no span number - integer + \param cfg span registration struct + \param version library version number added by the macro + \return NULL: fail, Span Object: pass + * + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ + +sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version) +{ + int err,i,ch=0; + sangoma_hptdm_span_t *span; + + span = malloc(sizeof(sangoma_hptdm_span_t)); + if (!span) { + return NULL; + } + + memset(span,0,sizeof(sangoma_hptdm_span_t)); + + span->span_no=span_no; + sprintf(span->if_name,"w%ig1",span_no+1); + + if (cfg) { + memcpy(&span->span_reg,cfg,sizeof(sangoma_hptdm_span_reg_t)); + if (!lib_log) { + lib_log=cfg->log; + } + } + + err=sangoma_hptdm_span_open(span); + if (err) { + free(span); + return NULL; + } + + if (span->span_cfg.media == WAN_MEDIA_E1) { + span->span_cfg.active_ch = span->span_cfg.active_ch >> 1; + } + + lib_printf(0,NULL,"Span %i Configuration\n",span->span_no+1); + lib_printf(0,NULL,"Used By\t:%i\n",span->span_cfg.usedby); + lib_printf(0,NULL,"Media\t:%i\n",span->span_cfg.media); + lib_printf(0,NULL,"Active Ch\t:0x%08X\n",span->span_cfg.active_ch); + lib_printf(0,NULL,"Chunk Sz\t:%i\n",span->span_cfg.chunk_sz); + lib_printf(0,NULL,"HW Coding\t:%i\n",span->span_cfg.hw_coding); + lib_printf(0,NULL,"If Number\t:%i\n",span->span_cfg.interface_number); + + + /* Map all channels to the actually configued on hardware */ + for (i=0;ichan_idx[i].chan_no_hw=-1; + if (span->span_cfg.active_ch & (1<chan_idx[i].chan_no_hw=ch; + lib_printf(0,NULL,"Chan %i Mapped to %i",i,ch); + ch++; + span->max_chans++; + } else { + lib_printf(0,NULL,"Chan %i Not Mapped",i); + } + } + + lib_printf(0,NULL,"Total Chans\t:%i\n",span->max_chans); + + /* Must be configurable */ + span->chunk_sz=span->span_cfg.chunk_sz; + span->tx_size=span->max_chans*span->chunk_sz; + + span->init=1; + span->idle=0xFF; + + span->open_chan = sangoma_hp_tdm_open_chan; + span->close_chan = sangoma_hp_tdm_close_chan; + span->is_chan_closed = sangoma_hp_tdm_is_chan_closed; + span->run_span =sangoma_hp_tdm_run_span; + span->close_span = sangoma_hp_tdm_close_span; + span->event_ctrl = sangoma_hp_tdm_event_ctrl_span; + span->get_cfg = sangoma_hp_tdm_event_get_cfg; + + lib_printf(5, NULL, "Span %i Initialized\n",span->span_no+1); + + return span; +} + +/* + \brief Free, Un-Initialize Span + \param span_no span object + \return 0 = pass, non zero fail + */ + +int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span) +{ + if (span->sock >= 0) { + span->close_span(span); + } + + free(span); + span=NULL; + + return 0; +} + diff --git a/api/libsangoma/libhpsangoma.h b/api/libsangoma/libhpsangoma.h new file mode 100644 index 0000000..8467f9d --- /dev/null +++ b/api/libsangoma/libhpsangoma.h @@ -0,0 +1,324 @@ +/***************************************************************************** + * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 _LIB_HP_SNAGOMA_H +#define _LIB_HP_SNAGOMA_H + + +#ifdef WIN32 + +#error "WINDOWS NOT DEFINED" + +#else +/* L I N U X */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#endif + +#define SMG_HP_MAX_CHAN_DATA 1024 +#define SMG_HP_TDM_CHUNK_IDX_SZ 16 +#define SMG_HP_TDM_MAX_CHANS 31 +#define SMG_HP_MAX_SPAN_DATA (31*160)+32 + +#define hp_tdmapi_rx_event_t api_rx_hdr_t +#define hp_tdmapi_tx_event_t api_tx_hdr_t + +#define SANGOMA_HPTDM_VERSION 1 + +/*--------------------------------------------------------- + * PUBLIC DEFINITIONS + */ + + +/*! + \brief Span registration structure + */ +typedef struct sangoma_hptdm_span_reg +{ + /*! pointer to user object used with callback functions */ + void *p; + /*! callback function to implement library logging */ + void (*log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + /*! callback function to span global events for all channels in a span */ + int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data); +}sangoma_hptdm_span_reg_t; + + +/*! + \brief A chunk structure used to implement a chunk buffer + */ +typedef struct hp_tdm_chunk +{ + /*! chunk init flag used to determine if chunk is being used*/ + int init; + /*! length of the current data chunk */ + int len; + /*! current offset to write/read to/from the chunk data structure. */ + int offset; + /*! chunk data location */ + char data[SMG_HP_MAX_CHAN_DATA]; +}hp_tmd_chunk_t; + +/*! + \brief Chan registration structure + */ +typedef struct sangoma_hptdm_chan_reg +{ + /*! pointer to user object used with callback functions */ + void *p; + /*! callback function used to pass rx chunk to user application */ + int (*rx_data)(void *p, char *data, int len); + /*! callback function used to pass channel specific event to user application */ + int (*rx_event)(void *p, hp_tdmapi_rx_event_t *data); + +}sangoma_hptdm_chan_reg_t; + +/*! + \brief Channel structure, describes a single timeslot/channel in a span. + */ +typedef struct sangoma_hptdm_chan +{ + /*! channel init flag used to determine if chan is being used */ + int init; + + /*! channel number: starting from 0 */ + int chan_no; + + /*! span number the current channel belongs to: starting from 0 */ + int span_no; + + /*! span object pointer the current channel belongs */ + void *span; + + /*! Rx chunk buffer used to rx data from the span */ + hp_tmd_chunk_t rx_chunk; + + /*! Circular buffer of tx data chunks used to tx data to span */ + hp_tmd_chunk_t tx_idx[SMG_HP_TDM_CHUNK_IDX_SZ]; + + /*! Circular buffer index for user to chan tx */ + int tx_idx_in; + + /*! Circular buffer index for chan to span tx */ + int tx_idx_out; + + /*! Callback func called by user to push chunk of data into the channel */ + int (*push)(struct sangoma_hptdm_chan *, char *data, int len); + + /*! Channel registration struct used to store user data, cfg and callbacks */ + sangoma_hptdm_chan_reg_t chan_reg; + +}sangoma_hptdm_chan_t; + +/*! + \brief Structure describing a array index of a channel inside the span structure. + * + * Structure describing a array index of a channel inside the span structure. + * Furthermore the index * also servers as a map from hardware channels to library channels. + * Hardware might be configured for channels 1-15.17-31, however library always + * provides all 31 channels + */ +typedef struct sangoma_hptdm_chan_map +{ + /*! A hardware channel number that is mapped to the current channel structure. + * Hardware might be configured for channels 1-15.17-31, however library always + * provides all 31 channels */ + int chan_no_hw; + + /*! A channel structure */ + sangoma_hptdm_chan_t chan; + +}sangoma_hptdm_chan_map_t; + + +/*! + \brief Span structure. Structure describing a single span. + */ +typedef struct sangoma_hptdm_span +{ + /*! span init flag used to determine if span is being used */ + int init; + + /*! span number - integer starting from 0 */ + int span_no; + + /*! span hw interface name to which span is bounded to */ + char if_name[100]; + + /*! span socket file descriptor used to rx/tx data to and from hw interface */ + int sock; + + /*! chunk size for each channel inside the span */ + int chunk_sz; + + /*! total number of channels configured in the span */ + int max_chans; + + /*! total tx data size to hw interface. tx_size = max_chans * chunk_sz */ + int tx_size; + + /*! idle flag used to fill an unused channel */ + unsigned char idle; + + /*! bit map of configured timeslots obtained from hw interface */ + unsigned int timeslot_cfg; + + /*! hw data encoding: ULAW/ALAW obtained from hw interface */ + unsigned int hwcoding; + + /*! array of maximum number of channels in a span */ + sangoma_hptdm_chan_map_t chan_idx[SMG_HP_TDM_MAX_CHANS]; + + /*! span rx data block: used to receive a block of data from hw interface: recv() */ + char rx_data[SMG_HP_MAX_SPAN_DATA]; + + /*! span rx data len, obtained after a recv() call to hw interface */ + int rx_len; + + /*! span tx data block: used to transmit a block of data to hw interface: send() */ + char tx_data[SMG_HP_MAX_SPAN_DATA]; + + /*! span tx data block len: passed to send() function */ + int tx_len; + + /*! span registration functions: contains user callback functions */ + sangoma_hptdm_span_reg_t span_reg; + + /*! span config structure obtained from hw interface via managment ioctl call. */ + wan_if_cfg_t span_cfg; + + /*! span managment structure used to execute mgmnt ioctl commands to hw interface */ + wan_udp_hdr_t wan_udp; + + /*! \brief Method: open a channel inside a span + * \param span span object + * \param chan_reg channel registration structure: callbacks and cfg + * \param chan_no channel number - integer starting from 0 + * \param chan_ptr user container for channel object passed up to the user. + */ + int (*open_chan)(struct sangoma_hptdm_span *span, + sangoma_hptdm_chan_reg_t *chan_reg, + unsigned int chan_no, + sangoma_hptdm_chan_t **chan_ptr); + + /*! \brief Method: close a channel inside the span + * \param chan chan object + */ + int (*close_chan)(sangoma_hptdm_chan_t *chan); + + /*! \brief Method: check if channel is closed + * \param chan chan object */ + int (*is_chan_closed)(sangoma_hptdm_chan_t *chan); + + /*! \brief Method: run main span execution logic: rx/tx/oob + * \param span span object + * + * Run main span execution logic. This function peforms all socket operations + * on a hw interface. Rx/Tx/Oob. + * Receives data and demultiplexes it to channels. + * Receives oob data and passes user events global to all channels. + * Multiplexes all channel tx data into a single tx data block and + * passes it to hw iface. + */ + int (*run_span)(struct sangoma_hptdm_span *span); + + /*! \brief Method: close span + * \param span span object */ + int (*close_span)(struct sangoma_hptdm_span *span); + + /*! \brief Method: used by user app to execute events on current span + * \param span span object + * \param event event object + */ + int (*event_ctrl)(struct sangoma_hptdm_span *span, hp_tdmapi_tx_event_t *event); + + /*! \brief Method: request full span configuration from a current span + * \param span span object + * \param cfg configuratoin object to be filled by span + */ + int (*get_cfg)(struct sangoma_hptdm_span *span, wan_if_cfg_t *cfg); + + +}sangoma_hptdm_span_t; + +/*--------------------------------------------------------- + * PUBLIC FUNCTIONS + */ + +/*! + \brief Initialize and Configure a Span + \param span_no span number - integer + \param cfg span registration struct + \return NULL: fail, Span Object: pass + */ + +/* Initialize and Configure a Span */ +#define sangoma_hptdm_api_span_init(span,cfg) __sangoma_hptdm_api_span_init(span, cfg, SANGOMA_HPTDM_VERSION); + +/*! + \brief Initialize and Configure Span - private functions not to be used directly! + \param span_no span number - integer + \param cfg span registration struct + \param version library version number added by the macro + \return NULL: fail, Span Object: pass + * + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ + + /* + * The __sangoma_hptdm_api_span_init() function must NOT be called directly! + * One MUST use defined sangoma_hptdm_api_span_init() macro instead + */ +extern sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version); + + +/*! + \brief Free, Un-Initialize Span + \param span_no span object + \return 0 = pass, non zero fail + */ +extern int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span); + + + + + +#endif + diff --git a/api/libsangoma/libhpsangoma_priv.c b/api/libsangoma/libhpsangoma_priv.c new file mode 100644 index 0000000..778fe06 --- /dev/null +++ b/api/libsangoma/libhpsangoma_priv.c @@ -0,0 +1,403 @@ +/***************************************************************************** + * libhpsangoma_priv.c: Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 "libhpsangoma.h" +#include "libhpsangoma_priv.h" +#define DFT_CARD "wanpipe1" + + +/*! + \brief Span read data from a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail +*/ +int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag) +{ + int rx_len=0; + +#if defined(WIN32) + +#error "WINDOWS HP TDMAPI NOT DEFINED" + +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + rx_len = recvmsg(fd,&msg,0); + + if (rx_len <= sizeof(api_rx_hdr_t)){ + return -EINVAL; + } + + rx_len-=sizeof(api_rx_hdr_t); +#endif + + return rx_len; +} + + + +/*! + \brief Span write data into a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail +*/ +int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag) +{ + int bsent; + +#if defined(WIN32) + +#error "Windows TX not implemented" + +#else + struct msghdr msg; + struct iovec iov[2]; + + memset(&msg,0,sizeof(struct msghdr)); + + iov[0].iov_len=hdrlen; + iov[0].iov_base=hdrbuf; + + iov[1].iov_len=datalen; + iov[1].iov_base=databuf; + + msg.msg_iovlen=2; + msg.msg_iov=iov; + + bsent = sendmsg(fd,&msg,0); + if (bsent > 0){ + bsent-=sizeof(api_tx_hdr_t); + } +#endif + return bsent; +} + +/*! + \brief Execute a management ioctl command + \param span span object + \return 0 = pass, non zero fail + */ +int do_wanpipemon_cmd(sangoma_hptdm_span_t *span) +{ + struct ifreq ifr; + memset(&ifr,0,sizeof(ifr)); + ifr.ifr_data = (void*)&span->wan_udp; + sprintf (ifr.ifr_name, "%s", span->if_name); + return ioctl(span->sock,SIOC_WANPIPE_PIPEMON,&ifr); +} + +/*! + \brief Get full span hw configuration + \param span span object + \return 0 = pass, non zero fail + */ +unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span) +{ + span->wan_udp.wan_udphdr_command = READ_CONFIGURATION; + span->wan_udp.wan_udphdr_data_len = 0; + span->wan_udp.wan_udphdr_return_code = 0xaa; + do_wanpipemon_cmd(span); + if (span->wan_udp.wan_udphdr_return_code != 0){ + lib_printf(0,NULL,"Error: SPAN %i management command failed 0x02Xs (%s)", + span->span_no+1, span->wan_udp.wan_udphdr_return_code,strerror(errno)); + return -1; + } + + memcpy(&span->span_cfg,&span->wan_udp.wan_udphdr_data[0],sizeof(span->span_cfg)); + + return 0; +} + + +/*! + \brief Open socket to span hw interface + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span) +{ + struct wan_sockaddr_ll sa; + char if_name[100]; + int sock=-1; + int err; + + memset(&sa,0,sizeof(struct wan_sockaddr_ll)); + sock = socket(AF_WANPIPE, SOCK_RAW, 0); + if( sock < 0 ) { + perror("Socket"); + return -1; + } /* if */ + + sprintf(if_name, "w%ig1", span->span_no+1); + + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, DFT_CARD); + sa.sll_protocol = htons(PVC_PROT); + sa.sll_family=AF_WANPIPE; + + if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){ + lib_printf(0,NULL,"bind failed on span span %i %s\n", + span->span_no+1,strerror(errno)); + return -1; + } + + span->sock=sock; + + err= sangoma_get_cfg(span); + if (err) { + goto sangoma_hptdm_span_open_error; + } + + lib_printf(0,NULL,"libhp: span %i opened\n", + span->span_no+1); + + return 0; + +sangoma_hptdm_span_open_error: + + if (span->sock) { + close(span->sock); + span->sock=-1; + } + + return err; +} + + +/*! + \brief Read oob event from hw and push oob event up to the user. Called after select() + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span) +{ + int err; + hp_tdmapi_rx_event_t *rx_event; + + err = recv(span->sock, span->rx_data, sizeof(span->rx_data), MSG_OOB); + if (err > 0) { + rx_event=(hp_tdmapi_rx_event_t*)&span->rx_data; + if (span->span_reg.rx_event && span->span_reg.p) { + span->span_reg.rx_event(span->span_reg.p, rx_event); + } + } + /* For now treat all err as socket reload */ + return 1; +} + +/*! + \brief Multiplex span rx data and push it up to each channel + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span) +{ + int i=0,x=0,err=0; + sangoma_hptdm_chan_t *chan=NULL; + hp_tmd_chunk_t *chunk=NULL; + int chan_no_hw; + char *rx_data = &span->rx_data[sizeof(api_rx_hdr_t)]; + + + for (i=0;ichan_idx[i].chan; + if (!chan->init) { + continue; + } + chan_no_hw = span->chan_idx[i].chan_no_hw; + + lib_printf(15,NULL, "SPAN %i Chan %i Chunk %i Channelizing\n", + span->span_no+1, chan->chan_no+1, span->chunk_sz); + + chunk = &chan->rx_chunk; + + for (x=0;xchunk_sz;x++) { + chunk->data[x] = rx_data[(span->max_chans*x)+chan_no_hw]; + } + + chunk->len = span->chunk_sz; + if (chan->chan_reg.p && chan->chan_reg.rx_data) { + err=chan->chan_reg.rx_data(chan->chan_reg.p,chunk->data,chunk->len); + } else { + err=1; + } + + if (err) { + chan->init=0; + chan->chan_reg.p=NULL; + } + + } + + return err; + + +} + +/*! + \brief Read data from hw interface and pass it up to the rxdata handler: called by run_span() + \param span span object + \return 0 = pass, non zero fail +*/ + +int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span) +{ + int err; + hp_tdmapi_rx_event_t *rx_event = (hp_tdmapi_rx_event_t*)&span->rx_data[0]; + + err = sangoma_readmsg_hp_tdm(span->sock, + &span->rx_data[0],sizeof(api_rx_hdr_t), + &span->rx_data[sizeof(api_rx_hdr_t)], + sizeof(span->rx_data) - sizeof(api_rx_hdr_t), + 0); + + if (err > sizeof(api_rx_hdr_t)) { + + lib_printf(15,NULL, "SPAN %i Read Len = %i\n",span->span_no+1,err); + + if (rx_event->event_type) { + + if (span->span_reg.rx_event && span->span_reg.p) { + span->span_reg.rx_event(span->span_reg.p, rx_event); + } + + } else { + + if (err % span->chunk_sz) { + lib_printf(0,NULL, "Error: SPAN %i Read Len = %i Block not chunk %i aligned! \n",span->span_no+1,err,span->chunk_sz); + /* Received chunk size is not aligned drop it for now */ + return 0; + } + + sangoma_hp_tdm_push_rx_data(span); + } + + err=0; + + } else { + if (errno == EAGAIN) { + err = 0; + } else { + err=-1; + } + } + + return err; +} + + +/*! + \brief Pull data from all chans and write data to hw interface: called by run_span() + \param span span object + \return 0 = pass, non zero fail +*/ +int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span) +{ + int i=0,x=0,err=0; + sangoma_hptdm_chan_t *chan; + hp_tmd_chunk_t *chunk; + int chan_no_hw=0; + char *tx_data = &span->tx_data[sizeof(api_tx_hdr_t)]; + + memset(&span->tx_data,span->idle,sizeof(span->tx_data)); + + + for (i=0;ichan_idx[i].chan; + if (!chan->init) { + /* This channel is not open */ + continue; + } + chan_no_hw=span->chan_idx[i].chan_no_hw; + + chunk = &chan->tx_idx[chan->tx_idx_out]; + if (!chunk->init) { + lib_printf(15,NULL,"span write s%ic%i tx chunk underrun out %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_out); + /* There is no tx data for this channel */ + continue; + } + + for (x=0;xchunk_sz;x++) { + + tx_data[(span->max_chans*x)+chan_no_hw] = chunk->data[chunk->offset]; + chunk->offset++; + + if (chunk->offset >= chunk->len) { + chunk->init=0; + + lib_printf(15,NULL,"span write s%ic%i tx chunk out %i \n", + chan->span_no+1,chan->chan_no+1,chan->tx_idx_out); + + chan->tx_idx_out++; + if (chan->tx_idx_out >= SMG_HP_TDM_CHUNK_IDX_SZ) { + chan->tx_idx_out=0; + } + chunk=&chan->tx_idx[chan->tx_idx_out]; + if (!chunk->init) { + /* We are out of tx data on this channel */ + break; + } + } + } + } + + + err = sangoma_writemsg_hp_tdm(span->sock, + span->tx_data,sizeof(api_tx_hdr_t), + tx_data, span->tx_size, + 0); + + lib_printf(15, NULL, "SPAN %i TX Len %i Expecting %i\n", + span->span_no+1, err, span->tx_size+sizeof(api_tx_hdr_t)); + + if (err < span->tx_size) { + if (errno == EAGAIN) { + return 0; + } else { + return -1; + } + } else { + err=0; + } + + return err; + +} diff --git a/api/libsangoma/libhpsangoma_priv.h b/api/libsangoma/libhpsangoma_priv.h new file mode 100644 index 0000000..3d10f0a --- /dev/null +++ b/api/libsangoma/libhpsangoma_priv.h @@ -0,0 +1,118 @@ +/***************************************************************************** + * libhpsangoma.h : Sangoma High Performance TDM API - Span Based Library + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2008 Nenad Corbic + * + * 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 _LIB_HP_SANGOMA_PRIV_H +#define _LIB_HP_SANGOMA_PRIV_H + +#include "libhpsangoma.h" + + +/*! + \brief library print function based on registered span callback function + \return void + */ +#define lib_printf(level, fp, fmt, ...) if (lib_log) lib_log(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + +extern void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + + +/*--------------------------------------------------------- + * PRIVATE - FUNCTIONS + */ + +/*! + \brief Span read data from a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail + */ +int sangoma_readmsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag); + + +/*! + \brief Span write data into a hw interface + \param fd socket file descriptor to span hw interface + \param hdrbuf pointer to header buffer used for misc oob data - not used + \param hdrlen size of hdr buffer - always standard 16 bytes + \param databuf pointer to span data that includes all timeslots * chunk size + \param datalen size of span data: timeslots * chunk size + \param flag selects normal (0) or oob (MSG_OOB) read queue + \return 0 = pass, non zero fail + */ +int sangoma_writemsg_hp_tdm(int fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag); + +/*! + \brief Execute a management ioctl command + \param span span object + \return 0 = pass, non zero fail + */ +int do_wanpipemon_cmd(sangoma_hptdm_span_t *span); + + +/*! + \brief Get full span hw configuration + \param span span object + \return 0 = pass, non zero fail + */ +unsigned char sangoma_get_cfg(sangoma_hptdm_span_t *span); + + +/*! + \brief Open socket to span hw interface + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hptdm_span_open(sangoma_hptdm_span_t *span); + + +/*! + \brief Read oob event from hw and push oob event up to the user. Called after select() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_oob_event(sangoma_hptdm_span_t *span); + + +/*! + \brief Multiplex span rx data and push it up to each channel + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_push_rx_data(sangoma_hptdm_span_t *span); + + +/*! + \brief Read data from hw interface and pass it up to the rxdata handler: called by run_span() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_read_event(sangoma_hptdm_span_t *span); + + +/*! + \brief Pull data from all chans and write data to hw interface: called by run_span() + \param span span object + \return 0 = pass, non zero fail + */ +int sangoma_hp_tdm_handle_write_event(sangoma_hptdm_span_t *span); + + + + +#endif + diff --git a/api/libsangoma/libsangoma.c b/api/libsangoma/libsangoma.c index 587abca..7a1c738 100644 --- a/api/libsangoma/libsangoma.c +++ b/api/libsangoma/libsangoma.c @@ -666,6 +666,7 @@ int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api) return tdm_api->wp_tdm_cmd.hw_tdm_coding; } +#ifdef WP_TDM_FEATURE_DTMF_EVENTS /*======================================================== * GET Current User Hardware DTMF Enabled/Disabled * @@ -682,6 +683,7 @@ int sangoma_tdm_get_hw_dtmf(int fd, wanpipe_tdm_api_t *tdm_api) } return tdm_api->wp_tdm_cmd.hw_dtmf; } +#endif /*======================================================== * GET Current User MTU/MRU values in bytes. @@ -953,7 +955,6 @@ 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) { @@ -1173,6 +1174,8 @@ 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; @@ -1218,7 +1221,6 @@ int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return tdm_api->wp_tdm_cmd.fe_alarms; } -#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) @@ -1231,6 +1233,7 @@ int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned return err; } +#endif /* get current Line Connection state - Connected/Disconnected */ #ifdef WP_TDM_FEATURE_LINK_STATUS @@ -1244,7 +1247,6 @@ int sangoma_tdm_get_link_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigne return err; } -#endif /* 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) @@ -1254,5 +1256,6 @@ int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned return sangoma_tdm_cmd_exec(fd, tdm_api); } +#endif #endif /* WANPIPE_TDM_API */ diff --git a/api/libsangoma/svn-commit.2.tmp b/api/libsangoma/svn-commit.2.tmp deleted file mode 100644 index 48940b9..0000000 --- a/api/libsangoma/svn-commit.2.tmp +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index 4965420..0000000 --- a/api/libsangoma/svn-commit.tmp +++ /dev/null @@ -1,5 +0,0 @@ -Added new event features ---This line, and those below, will be ignored-- - -M libsangoma.c -M libsangoma.h diff --git a/api/mpapi/x25/Makefile b/api/mpapi/x25/Makefile index 890c828..38ea428 100644 --- a/api/mpapi/x25/Makefile +++ b/api/mpapi/x25/Makefile @@ -11,12 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include APIINC = ../../include -VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../ -I../../lib -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../ -I../../lib -I$(APIINC) ####### RULES ################################################################ diff --git a/api/pos/Makefile b/api/pos/Makefile index 73708f7..c6ec227 100644 --- a/api/pos/Makefile +++ b/api/pos/Makefile @@ -11,11 +11,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(APIINC) ####### RULES ################################################################ diff --git a/api/sdlc/Makefile b/api/sdlc/Makefile index be8151c..82889cd 100644 --- a/api/sdlc/Makefile +++ b/api/sdlc/Makefile @@ -11,12 +11,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) APIINC = ./ # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(APIINC) ####### RULES ################################################################ diff --git a/api/tdmapi/Makefile b/api/tdmapi/Makefile index 5eea27b..bae316b 100644 --- a/api/tdmapi/Makefile +++ b/api/tdmapi/Makefile @@ -10,16 +10,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 -SYSINC=$(shell if [ -f ../../.sysinclude ]; then cat ../../.sysinclude; else echo ""; fi) -ifeq "$(SYSINC)" "" -SYSINC=/lib/modules/$(uname -r)/build/include -endif -VPATH = $(SYSINC) # Tools options. CFLAGS = -Wall -O2 -D$(OS_TYPE) -DWANPIPE_TDM_API -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib/hdlc -I../lib CFLAGS += -I/usr/include/wanpipe -I../../patches/kdrivers/include/ -#CFLAGS = -I$(SYSINC) TARGETS = aft_tdm_voice_api TARGETS += aft_tdm_ctrl_api diff --git a/api/x25/Makefile b/api/x25/Makefile index 2c827f4..196670e 100644 --- a/api/x25/Makefile +++ b/api/x25/Makefile @@ -10,14 +10,10 @@ OS_TYPE = __LINUX__ DEBUG = 2 -SYSINC=$(shell if [ -f ../../.sysinclude ]; then cat ../../.sysinclude; else echo ""; fi) -ifeq "$(SYSINC)" "" -SYSINC=/usr/src/linux/include -endif -APIINC = /usr/src/linux/include +APIINC = /usr/include/wanpipe # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(APIINC) ####### RULES ################################################################ diff --git a/api/x25/pthread/Makefile b/api/x25/pthread/Makefile index 0d36f53..c10f4c3 100644 --- a/api/x25/pthread/Makefile +++ b/api/x25/pthread/Makefile @@ -1,8 +1,7 @@ CC=g++ -SYSINC=/usr/src/linux/include APIINC=../../include CFLAGS=-O -I.. -D_REENTRANT -lpthread -CFLAGS1=-w -c -D_REENTRANT -D_GNUC_ -D__LINUX__ -I$(SYSINC) -I$(APIINC) +CFLAGS1=-w -c -D_REENTRANT -D_GNUC_ -D__LINUX__ -I$(APIINC) server: bitmap.o server.o $(CC) $(CFLAGS) bitmap.o server.o -o server diff --git a/api/xdlc/Makefile b/api/xdlc/Makefile index 5fc53ee..6469ff3 100644 --- a/api/xdlc/Makefile +++ b/api/xdlc/Makefile @@ -11,11 +11,9 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib ####### RULES ################################################################ diff --git a/deb_control/wanpipe.deb b/deb_control/wanpipe.deb index 25e75a0..828b264 100644 --- a/deb_control/wanpipe.deb +++ b/deb_control/wanpipe.deb @@ -1,5 +1,5 @@ Package: wanpipe -Version: 3.3.12-0 +Version: 3.3.14-0 Section: networking Priority: optional Architecture: all diff --git a/patches/kdrivers/diff b/patches/kdrivers/diff deleted file mode 100644 index c033e7b..0000000 --- a/patches/kdrivers/diff +++ /dev/null @@ -1,1013 +0,0 @@ -Only in /common/wanec/buffers: DTMF_0_ulaw.pcm -Only in /common/wanec/buffers: DTMF_1_ulaw.pcm -Only in /common/wanec/buffers: DTMF_2_ulaw.pcm -Only in /common/wanec/buffers: DTMF_3_ulaw.pcm -Only in /common/wanec/buffers: DTMF_4_ulaw.pcm -Only in /common/wanec/buffers: DTMF_5_ulaw.pcm -Only in /common/wanec/buffers: DTMF_6_ulaw.pcm -Only in /common/wanec/buffers: DTMF_7_ulaw.pcm -Only in /common/wanec/buffers: DTMF_8_ulaw.pcm -Only in /common/wanec/buffers: DTMF_9_ulaw.pcm -Only in /common/wanec/buffers: DTMF_A_ulaw.pcm -Only in /common/wanec/buffers: DTMF_B_ulaw.pcm -Only in /common/wanec/buffers: DTMF_C_ulaw.pcm -Only in /common/wanec/buffers: DTMF_D_ulaw.pcm -Only in /common/wanec/buffers: DTMF_POUND_ulaw.pcm -Only in /common/wanec/buffers: DTMF_STAR_ulaw.pcm -Only in /common/wanec/buffers: female_voice1_a_law.pcm -Only in /common/wanec/buffers: female_voice1_u_law.pcm -Only in /common/wanec/buffers: male_voice1_a_law.pcm -Only in /common/wanec/buffers: male_voice1_u_law.pcm -Only in /common/wanec/buffers: male_voice2_a_law.pcm -Only in /common/wanec/buffers: male_voice2_u_law.pcm -Only in /common/wanec/buffers: oct_phone_number_a_law.pcm -Only in /common/wanec/buffers: oct_phone_number_u_law.pcm -Only in /common/wanec/buffers: Rin_a_law.pcm -Only in /common/wanec/buffers: Rin_u_law.pcm -Only in /common/wanec/buffers: Sin_a_law.pcm -Only in /common/wanec/buffers: Sin_u_law.pcm -Only in /common/wanec/buffers: .svn -Only in /common/wanec/buffers: voice_long_a_law.pcm -Only in /common/wanec/buffers: voice_long_u_law.pcm -Only in wanec/: build.sh -Only in /common/wanec/image: OCT6116-128S.ima -Only in /common/wanec/image: OCT6116-256S.ima -Only in /common/wanec/image: OCT6116-32S.ima -Only in /common/wanec/image: OCT6116-64S.ima -Only in /common/wanec/image: OCT6116FW-01.05.01 -Only in /common/wanec/image: OCT6116FW-01.05.17 -Only in /common/wanec/image: OCT6116FW-01.05.19 -Only in /common/wanec/image: OCT6116FW-01.06.00 -Only in /common/wanec/image: OCT6116FW-01.06.01 -Only in /common/wanec/image: OCT6126FW-01.03.04 -Only in /common/wanec/image: OCT6126FW-01.05.00 -Only in /common/wanec/image: OCT6126FW-01.05.01 -Only in /common/wanec/image: .svn -Only in /common/wanec/: linux -diff -dur /common/wanec/Makefile wanec/Makefile ---- /common/wanec/Makefile 2008-06-11 18:20:34.000000000 -0400 -+++ wanec/Makefile 2008-07-23 12:50:42.000000000 -0400 -@@ -1,37 +1,57 @@ -+# Makefile for hello world kernel 2.6 module. -*-makefile-*- - # --# Makefile for the Linux network (wan) device drivers. -+# Copyright (C) 2004 Joachim Nilsson - # --# 3 Aug 2000, Christoph Hellwig --# Rewritten to use lists instead of if-statements. -+# 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 - # - --EXTRA_CFLAGS=-Werror $(EXTRA_FLAGS) --EXTRA_CFLAGS+=-DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/include/wanpipe --HOME=/common/wanec -+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= - --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 -+all: -+ $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules - --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 -+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 - --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 -+distclean: clean -+ $(RM) $(JUNK) $(OBJS) - --wanec-objs := $(OBJS) -+help: -+ $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help - --obj-m += wanec.o - -+# Indents the kernel source the way linux/Documentation/CodingStyle.txt -+# wants it to be. -+indent: -+ indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) -+ -+install: -+ $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install -+ -+endif -diff -dur /common/wanec/Makefile.Kbuild.Linux wanec/Makefile.Kbuild.Linux ---- /common/wanec/Makefile.Kbuild.Linux 2008-06-11 18:20:34.000000000 -0400 -+++ wanec/Makefile.Kbuild.Linux 2008-07-23 12:50:42.000000000 -0400 -@@ -1,37 +1,57 @@ -+# Makefile for hello world kernel 2.6 module. -*-makefile-*- - # --# Makefile for the Linux network (wan) device drivers. -+# Copyright (C) 2004 Joachim Nilsson - # --# 3 Aug 2000, Christoph Hellwig --# Rewritten to use lists instead of if-statements. -+# 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 - # - --EXTRA_CFLAGS=-Werror $(EXTRA_FLAGS) --EXTRA_CFLAGS+=-DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/include/wanpipe --HOME=/common/wanec -+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= - --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 -+all: -+ $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules - --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 -+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 - --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 -+distclean: clean -+ $(RM) $(JUNK) $(OBJS) - --wanec-objs := $(OBJS) -+help: -+ $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help - --obj-m += wanec.o - -+# Indents the kernel source the way linux/Documentation/CodingStyle.txt -+# wants it to be. -+indent: -+ indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) -+ -+install: -+ $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install -+ -+endif -Only in /common/wanec/modinfo: .svn -diff -dur /common/wanec/modules.order wanec/modules.order ---- /common/wanec/modules.order 2008-07-23 12:20:28.000000000 -0400 -+++ wanec/modules.order 2008-07-17 08:20:35.000000000 -0400 -@@ -1 +1 @@ --kernel//common/wanec/wanec.ko -+kernel//root/3.3/wanpipe/patches/kdrivers/wanec/wanec.ko -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/bt: .svn -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/largmath: .svn -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/apilib/llman: .svn -Only in /common/wanec/oct6100_api/apilib: .svn -Only in /common/wanec/oct6100_api/include/apilib: .svn -Only in /common/wanec/oct6100_api/include/oct6100api: .svn -Only in /common/wanec/oct6100_api/include/octrpc: .svn -Only in /common/wanec/oct6100_api/include: .svn -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_api: .svn -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/octdeviceapi/oct6100api/oct6100_apimi: .svn -Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api: .svn -Only in /common/wanec/oct6100_api/octdeviceapi: .svn -Only in /common/wanec/oct6100_api: .svn -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 -Only in /common/wanec/OCT612x-01.01.01/apilib/bt: octapi_bt0.o -Only in /common/wanec/OCT612x-01.01.01/apilib/bt: .octapi_bt0.o.cmd -Only in /common/wanec/OCT612x-01.01.01/apilib/bt: .svn -Only in /common/wanec/OCT612x-01.01.01/apilib/largmath: octapi_largmath.o -Only in /common/wanec/OCT612x-01.01.01/apilib/largmath: .octapi_largmath.o.cmd -Only in /common/wanec/OCT612x-01.01.01/apilib/largmath: .svn -Only in /common/wanec/OCT612x-01.01.01/apilib/llman: octapi_llman.o -Only in /common/wanec/OCT612x-01.01.01/apilib/llman: .octapi_llman.o.cmd -Only in /common/wanec/OCT612x-01.01.01/apilib/llman: .svn -Only in /common/wanec/OCT612x-01.01.01/apilib: .svn -Only in /common/wanec/OCT612x-01.01.01/include/apilib: .svn -Only in /common/wanec/OCT612x-01.01.01/include/oct6100api: .svn -Only in /common/wanec/OCT612x-01.01.01/include/octrpc: .svn -Only in /common/wanec/OCT612x-01.01.01/include: .svn -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_adpcm_chan.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_adpcm_chan.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_channel.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_channel.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_open.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_open.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_stats.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_stats.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_conf_bridge.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_conf_bridge.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_debug.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_debug.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_events.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_events.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_interrupts.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_interrupts.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_memory.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_memory.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_miscellaneous.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_miscellaneous.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_mixer.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_mixer.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_phasing_tsst.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_phasing_tsst.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_playout_buf.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_playout_buf.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_remote_debug.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_remote_debug.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_tlv.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_tlv.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_tone_detection.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_tone_detection.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_tsi_cnct.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsi_cnct.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_tsst.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsst.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: oct6100_user.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .oct6100_user.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_api: .svn -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_apimi: oct6100_mask_interrupts.o -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_apimi: .oct6100_mask_interrupts.o.cmd -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api/oct6100_apimi: .svn -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi/oct6100api: .svn -Only in /common/wanec/OCT612x-01.01.01/octdeviceapi: .svn -Only in /common/wanec/OCT612x-01.01.01: .svn -Only in /common/wanec/: .svn -Only in /common/wanec/.tmp_versions: wanec.mod -Binary files /common/wanec/wanec_cmd.o and wanec/wanec_cmd.o differ -diff -dur /common/wanec/.wanec_cmd.o.cmd wanec/.wanec_cmd.o.cmd ---- /common/wanec/.wanec_cmd.o.cmd 2008-07-23 12:14:16.000000000 -0400 -+++ wanec/.wanec_cmd.o.cmd 2008-07-23 12:50:45.000000000 -0400 -@@ -1,8 +1,8 @@ --cmd_/common/wanec/wanec_cmd.o := gcc -Wp,-MD,/common/wanec/.wanec_cmd.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -Werror -I/wanpipe/code/include/common -I/wanpipe/code/include -I/wanpipe/code/include/annexg -I/usr/include/wanpipe -I/common/wanec/oct6100_api/include/ -I/common/wanec -Iinclude -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/src/linux-2.6.26/include/linux -DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/include/wanpipe -I. -I/common/wanec/oct6100_api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/octrpc -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_cmd)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /common/wanec/.tmp_wanec_cmd.o /common/wanec/wanec_cmd.c -+cmd_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o := gcc -Wp,-MD,/root/3.3/wanpipe/patches/kdrivers/wanec/.wanec_cmd.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_X25 -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_LIP_ATM -DCONFIG_PRODUCT_WANPIPE_ATM -DCONFIG_PRODUCT_WANPIPE_MULTFR -DCONFIG_PRODUCT_WANPIPE_MULTPROT -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 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DWANPIPE_USE_I_PRIVATE -DCONFIG_WANPIPE_HWEC -I. -I/root/3.3/wanpipe/patches/kdrivers/wanec -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octrpc -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -I//usr/include/wanpipe -I/usr/include/wanpipe/oct6100_api -I/usr/include/wanpipe/oct6100_api/oct6100api -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_cmd)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /root/3.3/wanpipe/patches/kdrivers/wanec/.tmp_wanec_cmd.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.c - --deps_/common/wanec/wanec_cmd.o := \ -- /common/wanec/wanec_cmd.c \ -- /wanpipe/code/include/common/linux/wanpipe_includes.h \ -+deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o := \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.c \ -+ include/linux/wanpipe_includes.h \ - $(wildcard include/config/inet.h) \ - include/linux/init.h \ - $(wildcard include/config/modules.h) \ -@@ -664,18 +664,18 @@ - include/linux/etherdevice.h \ - include/linux/inetdevice.h \ - include/net/inet_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_defines.h \ -- /wanpipe/code/include/common/linux/wanpipe_version.h \ -- /wanpipe/code/include/linux/wanpipe_kernel.h \ -- /wanpipe/code/include/common/linux/wanpipe_abstr_types.h \ -- /wanpipe/code/include/common/linux/wanpipe.h \ -+ include/linux/wanpipe_defines.h \ -+ include/linux/wanpipe_version.h \ -+ include/linux/wanpipe_kernel.h \ -+ include/linux/wanpipe_abstr_types.h \ -+ include/linux/wanpipe.h \ - $(wildcard include/config/product/wanpipe/tdm/voice.h) \ - $(wildcard include/config/product/wanpipe/generic.h) \ - $(wildcard include/config/product/wanpipe/annexg.h) \ -- /wanpipe/code/include/common/linux/wanpipe_debug.h \ -- /wanpipe/code/include/common/linux/wanpipe_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_events.h \ -- /wanpipe/code/include/common/linux/wanpipe_cfg.h \ -+ include/linux/wanpipe_debug.h \ -+ include/linux/wanpipe_common.h \ -+ include/linux/wanpipe_events.h \ -+ include/linux/wanpipe_cfg.h \ - $(wildcard include/config/product/wanpipe/fr.h) \ - $(wildcard include/config/product/wanpipe/chdlc.h) \ - $(wildcard include/config/product/wanpipe/ppp.h) \ -@@ -729,27 +729,27 @@ - $(wildcard include/config/eth.h) \ - $(wildcard include/config/none.h) \ - $(wildcard include/config/aft/firmware/update.h) \ -- /wanpipe/code/include/common/linux/sdla_56k.h \ -- /wanpipe/code/include/common/linux/sdla_te1.h \ -+ include/linux/sdla_56k.h \ -+ include/linux/sdla_te1.h \ - $(wildcard include/config/verify.h) \ -- /wanpipe/code/include/common/linux/sdla_te3.h \ -- /wanpipe/code/include/common/linux/sdla_remora.h \ -- /wanpipe/code/include/common/linux/sdla_remora_proslic.h \ -- /wanpipe/code/include/common/linux/sdla_bri.h \ -- /wanpipe/code/include/common/linux/xhfc24succ.h \ -- /wanpipe/code/include/common/linux/sdla_serial.h \ -- /wanpipe/code/include/common/linux/sdla_front_end.h \ -- /wanpipe/code/include/common/linux/wanrouter.h \ -+ include/linux/sdla_te3.h \ -+ include/linux/sdla_remora.h \ -+ include/linux/sdla_remora_proslic.h \ -+ include/linux/sdla_bri.h \ -+ include/linux/xhfc24succ.h \ -+ include/linux/sdla_serial.h \ -+ include/linux/sdla_front_end.h \ -+ include/linux/wanrouter.h \ - include/linux/proc_fs.h \ - $(wildcard include/config/proc/devicetree.h) \ - $(wildcard include/config/proc/kcore.h) \ - include/linux/magic.h \ -- /wanpipe/code/include/common/linux/sdla_tdmv.h \ -+ include/linux/sdla_tdmv.h \ - $(wildcard include/config/product/wanpipe/tdm/voice/echomaster.h) \ - $(wildcard include/config/product/wanpipe/tdm/voice/dchan.h) \ -- /wanpipe/code/include/common/linux/sdla_tdmv_dummy.h \ -- /wanpipe/code/include/common/linux/sdlasfm.h \ -- /wanpipe/code/include/common/linux/sdladrv.h \ -+ include/linux/sdla_tdmv_dummy.h \ -+ include/linux/sdlasfm.h \ -+ include/linux/sdladrv.h \ - $(wildcard include/config/isa.h) \ - include/linux/serial.h \ - include/linux/serialP.h \ -@@ -769,51 +769,51 @@ - include/linux/cdev.h \ - include/linux/tty_ldisc.h \ - include/linux/tty_flip.h \ -- /wanpipe/code/include/linux/if_wanpipe.h \ -+ include/linux/if_wanpipe.h \ - $(wildcard include/config/id.h) \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -- /common/wanec/oct6100_api/include/octdef.h \ -- /common/wanec/oct6100_api/include/octosdependant.h \ -- /common/wanec/oct6100_api/include/octtype.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octdef.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octosdependant.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octtype.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ - $(wildcard include/config/.h) \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -- /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_version.h \ -- /common/wanec/wanec_iface.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -- /common/wanec/wanec_tones.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_version.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_tones.h \ - --/common/wanec/wanec_cmd.o: $(deps_/common/wanec/wanec_cmd.o) -+/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o: $(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o) - --$(deps_/common/wanec/wanec_cmd.o): -+$(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o): -diff -dur /common/wanec/wanec_dev.c wanec/wanec_dev.c ---- /common/wanec/wanec_dev.c 2008-07-23 12:15:37.000000000 -0400 -+++ wanec/wanec_dev.c 2008-07-17 08:20:35.000000000 -0400 -@@ -57,15 +57,11 @@ - - #ifdef WP_ECDEV_UDEV - --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) --#define class_device_destroy device_destroy --#define WP_CLASS_DEV_CREATE(class, devt, device, priv_data, name) \ -- device_create_drvdata(class, device, devt, priv_data, name) --#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) --#define WP_CLASS_DEV_CREATE(class, devt, device, priv_data, name) \ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) -+#define WP_CLASS_DEV_CREATE(class, devt, device, name) \ - class_device_create(class, NULL, devt, device, name) - #else --#define WP_CLASS_DEV_CREATE(class, devt, device, priv_data, name) \ -+#define WP_CLASS_DEV_CREATE(class, devt, device, name) \ - class_device_create(class, devt, device, name) - #endif - -@@ -140,7 +136,7 @@ - #ifdef WP_ECDEV_UDEV - WP_CLASS_DEV_CREATE( wanec_dev_class, - MKDEV(WP_ECDEV_MAJOR, 0), -- NULL,NULL, -+ NULL, - WANEC_DEV_NAME); - #endif - -Only in /common/wanec/: wanec_dev.o -Only in /common/wanec/: .wanec_dev.o.cmd -Only in wanec/: .wanec_dev.o.d -Binary files /common/wanec/wanec_iface.o and wanec/wanec_iface.o differ -diff -dur /common/wanec/.wanec_iface.o.cmd wanec/.wanec_iface.o.cmd ---- /common/wanec/.wanec_iface.o.cmd 2008-07-23 12:14:15.000000000 -0400 -+++ wanec/.wanec_iface.o.cmd 2008-07-23 12:50:43.000000000 -0400 -@@ -1,10 +1,10 @@ --cmd_/common/wanec/wanec_iface.o := gcc -Wp,-MD,/common/wanec/.wanec_iface.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -Werror -I/wanpipe/code/include/common -I/wanpipe/code/include -I/wanpipe/code/include/annexg -I/usr/include/wanpipe -I/common/wanec/oct6100_api/include/ -I/common/wanec -Iinclude -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/src/linux-2.6.26/include/linux -DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/include/wanpipe -I. -I/common/wanec/oct6100_api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/octrpc -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_iface)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /common/wanec/.tmp_wanec_iface.o /common/wanec/wanec_iface.c -+cmd_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o := gcc -Wp,-MD,/root/3.3/wanpipe/patches/kdrivers/wanec/.wanec_iface.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_X25 -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_LIP_ATM -DCONFIG_PRODUCT_WANPIPE_ATM -DCONFIG_PRODUCT_WANPIPE_MULTFR -DCONFIG_PRODUCT_WANPIPE_MULTPROT -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 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DWANPIPE_USE_I_PRIVATE -DCONFIG_WANPIPE_HWEC -I. -I/root/3.3/wanpipe/patches/kdrivers/wanec -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octrpc -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -I//usr/include/wanpipe -I/usr/include/wanpipe/oct6100_api -I/usr/include/wanpipe/oct6100_api/oct6100api -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_iface)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /root/3.3/wanpipe/patches/kdrivers/wanec/.tmp_wanec_iface.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.c - --deps_/common/wanec/wanec_iface.o := \ -- /common/wanec/wanec_iface.c \ -+deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o := \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.c \ - $(wildcard include/config/poll.h) \ - $(wildcard include/config/wanpipe/hwec.h) \ -- /wanpipe/code/include/common/linux/wanpipe_includes.h \ -+ include/linux/wanpipe_includes.h \ - $(wildcard include/config/inet.h) \ - include/linux/init.h \ - $(wildcard include/config/modules.h) \ -@@ -666,18 +666,18 @@ - include/linux/etherdevice.h \ - include/linux/inetdevice.h \ - include/net/inet_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_defines.h \ -- /wanpipe/code/include/common/linux/wanpipe_version.h \ -- /wanpipe/code/include/linux/wanpipe_kernel.h \ -- /wanpipe/code/include/common/linux/wanpipe_abstr_types.h \ -- /wanpipe/code/include/common/linux/wanpipe.h \ -+ include/linux/wanpipe_defines.h \ -+ include/linux/wanpipe_version.h \ -+ include/linux/wanpipe_kernel.h \ -+ include/linux/wanpipe_abstr_types.h \ -+ include/linux/wanpipe.h \ - $(wildcard include/config/product/wanpipe/tdm/voice.h) \ - $(wildcard include/config/product/wanpipe/generic.h) \ - $(wildcard include/config/product/wanpipe/annexg.h) \ -- /wanpipe/code/include/common/linux/wanpipe_debug.h \ -- /wanpipe/code/include/common/linux/wanpipe_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_events.h \ -- /wanpipe/code/include/common/linux/wanpipe_cfg.h \ -+ include/linux/wanpipe_debug.h \ -+ include/linux/wanpipe_common.h \ -+ include/linux/wanpipe_events.h \ -+ include/linux/wanpipe_cfg.h \ - $(wildcard include/config/product/wanpipe/fr.h) \ - $(wildcard include/config/product/wanpipe/chdlc.h) \ - $(wildcard include/config/product/wanpipe/ppp.h) \ -@@ -730,27 +730,27 @@ - $(wildcard include/config/eth.h) \ - $(wildcard include/config/none.h) \ - $(wildcard include/config/aft/firmware/update.h) \ -- /wanpipe/code/include/common/linux/sdla_56k.h \ -- /wanpipe/code/include/common/linux/sdla_te1.h \ -+ include/linux/sdla_56k.h \ -+ include/linux/sdla_te1.h \ - $(wildcard include/config/verify.h) \ -- /wanpipe/code/include/common/linux/sdla_te3.h \ -- /wanpipe/code/include/common/linux/sdla_remora.h \ -- /wanpipe/code/include/common/linux/sdla_remora_proslic.h \ -- /wanpipe/code/include/common/linux/sdla_bri.h \ -- /wanpipe/code/include/common/linux/xhfc24succ.h \ -- /wanpipe/code/include/common/linux/sdla_serial.h \ -- /wanpipe/code/include/common/linux/sdla_front_end.h \ -- /wanpipe/code/include/common/linux/wanrouter.h \ -+ include/linux/sdla_te3.h \ -+ include/linux/sdla_remora.h \ -+ include/linux/sdla_remora_proslic.h \ -+ include/linux/sdla_bri.h \ -+ include/linux/xhfc24succ.h \ -+ include/linux/sdla_serial.h \ -+ include/linux/sdla_front_end.h \ -+ include/linux/wanrouter.h \ - include/linux/proc_fs.h \ - $(wildcard include/config/proc/devicetree.h) \ - $(wildcard include/config/proc/kcore.h) \ - include/linux/magic.h \ -- /wanpipe/code/include/common/linux/sdla_tdmv.h \ -+ include/linux/sdla_tdmv.h \ - $(wildcard include/config/product/wanpipe/tdm/voice/echomaster.h) \ - $(wildcard include/config/product/wanpipe/tdm/voice/dchan.h) \ -- /wanpipe/code/include/common/linux/sdla_tdmv_dummy.h \ -- /wanpipe/code/include/common/linux/sdlasfm.h \ -- /wanpipe/code/include/common/linux/sdladrv.h \ -+ include/linux/sdla_tdmv_dummy.h \ -+ include/linux/sdlasfm.h \ -+ include/linux/sdladrv.h \ - $(wildcard include/config/isa.h) \ - include/linux/serial.h \ - include/linux/serialP.h \ -@@ -770,54 +770,54 @@ - include/linux/cdev.h \ - include/linux/tty_ldisc.h \ - include/linux/tty_flip.h \ -- /wanpipe/code/include/linux/if_wanpipe.h \ -+ include/linux/if_wanpipe.h \ - $(wildcard include/config/id.h) \ -- /wanpipe/code/include/common/linux/wanpipe_tdm_api.h \ -- /wanpipe/code/include/common/linux/wanpipe_codec_iface.h \ -- /wanpipe/code/include/common/linux/wanpipe_tdm_api_iface.h \ -- /wanpipe/code/include/common/linux/wanpipe_ec_kernel.h \ -- /common/wanec/wanec_iface_api.h \ -- /common/wanec/linux/wanec_iface.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -- /common/wanec/oct6100_api/include/octdef.h \ -- /common/wanec/oct6100_api/include/octosdependant.h \ -- /common/wanec/oct6100_api/include/octtype.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ -+ include/linux/wanpipe_tdm_api.h \ -+ include/linux/wanpipe_codec_iface.h \ -+ include/linux/wanpipe_tdm_api_iface.h \ -+ include/linux/wanpipe_ec_kernel.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface_api.h \ -+ include/linux/wanec_iface.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octdef.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octosdependant.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octtype.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ - $(wildcard include/config/.h) \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ - --/common/wanec/wanec_iface.o: $(deps_/common/wanec/wanec_iface.o) -+/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o: $(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o) - --$(deps_/common/wanec/wanec_iface.o): -+$(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o): -Only in /common/wanec/: wanec.ko -diff -dur /common/wanec/.wanec.ko.cmd wanec/.wanec.ko.cmd ---- /common/wanec/.wanec.ko.cmd 2008-07-23 12:15:53.000000000 -0400 -+++ wanec/.wanec.ko.cmd 2008-07-23 12:42:47.000000000 -0400 -@@ -1 +1 @@ --cmd_/common/wanec/wanec.ko := ld -r -m elf_i386 -o /common/wanec/wanec.ko /common/wanec/wanec.o /common/wanec/wanec.mod.o -+cmd_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec.ko := ld -m elf_i386 -m elf_i386 -r -o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec.ko /root/3.3/wanpipe/patches/kdrivers/wanec/wanec.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec.mod.o -diff -dur /common/wanec/wanec.mod.c wanec/wanec.mod.c ---- /common/wanec/wanec.mod.c 2008-07-23 12:15:53.000000000 -0400 -+++ wanec/wanec.mod.c 2008-07-17 13:15:47.000000000 -0400 -@@ -11,18 +11,46 @@ - #ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, - #endif -- .arch = MODULE_ARCH_INIT, - }; - - static const struct modversion_info ____versions[] --__used -+__attribute_used__ - __attribute__((section("__versions"))) = { -+ { 0x89e24b9c, "struct_module" }, -+ { 0x12da5bb2, "__kmalloc" }, -+ { 0x7e3f931f, "_spin_trylock" }, -+ { 0xec7bc0d, "__mod_timer" }, -+ { 0xd6ee688f, "vmalloc" }, -+ { 0x4827a016, "del_timer" }, -+ { 0xf26c4b72, "class_device_destroy" }, -+ { 0xb5513e49, "class_device_create" }, -+ { 0xab978df6, "malloc_sizes" }, -+ { 0x1bcd461f, "_spin_lock" }, -+ { 0x4e830a3e, "strnicmp" }, -+ { 0xeae3dfd6, "__const_udelay" }, -+ { 0x2fd1d81c, "vfree" }, -+ { 0x1d26aa98, "sprintf" }, -+ { 0x7d11c268, "jiffies" }, -+ { 0x1b7d4074, "printk" }, -+ { 0x5152e605, "memcmp" }, -+ { 0x2da418b5, "copy_to_user" }, -+ { 0x2e1de6c1, "class_create" }, -+ { 0x19070091, "kmem_cache_alloc" }, -+ { 0x4086729e, "register_chrdev" }, -+ { 0xd0b91f9b, "init_timer" }, -+ { 0xf6ebc03b, "net_ratelimit" }, -+ { 0x72270e35, "do_gettimeofday" }, -+ { 0x37a0cba, "kfree" }, -+ { 0x2e60bace, "memcpy" }, -+ { 0xc192d491, "unregister_chrdev" }, -+ { 0x4870cf59, "class_destroy" }, -+ { 0xf2a644fb, "copy_from_user" }, - }; - - static const char __module_depends[] --__used -+__attribute_used__ - __attribute__((section(".modinfo"))) = - "depends="; - - --MODULE_INFO(srcversion, "86B10641B83578F21469DCA"); -+MODULE_INFO(srcversion, "779B0FEF1949B05B46A7CD4"); -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 -Binary files /common/wanec/wanec_utils.o and wanec/wanec_utils.o differ -diff -dur /common/wanec/.wanec_utils.o.cmd wanec/.wanec_utils.o.cmd ---- /common/wanec/.wanec_utils.o.cmd 2008-07-23 12:14:17.000000000 -0400 -+++ wanec/.wanec_utils.o.cmd 2008-07-23 12:50:45.000000000 -0400 -@@ -1,8 +1,8 @@ --cmd_/common/wanec/wanec_utils.o := gcc -Wp,-MD,/common/wanec/.wanec_utils.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -Werror -I/wanpipe/code/include/common -I/wanpipe/code/include -I/wanpipe/code/include/annexg -I/usr/include/wanpipe -I/common/wanec/oct6100_api/include/ -I/common/wanec -Iinclude -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/src/linux-2.6.26/include/linux -DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -I/usr/include/wanpipe -I. -I/common/wanec/oct6100_api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/include -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/apilib -I/common/wanec/oct6100_api/include/octrpc -I/common/wanec/oct6100_api/include/oct6100api -I/common/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_utils)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /common/wanec/.tmp_wanec_utils.o /common/wanec/wanec_utils.c -+cmd_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o := gcc -Wp,-MD,/root/3.3/wanpipe/patches/kdrivers/wanec/.wanec_utils.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.1/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -fno-stack-protector -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-generic -Iinclude/asm-x86/mach-default -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_X25 -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_LIP_ATM -DCONFIG_PRODUCT_WANPIPE_ATM -DCONFIG_PRODUCT_WANPIPE_MULTFR -DCONFIG_PRODUCT_WANPIPE_MULTPROT -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 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DWANPIPE_USE_I_PRIVATE -DCONFIG_WANPIPE_HWEC -I. -I/root/3.3/wanpipe/patches/kdrivers/wanec -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/apilib -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octrpc -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api -I/root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY -I//usr/include/wanpipe -I/usr/include/wanpipe/oct6100_api -I/usr/include/wanpipe/oct6100_api/oct6100api -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(wanec_utils)" -D"KBUILD_MODNAME=KBUILD_STR(wanec)" -c -o /root/3.3/wanpipe/patches/kdrivers/wanec/.tmp_wanec_utils.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.c - --deps_/common/wanec/wanec_utils.o := \ -- /common/wanec/wanec_utils.c \ -- /wanpipe/code/include/common/linux/wanpipe_includes.h \ -+deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o := \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.c \ -+ include/linux/wanpipe_includes.h \ - $(wildcard include/config/inet.h) \ - include/linux/init.h \ - $(wildcard include/config/modules.h) \ -@@ -664,18 +664,18 @@ - include/linux/etherdevice.h \ - include/linux/inetdevice.h \ - include/net/inet_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_defines.h \ -- /wanpipe/code/include/common/linux/wanpipe_version.h \ -- /wanpipe/code/include/linux/wanpipe_kernel.h \ -- /wanpipe/code/include/common/linux/wanpipe_abstr_types.h \ -- /wanpipe/code/include/common/linux/wanpipe.h \ -+ include/linux/wanpipe_defines.h \ -+ include/linux/wanpipe_version.h \ -+ include/linux/wanpipe_kernel.h \ -+ include/linux/wanpipe_abstr_types.h \ -+ include/linux/wanpipe.h \ - $(wildcard include/config/product/wanpipe/tdm/voice.h) \ - $(wildcard include/config/product/wanpipe/generic.h) \ - $(wildcard include/config/product/wanpipe/annexg.h) \ -- /wanpipe/code/include/common/linux/wanpipe_debug.h \ -- /wanpipe/code/include/common/linux/wanpipe_common.h \ -- /wanpipe/code/include/common/linux/wanpipe_events.h \ -- /wanpipe/code/include/common/linux/wanpipe_cfg.h \ -+ include/linux/wanpipe_debug.h \ -+ include/linux/wanpipe_common.h \ -+ include/linux/wanpipe_events.h \ -+ include/linux/wanpipe_cfg.h \ - $(wildcard include/config/product/wanpipe/fr.h) \ - $(wildcard include/config/product/wanpipe/chdlc.h) \ - $(wildcard include/config/product/wanpipe/ppp.h) \ -@@ -729,27 +729,27 @@ - $(wildcard include/config/eth.h) \ - $(wildcard include/config/none.h) \ - $(wildcard include/config/aft/firmware/update.h) \ -- /wanpipe/code/include/common/linux/sdla_56k.h \ -- /wanpipe/code/include/common/linux/sdla_te1.h \ -+ include/linux/sdla_56k.h \ -+ include/linux/sdla_te1.h \ - $(wildcard include/config/verify.h) \ -- /wanpipe/code/include/common/linux/sdla_te3.h \ -- /wanpipe/code/include/common/linux/sdla_remora.h \ -- /wanpipe/code/include/common/linux/sdla_remora_proslic.h \ -- /wanpipe/code/include/common/linux/sdla_bri.h \ -- /wanpipe/code/include/common/linux/xhfc24succ.h \ -- /wanpipe/code/include/common/linux/sdla_serial.h \ -- /wanpipe/code/include/common/linux/sdla_front_end.h \ -- /wanpipe/code/include/common/linux/wanrouter.h \ -+ include/linux/sdla_te3.h \ -+ include/linux/sdla_remora.h \ -+ include/linux/sdla_remora_proslic.h \ -+ include/linux/sdla_bri.h \ -+ include/linux/xhfc24succ.h \ -+ include/linux/sdla_serial.h \ -+ include/linux/sdla_front_end.h \ -+ include/linux/wanrouter.h \ - include/linux/proc_fs.h \ - $(wildcard include/config/proc/devicetree.h) \ - $(wildcard include/config/proc/kcore.h) \ - include/linux/magic.h \ -- /wanpipe/code/include/common/linux/sdla_tdmv.h \ -+ include/linux/sdla_tdmv.h \ - $(wildcard include/config/product/wanpipe/tdm/voice/echomaster.h) \ - $(wildcard include/config/product/wanpipe/tdm/voice/dchan.h) \ -- /wanpipe/code/include/common/linux/sdla_tdmv_dummy.h \ -- /wanpipe/code/include/common/linux/sdlasfm.h \ -- /wanpipe/code/include/common/linux/sdladrv.h \ -+ include/linux/sdla_tdmv_dummy.h \ -+ include/linux/sdlasfm.h \ -+ include/linux/sdladrv.h \ - $(wildcard include/config/isa.h) \ - include/linux/serial.h \ - include/linux/serialP.h \ -@@ -769,53 +769,53 @@ - include/linux/cdev.h \ - include/linux/tty_ldisc.h \ - include/linux/tty_flip.h \ -- /wanpipe/code/include/linux/if_wanpipe.h \ -+ include/linux/if_wanpipe.h \ - $(wildcard include/config/id.h) \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -- /common/wanec/oct6100_api/include/octdef.h \ -- /common/wanec/oct6100_api/include/octosdependant.h \ -- /common/wanec/oct6100_api/include/octtype.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octdef.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octosdependant.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/octtype.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_defines.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_errors.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_apiud.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tlv_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_inst.h \ - $(wildcard include/config/.h) \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -- /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_version.h \ -- /common/wanec/wanec_iface.h \ -- /common/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -- /common/wanec/wanec_iface_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api_inst.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_interrupts_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tsi_cnct_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_events_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_tone_detection_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_mixer_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_conf_bridge_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_playout_buf_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_channel_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_remote_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_debug_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_open_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_chip_stats_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_adpcm_chan_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_phasing_tsst_pub.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_version.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/include/oct6100api/oct6100_api.h \ -+ /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface_api.h \ - $(wildcard include/config/poll.h) \ -- /common/wanec/linux/wanec_iface.h \ -+ include/linux/wanec_iface.h \ - --/common/wanec/wanec_utils.o: $(deps_/common/wanec/wanec_utils.o) -+/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o: $(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o) - --$(deps_/common/wanec/wanec_utils.o): -+$(deps_/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o): diff --git a/patches/kdrivers/include/sdla_adsl.h b/patches/kdrivers/include/sdla_adsl.h index 83482dd..4e76ff4 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.9 2008/01/09 17:45:29 sangoma Exp $ + * $Id: sdla_adsl.h,v 1.10 2008-02-04 18:03:54 sangoma Exp $ */ /************************************************************************* @@ -86,8 +86,8 @@ typedef struct adsl_private_area unsigned char udp_pkt_data[sizeof(wan_udp_pkt_t)]; unsigned char udp_pkt_src; unsigned char remote_eth_addr[6]; - unsigned long router_start_time; - unsigned long router_up_time; + wan_time_t router_start_time; /*unsigned long router_start_time;*/ + wan_time_t router_up_time; /*unsigned long router_up_time;*/ unsigned long trace_timeout; #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) struct ifmedia media; /* media information */ diff --git a/patches/kdrivers/include/sdla_aft_te1.h b/patches/kdrivers/include/sdla_aft_te1.h index 3a96834..041fa6e 100644 --- a/patches/kdrivers/include/sdla_aft_te1.h +++ b/patches/kdrivers/include/sdla_aft_te1.h @@ -1411,8 +1411,9 @@ enum wanpipe_aft_api_events { WP_API_EVENT_TXSIG_ONHOOK, WP_API_EVENT_ONHOOKTRANSFER, WP_API_EVENT_SETPOLARITY, - WP_API_EVENT_BRI_CHAN_LOOPBACK - + WP_API_EVENT_BRI_CHAN_LOOPBACK, + WP_API_EVENT_RING_TRIP_DETECT, + }; #define WP_API_EVENT_ENABLE 0x01 @@ -1521,6 +1522,16 @@ typedef struct { } api_tx_element_t; +typedef struct wan_if_cfg{ + unsigned char usedby; + unsigned int active_ch; + unsigned char media; + unsigned int interface_number; + unsigned int sub_media; + unsigned char hw_coding; + unsigned int chunk_sz; + sdla_fe_cfg_t fe_cfg; +}wan_if_cfg_t; #pragma pack() @@ -1762,6 +1773,8 @@ typedef struct private_area netdevice_t *annexg_dev; unsigned char label[WAN_IF_LABEL_SZ+1]; + unsigned char tdm_span_voice_api; + }private_area_t; diff --git a/patches/kdrivers/include/sdla_aft_te1.h~ b/patches/kdrivers/include/sdla_aft_te1.h~ new file mode 100644 index 0000000..d70ddd1 --- /dev/null +++ b/patches/kdrivers/include/sdla_aft_te1.h~ @@ -0,0 +1,1792 @@ +/***************************************************************************** +* 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 +#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 +#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_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 + +# 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_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 + + +/* 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_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 */ + +# 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; +} + + +/* 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 +# 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_DMACTRL_MAX_LOGIC_CH_SHIFT; + return max_logic_ch; +} + + +/*====================================================== + * PER PORT + * + * AFT Control RAM DMA Registers + * + *=====================================================*/ + +#define AFT_CONTROL_RAM_ACCESS_BASE_REG 0x1000 + + +# define AFT_CTRLRAM_LOGIC_CH_NUM_MASK 0x1F +# define AFT_CTRLRAM_LOGIC_CH_NUM_SHIFT 0 + +# define AFT_CTRLRAM_HDLC_MODE_BIT 7 +# define AFT_CTRLRAM_HDLC_CRC_SIZE_BIT 8 +# define AFT_CTRLRAM_HDLC_TXCH_RESET_BIT 9 +# define AFT_CTRLRAM_HDLC_RXCH_RESET_BIT 10 + +# define AFT_CTRLRAM_SYNC_FST_TSLOT_BIT 11 + +# define AFT_CTRLRAM_SS7_ENABLE_BIT 12 + +# define AFT_CTRLRAM_DATA_MUX_ENABLE_BIT 13 +# define AFT_CTRLRAM_SS7_FORCE_RX_BIT 14 + +# define AFT_CTRLRAM_FIFO_SIZE_SHIFT 16 +# define AFT_CTRLRAM_FIFO_SIZE_MASK 0x1F + +# define AFT_CTRLRAM_FIFO_BASE_SHIFT 24 +# define AFT_CTRLRAM_FIFO_BASE_MASK 0x1F + + +static __inline void +aft_ctrlram_set_logic_ch(u32 *reg, int logic_ch) +{ + *reg&=~(AFT_CTRLRAM_LOGIC_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< rate)) { + div=div-1; + } + *reg&=~(AFT_SERIAL_LCFG_BAUD_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 BRI_CPLD0_ECHO_RESET_BIT 0 +#define BRI_CPLD0_NETWORK_SYNC_OUT_BIT 2 + +/* -------------------------------------- */ + +#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) +{ + unsigned short new_mtu; + + if (mtu <= 128){ + new_mtu = 256; + + }else if (mtu <= 256){ + new_mtu = 512; + + }else if (mtu <= 512){ + new_mtu = 1024; + + }else if (mtu <= 1024){ + new_mtu = 2048; + + }else if (mtu <= 2048){ + new_mtu = 4096; + + }else if (mtu <= 4096){ + new_mtu = 8188; + + }else if (mtu <= 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 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; + u32 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 + * + *================================================================*/ + +#if !defined(__WINDOWS__)/* use 'wan_udphdr_aft_data'! */ +#undef wan_udphdr_data +#define wan_udphdr_data wan_udphdr_u.aft.data +#endif + +#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 +}; + +#if !defined(__WINDOWS__) +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 +}; +#endif + +#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 short len; + unsigned short pkt_error; +#if defined(__WINDOWS__) + api_header_t rx_info; +#endif +}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, + WP_API_EVENT_BRI_CHAN_LOOPBACK, + +}; + +#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 { + unsigned char repeat; + unsigned char len; + unsigned char data[8]; +} api_tx_hdlc_rpt_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_tx_hdlc_rpt_hdr_t hdlc_rpt; + api_tdm_event_hdr_t event; + unsigned char reserved[16]; + }hdr_u; +#define wp_api_tx_hdr_event_type hdr_u.event.type +#define wp_api_tx_hdr_event_mode hdr_u.event.mode +#define wp_api_tx_hdr_event_tone hdr_u.event.tone +#define wp_api_tx_hdr_event_channel hdr_u.event.channel +#define wp_api_tx_hdr_event_ohttimer hdr_u.event.ohttimer +#define wp_api_tx_hdr_event_polarity hdr_u.event.polarity + +#define wp_api_tx_hdr_hdlc_rpt_len hdr_u.hdlc_rpt.len +#define wp_api_tx_hdr_hdlc_rpt_data hdr_u.hdlc_rpt.data + +} api_tx_hdr_t; + +typedef struct { + api_tx_hdr_t api_tx_hdr; + unsigned char data[1]; +} api_tx_element_t; + + +typedef struct wan_if_cfg{ + unsigned char usedby; + unsigned int active_ch; + unsigned char media; + unsigned int interface_number; + unsigned int sub_media; + unsigned char hw_coding; + unsigned int chunk_sz; + sdla_fe_cfg_t fe_cfg; +}wan_if_cfg_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_SERIAL_MIN_FRMW_VER 0x04 + +#define AFT_MIN_ANALOG_FRMW_VER 0x05 + +#define A500_MAX_EC_CHANS 64 + +#if 0 +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; +#if defined(__FreeBSD__) + bus_dma_tag_t dma_tag; + bus_dmamap_t dmamap; + int dma_ready; +#endif +}aft_dma_chain_t; +#endif + +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 +{ +#if defined(__WINDOWS__) + /*NOTHING SHOULD BE ADDED ABOVE THIS!*/ + common_private_area_t; + wp_rx_element_t wp_rx_element; +#endif + + wanpipe_common_t common; +#if !defined(__WINDOWS__) + sdla_t *card; + char if_name[WAN_IFNAME_SZ+1]; +#endif + wan_xilinx_conf_if_t cfg; + + wan_skb_queue_t wp_tx_pending_list; + wan_skb_queue_t wp_tx_complete_list; + wan_skb_queue_t wp_tx_hdlc_rpt_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_bri_dchan_complete_list; + + u32 time_slot_map; + unsigned char num_of_time_slots; + int logic_ch_num; + + unsigned char hdlc_eng; + u32 dma_status; + unsigned char protocol; + +// struct net_device_stats if_stats; + + int tracing_enabled; /* For enabling Tracing */ + unsigned long router_start_time; + wan_ticks_t 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; + + 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; + netskb_t *tx_hdlc_rpt_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 */ +#if defined(__WINDOWS__) + aft_dma_chain_t tx_dma_chain_table; + aft_dma_chain_t rx_dma_chain_table; + unsigned char tx_chain_indx,tx_pending_chain_indx; +#else + unsigned char tx_chain_indx,tx_pending_chain_indx; + wan_dma_descr_t/*aft_dma_chain_t*/ tx_dma_chain_table[MAX_AFT_DMA_CHAINS]; + + unsigned char rx_chain_indx,rx_pending_chain_indx; + wan_dma_descr_t/*aft_dma_chain_t*/ rx_dma_chain_table[MAX_AFT_DMA_CHAINS]; +#endif + int rx_no_data_cnt; + + u32 dma_chain_status; + u32 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; + +#if defined(__FreeBSD__) +// int dma_ready; + bus_dma_tag_t dma_rx_mtag; + bus_dma_tag_t dma_tx_mtag; +#endif + struct private_area *next; + + int dchan_time_slot; + int xmtp2_api_index; + + aft_dma_swring_t swring; + + netdevice_t *annexg_dev; + unsigned char label[WAN_IF_LABEL_SZ+1]; + + unsigned char tdm_span_voice_api; + +}private_area_t; + + +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 + + +#endif diff --git a/patches/kdrivers/include/sdla_aft_te3.h b/patches/kdrivers/include/sdla_aft_te3.h index fe418d0..ef7b005 100644 --- a/patches/kdrivers/include/sdla_aft_te3.h +++ b/patches/kdrivers/include/sdla_aft_te3.h @@ -590,7 +590,7 @@ te3_enable_fractional(unsigned int *reg, unsigned int vendor) /* Length of tx data dma block * defined in 32bit words increments */ -#define TxDMA_HI_DMA_DATA_LENGTH_MASK 0x000007FF +#define TxDMA_HI_DMA_DATA_LENGTH_MASK 0x00000FFF /* DMA status bits: 11-14 * 0: Normal Operation */ @@ -705,7 +705,7 @@ te3_enable_fractional(unsigned int *reg, unsigned int vendor) /* Length of rx data dma block * defined in 32bit words increments */ -#define RxDMA_HI_DMA_DATA_LENGTH_MASK 0x000007FF +#define RxDMA_HI_DMA_DATA_LENGTH_MASK 0x00000FFF /* DMA status bits: 16-21 * 0: Normal Operation */ @@ -716,6 +716,9 @@ te3_enable_fractional(unsigned int *reg, unsigned int vendor) #define RxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT 0x00004000 +/* Enable irq if rx fifo is empty */ +# define DMA_HI_TE3_IFT_INTR_ENB_BIT 15 + /* Not used */ #define RxDMA_HI_DMA_COMMAND_BIT_SHIFT 28 @@ -1308,6 +1311,7 @@ static __inline unsigned short xilinx_dma_buf_bits(unsigned short dma_bufs) #define AFT_TX_TIMEOUT 5 #define AFT_RX_TIMEOUT 2 #define AFT_MAX_WTD_TIMEOUT 2 +#define AFT_IFT_FIMR_VER 0x11 static __inline void aft_reset_rx_watchdog(sdla_t *card) { @@ -1317,7 +1321,11 @@ static __inline void aft_reset_rx_watchdog(sdla_t *card) static __inline void aft_enable_rx_watchdog(sdla_t *card, unsigned char timeout) { aft_reset_rx_watchdog(card); - card->hw_iface.bus_write_1(card->hw,AFT_TE3_RX_WDT_CTRL_REG,timeout); + + /* Rx Watchdog is not used if firmware supports IFT interrupt */ + if (card->u.aft.firm_ver < AFT_IFT_FIMR_VER) { + card->hw_iface.bus_write_1(card->hw,AFT_TE3_RX_WDT_CTRL_REG,timeout); + } } static __inline void aft_reset_tx_watchdog(sdla_t *card) diff --git a/patches/kdrivers/include/sdla_bscstrm.h b/patches/kdrivers/include/sdla_bscstrm.h index 8d97474..6485685 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.4 2007/05/24 17:45:25 sangoma Exp $ */ +/* $Header: /home/ncorbic/svn2cvs/cvsroot/wanpipe_linux/code/include/sdla_bscstrm.h,v 1.4 2007-05-24 17:45:25 sangoma Exp $ */ /* @@ -11,10 +11,7 @@ /* - * $Log: sdla_bscstrm.h,v $ - * Revision 1.4 2007/05/24 17:45:25 sangoma - * Removed PACKED from include files - * + * $Log: not supported by cvs2svn $ * Revision 1.3 2004/09/28 21:47:30 sangoma * *** empty log message *** * diff --git a/patches/kdrivers/include/sdla_front_end.h b/patches/kdrivers/include/sdla_front_end.h index 71fedfa..46d74be 100644 --- a/patches/kdrivers/include/sdla_front_end.h +++ b/patches/kdrivers/include/sdla_front_end.h @@ -124,6 +124,7 @@ /* Alaw/Mulaw */ #define WAN_TDMV_ALAW 0x01 #define WAN_TDMV_MULAW 0x02 +#define WAN_TDMV_HDLC 0x03 #define FE_MEDIA(fe_cfg) ((fe_cfg)->media) #define FE_SUBMEDIA(fe_cfg) ((fe_cfg)->sub_media) @@ -194,6 +195,13 @@ #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; /* must be first !!! */ + unsigned char sub_media; + unsigned char chip_id; + unsigned char max_ports; + +} wan_femedia_t; typedef struct { unsigned char media; diff --git a/patches/kdrivers/include/sdla_remora.h b/patches/kdrivers/include/sdla_remora.h index f7c7a57..24cceb7 100644 --- a/patches/kdrivers/include/sdla_remora.h +++ b/patches/kdrivers/include/sdla_remora.h @@ -414,6 +414,7 @@ typedef struct sdla_remora_param { int reg_dbg_busy; int reg_dbg_ready; unsigned char reg_dbg_value; + u32 access_counter; } sdla_remora_param_t; diff --git a/patches/kdrivers/include/sdla_sdlc.h b/patches/kdrivers/include/sdla_sdlc.h index 7145614..cc5df7e 100644 --- a/patches/kdrivers/include/sdla_sdlc.h +++ b/patches/kdrivers/include/sdla_sdlc.h @@ -34,10 +34,7 @@ /* - * $Log: sdla_sdlc.h,v $ - * Revision 1.3 2004/09/28 21:47:30 sangoma - * *** empty log message *** - * + * $Log: not supported by cvs2svn $ * Revision 1.2 2004/06/07 15:53:08 sangoma * *** empty log message *** * diff --git a/patches/kdrivers/include/sdla_te1.h b/patches/kdrivers/include/sdla_te1.h index 1c20735..c1082d7 100644 --- a/patches/kdrivers/include/sdla_te1.h +++ b/patches/kdrivers/include/sdla_te1.h @@ -53,15 +53,6 @@ /************************************************************************ * DEFINES AND MACROS * ***********************************************************************/ -#if 0 -#if defined(__NetBSD__) || defined (__FreeBSD__) || defined (__OpenBSD__) -# include -#elif defined (__WINDOWS__) -# include "sdla_te1_pmc.h" -#else -# include -#endif -#endif /* ************************************************************************* @@ -69,6 +60,9 @@ ************************************************************************* */ +#define WAN_TE_CHIP_PMC 0x00 +#define WAN_TE_CHIP_DM 0x01 + #define NUM_OF_T1_CHANNELS 24 #define NUM_OF_E1_TIMESLOTS 31 #define NUM_OF_E1_CHANNELS 32 @@ -181,29 +175,23 @@ #define WAN_TE1_LIU_LLB_MODE 0x06 #define WAN_TE1_LIU_RLB_MODE 0x07 #define WAN_TE1_LIU_DLB_MODE 0x08 -#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_MODE_DECODE(mode) \ - ((mode) == WAN_TE1_LINELB_MODE) ? "Line Loopback" : \ + ((mode) == WAN_TE1_LINELB_MODE) ? "Line/Remote 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_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_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" : \ + ((mode) == WAN_TE1_LIU_DLB_MODE) ? "Dual LIU Loopback" : \ "Unknown Loopback" /* Line loopback activate/deactive modes */ -#define WAN_TE1_ACTIVATE_LB 0x01 -#define WAN_TE1_DEACTIVATE_LB 0x02 -#define WAN_TE1_LB_ACTION_DECODE(action) \ - ((action) == WAN_TE1_ACTIVATE_LB) ? "Activate" : \ - ((action) == WAN_TE1_DEACTIVATE_LB) ? "Deactivate" :\ +#define WAN_TE1_LB_ENABLE 0x01 +#define WAN_TE1_LB_DISABLE 0x02 +#define WAN_TE1_LB_ACTION_DECODE(action) \ + ((action) == WAN_TE1_LB_ENABLE) ? "Enable" : \ + ((action) == WAN_TE1_LB_DISABLE) ? "Disable" : \ "Unknown" /* T1/E1 front end Master clock source */ diff --git a/patches/kdrivers/include/sdla_te1_pmc.h b/patches/kdrivers/include/sdla_te1_pmc.h index a15ddbc..9845f67 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.4 2007/04/25 21:23:03 sangoma Exp $ + * $Id: sdla_te1_pmc.h,v 1.4 2007-04-25 21:23:03 sangoma Exp $ */ /***************************************************************************** diff --git a/patches/kdrivers/include/sdla_te3.h b/patches/kdrivers/include/sdla_te3.h index f8638ef..3e478ab 100644 --- a/patches/kdrivers/include/sdla_te3.h +++ b/patches/kdrivers/include/sdla_te3.h @@ -32,11 +32,11 @@ "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" :\ +#define WAN_TE3_LB_ENABLE 0x01 +#define WAN_TE3_LB_DISABLE 0x02 +#define WAN_TE3_LB_ACTION_DECODE(mode) \ + ((mode) == WAN_TE3_LB_ENABLE) ? "Enable" : \ + ((mode) == WAN_TE3_LB_DISABLE) ? "Disable" :\ "Unknown" #define WAN_TE3_RDEVICE_NONE 0x00 @@ -108,6 +108,8 @@ typedef struct { int dummy; u_int8_t cpld_cntrl; u_int8_t cpld_status; + u_int8_t e3_lb_ctrl; + u_int8_t e3_connect_delay; } sdla_te3_param_t; int sdla_te3_iface_init(void *p_fe_iface); diff --git a/patches/kdrivers/include/sdladrv.h b/patches/kdrivers/include/sdladrv.h index a3f75c1..8080896 100644 --- a/patches/kdrivers/include/sdladrv.h +++ b/patches/kdrivers/include/sdladrv.h @@ -93,12 +93,16 @@ ****************************************************************** */ -#define SDLADRV_MAGIC 0x414C4453L /* signature: 'SDLA' reversed */ +#define SDLADRV_MAGIC 0x414C4453L /* signature: 'SDLA' reversed */ -#define SDLADRV_MAJOR_VER 2 -#define SDLADRV_MINOR_VER 1 -#define SDLA_MAXIORANGE 4 /* maximum I/O port range */ -#define SDLA_WINDOWSIZE 0x2000 /* default dual-port memory window size */ +#define SDLADRV_MODE_WANPIPE 0 +#define SDLADRV_MODE_LIMITED 1 + +#define SDLADRV_MAJOR_VER 2 +#define SDLADRV_MINOR_VER 1 + +#define SDLA_MAXIORANGE 4 /* maximum I/O port range */ +#define SDLA_WINDOWSIZE 0x2000 /* default dual-port memory window size */ /* */ #define SDLA_MEMBASE 0x01 @@ -537,6 +541,7 @@ typedef struct sdla_hw_type_cnt /****** Function Prototypes *************************************************/ +EXTERN int sdladrv_hw_mode(int); EXTERN unsigned int sdla_hw_probe(void); EXTERN unsigned int sdla_hw_bridge_probe(void); EXTERN void *sdla_get_hw_probe (void); diff --git a/patches/kdrivers/include/sdlapci.h b/patches/kdrivers/include/sdlapci.h index c73f74a..0194b08 100644 --- a/patches/kdrivers/include/sdlapci.h +++ b/patches/kdrivers/include/sdlapci.h @@ -55,7 +55,7 @@ #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 PLX_EEPROM_VENDOR_OFF 0x7C /* 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 */ diff --git a/patches/kdrivers/include/wanpipe_abstr_types.h b/patches/kdrivers/include/wanpipe_abstr_types.h index 797800f..dd30280 100644 --- a/patches/kdrivers/include/wanpipe_abstr_types.h +++ b/patches/kdrivers/include/wanpipe_abstr_types.h @@ -26,6 +26,7 @@ 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; diff --git a/patches/kdrivers/include/wanpipe_cfg.h b/patches/kdrivers/include/wanpipe_cfg.h index 0048922..13364d7 100644 --- a/patches/kdrivers/include/wanpipe_cfg.h +++ b/patches/kdrivers/include/wanpipe_cfg.h @@ -9,6 +9,13 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include #elif defined(__LINUX__) # include # include @@ -17,6 +24,13 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include #elif defined(__WINDOWS__) # include # include @@ -27,21 +41,20 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include #else # error "No OS Defined!" #endif -/* DSL interface types */ -#define WAN_INTERFACE 0 -#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 (160) @@ -88,194 +101,10 @@ For example: a number of DLCIs. */ /********** end of sprotocol.dll definitions ************/ #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 -#define UDP_FPIPE_TYPE 0x02 -#define UDP_CPIPE_TYPE 0x03 -#define UDP_DRVSTATS_TYPE 0x04 -#define UDP_INVALID_TYPE 0x05 - -#define UDPMGMT_UDP_PROTOCOL 0x11 - -/* Command return code */ -#define WAN_CMD_OK 0 /* normal firmware return code */ -#define WAN_CMD_TIMEOUT 0xFF /* firmware command timed out */ -/* FIXME: Remove these 2 defines (use WAN_x) */ -#define CMD_OK 0 /* normal firmware return code */ -#define CMD_TIMEOUT 0xFF /* firmware command timed out */ - -/* UDP Packet Management */ -#define UDP_PKT_FRM_STACK 0x00 -#define UDP_PKT_FRM_NETWORK 0x01 - -#define WAN_UDP_FAILED_CMD 0xCF -#define WAN_UDP_INVALID_CMD 0xCE -#define WAN_UDP_TIMEOUT_CMD 0xAA -#define WAN_UDP_INVALID_NET_CMD 0xCD - -/* Maximum interrupt test counter */ -#define MAX_INTR_TEST_COUNTER 100 -#define MAX_NEW_INTR_TEST_COUNTER 5 - -/* Critical Values for RACE conditions*/ -#define CRITICAL_IN_ISR 0xA1 -#define CRITICAL_INTR_HANDLED 0xB1 - -/* Card Types */ -#define WANOPT_S50X 1 -#define WANOPT_S51X 2 -#define WANOPT_ADSL 3 -#define WANOPT_AFT 4 -#define WANOPT_AFT104 5 -#define WANOPT_AFT300 6 -#define WANOPT_AFT_ANALOG 7 -#define WANOPT_AFT108 8 -#define WANOPT_AFT_X 9 -#define WANOPT_AFT102 10 -#define WANOPT_AFT_ISDN 11 -#define WANOPT_AFT_56K 12 -#define WANOPT_AFT101 13 -#define WANOPT_AFT_SERIAL 14 - -/* - * Configuration options defines. - */ -/* general options */ -#define WANOPT_OFF 0 -#define WANOPT_ON 1 -#define WANOPT_NO 0 -#define WANOPT_YES 1 - -#define WANOPT_SIM 2 - -/* intercace options */ -#define WANOPT_RS232 0 -#define WANOPT_V35 1 - -/* data encoding options */ -#define WANOPT_NRZ 0 -#define WANOPT_NRZI 1 -#define WANOPT_FM0 2 -#define WANOPT_FM1 3 - -/* line idle option */ -#define WANOPT_IDLE_FLAG 0 -#define WANOPT_IDLE_MARK 1 - -/* link type options */ -#define WANOPT_POINTTOPOINT 0 /* RTS always active */ -#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */ - -/* clocking options */ -#define WANOPT_EXTERNAL 0 -#define WANOPT_INTERNAL 1 - -/* station options */ -#define WANOPT_DTE 0 -#define WANOPT_DCE 1 -#define WANOPT_CPE 0 -#define WANOPT_NODE 1 -#define WANOPT_SECONDARY 0 -#define WANOPT_PRIMARY 1 - -/* connection options */ -#define WANOPT_PERMANENT 0 /* DTR always active */ -#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */ -#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */ - -/* frame relay in-channel signalling */ -#define WANOPT_FR_AUTO_SIG 0 /* Automatically find singalling */ -#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */ -#define WANOPT_FR_Q933 2 /* ITU Q.933A */ -#define WANOPT_FR_LMI 3 /* LMI */ -#define WANOPT_FR_NO_LMI 4 /* NO LMI */ - -#define WANOPT_FR_EEK_OFF 0 /* Frame Relay EEK Disabled */ -#define WANOPT_FR_EEK_REQUEST 1 /* Frame Relay EEK Request Mode */ -#define WANOPT_FR_EEK_REPLY 2 /* Frame Relay EEK Reply Mode */ - -/* PPP IP Mode Options */ -#define WANOPT_PPP_STATIC 0 -#define WANOPT_PPP_HOST 1 -#define WANOPT_PPP_PEER 2 - -/* ASY Mode Options */ -#define WANOPT_ONE 1 -#define WANOPT_TWO 2 -#define WANOPT_ONE_AND_HALF 3 - -#define WANOPT_NONE 0 -#define WANOPT_ODD 1 -#define WANOPT_EVEN 2 - -/* ATM sync options */ -#define WANOPT_AUTO 0 -#define WANOPT_MANUAL 1 - -#define WANOPT_DSP_HPAD 0 -#define WANOPT_DSP_TPAD 1 - - -/* SS7 options */ -#define WANOPT_SS7_FISU 0 -#define WANOPT_SS7_LSSU 1 - -#define WANOPT_SS7_MODE_128 0 -#define WANOPT_SS7_MODE_4096 1 - -#define WANOPT_SS7_FISU_128_SZ 3 -#define WANOPT_SS7_FISU_4096_SZ 6 - - -/* CHDLC Protocol Options */ -/* DF Commmented out for now. - -#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT -#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT -#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT -*/ - - - -/* SS7 options */ -#define WANOPT_SS7_ANSI 1 -#define WANOPT_SS7_ITU 2 -#define WANOPT_SS7_NTT 3 - - -/* Port options */ -#define WANOPT_PRI 0 -#define WANOPT_SEC 1 -/* read mode */ -#define WANOPT_INTR 0 -#define WANOPT_POLL 1 - - -#define WANOPT_TTY_SYNC 0 -#define WANOPT_TTY_ASYNC 1 - -/* RBS Signalling Options */ -#define WAN_RBS_SIG_A 0x01 -#define WAN_RBS_SIG_B 0x02 -#define WAN_RBS_SIG_C 0x04 -#define WAN_RBS_SIG_D 0x08 - -/* Front End Ref Clock Options */ - -#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{ @@ -318,26 +147,6 @@ enum { NCR7000, ICL }; -/* 'state' defines */ -enum wan_states -{ - WAN_UNCONFIGURED, /* link/channel is not configured */ - WAN_DISCONNECTED, /* link/channel is disconnected */ - WAN_CONNECTING, /* connection is in progress */ - WAN_CONNECTED, /* link/channel is operational */ - WAN_LIMIT, /* for verification only */ - WAN_DUALPORT, /* for Dual Port cards */ - WAN_DISCONNECTING, - WAN_FT1_READY /* FT1 Configurator Ready */ -}; - -enum { - WAN_LOCAL_IP, - WAN_POINTOPOINT_IP, - WAN_NETMASK_IP, - WAN_BROADCAST_IP -}; - /* Standard Mode */ enum { @@ -442,73 +251,6 @@ enum { typedef char devname_t[WAN_DRVNAME_SZ+1]; -typedef enum { - RFC_MODE_BRIDGED_ETH_LLC = 0, - RFC_MODE_BRIDGED_ETH_VC = 1, - RFC_MODE_ROUTED_IP_LLC = 2, - RFC_MODE_ROUTED_IP_VC = 3, - RFC_MODE_RFC1577_ENCAP = 4, - RFC_MODE_PPP_LLC = 5, - RFC_MODE_PPP_VC = 6, - RFC_MODE_STACK_VC = 7 -} RFC_MODE; - -typedef struct wan_adsl_vcivpi -{ - unsigned short vci; - unsigned char vpi; -} wan_adsl_vcivpi_t; - - -typedef struct wan_adsl_conf -{ -#if 1 - unsigned char EncapMode; - unsigned short Vci; - unsigned short Vpi; -#else - unsigned char interface; - unsigned char Rfc1483Mode; - unsigned short Rfc1483Vci; - unsigned short Rfc1483Vpi; - unsigned char Rfc2364Mode; - unsigned short Rfc2364Vci; - unsigned short Rfc2364Vpi; -#endif - unsigned char Verbose; - unsigned short RxBufferCount; - unsigned short TxBufferCount; - - unsigned short Standard; - unsigned short Trellis; - unsigned short TxPowerAtten; - unsigned short CodingGain; - unsigned short MaxBitsPerBin; - unsigned short TxStartBin; - unsigned short TxEndBin; - unsigned short RxStartBin; - unsigned short RxEndBin; - unsigned short RxBinAdjust; - unsigned short FramingStruct; - unsigned short ExpandedExchange; - unsigned short ClockType; - unsigned short MaxDownRate; - - unsigned char atm_autocfg; - unsigned short vcivpi_num; - wan_adsl_vcivpi_t vcivpi_list[100]; - unsigned char tty_minor; - 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; - typedef struct wan_atm_conf { @@ -524,34 +266,6 @@ typedef struct wan_atm_conf }wan_atm_conf_t; -typedef struct wan_atm_conf_if -{ - unsigned char encap_mode; - unsigned short vci; - unsigned short vpi; - - unsigned char atm_oam_loopback; - unsigned char atm_oam_loopback_intr; - unsigned char atm_oam_continuity; - unsigned char atm_oam_continuity_intr; - unsigned char atm_arp; - unsigned char atm_arp_intr; - - unsigned short mtu; - - unsigned char atm_sync_mode; - unsigned short atm_sync_data; - unsigned char atm_sync_offset; - unsigned short atm_hunt_timer; - - unsigned char atm_cell_cfg; - unsigned char atm_cell_pt; - unsigned char atm_cell_clp; - unsigned char atm_cell_payload; - -}wan_atm_conf_if_t; - - typedef struct wan_bitstrm_conf{ /* Bitstreaming options */ unsigned short sync_options; @@ -610,55 +324,6 @@ typedef struct wan_x25_conf unsigned char station; } wan_x25_conf_t; -/*---------------------------------------------------------------------------- - * 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 */ - unsigned int t391; /* link integrity verification timer */ - unsigned int t392; /* polling verification timer */ - unsigned int n391; /* full status polling cycle counter */ - unsigned int n392; /* error threshold counter */ - unsigned int n393; /* monitored events counter */ - unsigned int dlci_num; /* number of DLCs (access node) */ - 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 */ -#define DLCI_NAME_LEN 20 -typedef struct wan_lip_fr_dlci -{ - unsigned short dlci; - unsigned int dlci_type; - unsigned char dlci_state; - unsigned char name[20]; - unsigned int down; - unsigned char type; -} wan_fr_dlci_t; - -typedef struct wan_lip_hdlc_if_conf -{ - /* IMPLEMENT USER CONFIG OPTIONS HERE */ - unsigned char seven_bit_hdlc; - unsigned char rx_crc_bytes; - -}wan_lip_hdlc_if_conf_t; - - typedef struct wan_rtp_conf { unsigned int rtp_ip; @@ -876,34 +541,6 @@ typedef struct lapb_parms_struct { unsigned char real_addr[WAN_ADDRESS_SZ+1]; }wan_lapb_if_conf_t; -/* used by both PPP and CHDLC in LIP layer */ -typedef struct sppp_parms_struct { - - unsigned char dynamic_ip;/* Static/Host/Peer (the same as ip_mode) */ - unsigned int local_ip; - unsigned int remote_ip; - - unsigned int pp_auth_timer; - unsigned int sppp_keepalive_timer;/* if 0, ignore keepalive for link status */ - unsigned int pp_timer; - - unsigned char pap; - unsigned char chap; - unsigned char userid[WAN_AUTHNAMELEN]; - unsigned char passwd[WAN_AUTHNAMELEN]; -#define SYSTEM_NAME_LEN 31 - unsigned char sysname[SYSTEM_NAME_LEN]; - - unsigned int gateway; - 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; typedef struct x25_parms_struct { @@ -1362,28 +999,6 @@ typedef struct wanif_conf } wanif_conf_t; -#define ATM_CELL_SIZE 53 -/* -** TYPEDEF -*/ -typedef struct atm_stats { - unsigned int rx_valid; - unsigned int rx_empty; - unsigned int rx_invalid_atm_hdr; - unsigned int rx_invalid_prot_hdr; - unsigned int rx_atm_pdu_size; - unsigned int rx_chip; - unsigned int tx_valid; - unsigned int tx_chip; - unsigned int rx_congestion; - unsigned int rx_clp; -} atm_stats_t; - -enum { - ATM_CONNECTED, - ATM_DISCONNECTED, - ATM_AIS -}; typedef struct { unsigned short fr_active; @@ -1411,42 +1026,10 @@ typedef struct wan_debug { typedef struct wanpipe_debug_msg_hdr_t { int len; - unsigned long time; + wan_time_t time; //unsigned long time; } wanpipe_kernel_msg_hdr_t; -typedef struct wplip_prot_reg -{ - int (*prot_set_state) (void *, int, unsigned char *, int); - int (*chan_set_state) (void *, int, unsigned char *, int); - int (*tx_link_down) (void *, void *); - int (*tx_chan_down) (void *, void *); - int (*rx_up) (void *, void *, int type); - unsigned int (*get_ipv4_addr)(void *, int type); - int (*set_ipv4_addr)(void *, - unsigned int, - unsigned int, - unsigned int, - unsigned int); - int (*kick_task) (void *); -#if 0 - int (*set_hw_idle_frame) (void *, unsigned char *, int); -#endif - int mtu; -}wplip_prot_reg_t; - -enum { - WPLIP_RAW, - WPLIP_IP, - WPLIP_IPV6, - WPLIP_IPX, - WPLIP_FR_ARP, - WPLIP_PPP, - WPLIP_FR, - WPLIP_ETH, - WPLIP_LAPD -}; - #define TRC_INCOMING_FRM 0x00 #define TRC_OUTGOING_FRM 0x01 #pragma pack(1) @@ -1455,8 +1038,8 @@ typedef struct { unsigned char data_avail; unsigned short real_length; unsigned short time_stamp; - unsigned long sec; - unsigned long usec; + wan_time_t sec; //unsigned long sec; + wan_suseconds_t usec; //unsigned long usec; #if defined(__WINDOWS__)/* zero-sized array does not comply to ANSI 'C' standard! */ unsigned char data[1]; #else diff --git a/patches/kdrivers/include/wanpipe_cfg_adsl.h b/patches/kdrivers/include/wanpipe_cfg_adsl.h new file mode 100644 index 0000000..f4090d4 --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_adsl.h @@ -0,0 +1,76 @@ +/************************************************************************* +* wanpipe_cfg_adsl.h * +* * +* WANPIPE(tm) Wanpipe ADSL Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_ADSL_H__ +# define __WANPIPE_CFG_ADSL_H__ + +/* DSL interface types */ +#define WAN_INTERFACE 0 +#define LAN_INTERFACE 1 + +typedef struct wan_adsl_vcivpi +{ + unsigned short vci; + unsigned char vpi; +} wan_adsl_vcivpi_t; + + +typedef struct wan_adsl_conf +{ +#if 1 + unsigned char EncapMode; + unsigned short Vci; + unsigned short Vpi; +#else + unsigned char interface; + unsigned char Rfc1483Mode; + unsigned short Rfc1483Vci; + unsigned short Rfc1483Vpi; + unsigned char Rfc2364Mode; + unsigned short Rfc2364Vci; + unsigned short Rfc2364Vpi; +#endif + unsigned char Verbose; + unsigned short RxBufferCount; + unsigned short TxBufferCount; + + unsigned short Standard; + unsigned short Trellis; + unsigned short TxPowerAtten; + unsigned short CodingGain; + unsigned short MaxBitsPerBin; + unsigned short TxStartBin; + unsigned short TxEndBin; + unsigned short RxStartBin; + unsigned short RxEndBin; + unsigned short RxBinAdjust; + unsigned short FramingStruct; + unsigned short ExpandedExchange; + unsigned short ClockType; + unsigned short MaxDownRate; + + unsigned char atm_autocfg; + unsigned short vcivpi_num; + wan_adsl_vcivpi_t vcivpi_list[100]; + unsigned char tty_minor; + 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; + + +#endif /* __WANPIPE_CFG_ADSL_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_atm.h b/patches/kdrivers/include/wanpipe_cfg_atm.h new file mode 100644 index 0000000..524a6a7 --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_atm.h @@ -0,0 +1,63 @@ +/************************************************************************* +* wanpipe_cfg_atm.h * +* * +* WANPIPE(tm) Wanpipe ATM Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_ATM_H__ +# define __WANPIPE_CFG_ATM_H__ + +#define ATM_CELL_SIZE 53 + +enum { + ATM_CONNECTED, + ATM_DISCONNECTED, + ATM_AIS +}; + +typedef struct atm_stats { + unsigned int rx_valid; + unsigned int rx_empty; + unsigned int rx_invalid_atm_hdr; + unsigned int rx_invalid_prot_hdr; + unsigned int rx_atm_pdu_size; + unsigned int rx_chip; + unsigned int tx_valid; + unsigned int tx_chip; + unsigned int rx_congestion; + unsigned int rx_clp; +} atm_stats_t; + +typedef struct wan_atm_conf_if +{ + unsigned char encap_mode; + unsigned short vci; + unsigned short vpi; + + unsigned char atm_oam_loopback; + unsigned char atm_oam_loopback_intr; + unsigned char atm_oam_continuity; + unsigned char atm_oam_continuity_intr; + unsigned char atm_arp; + unsigned char atm_arp_intr; + + unsigned short mtu; + + unsigned char atm_sync_mode; + unsigned short atm_sync_data; + unsigned char atm_sync_offset; + unsigned short atm_hunt_timer; + + unsigned char atm_cell_cfg; + unsigned char atm_cell_pt; + unsigned char atm_cell_clp; + unsigned char atm_cell_payload; + +}wan_atm_conf_if_t; + +#endif /* __WANPIPE_CFG_ATM_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_def.h b/patches/kdrivers/include/wanpipe_cfg_def.h new file mode 100644 index 0000000..bc18e4b --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_def.h @@ -0,0 +1,220 @@ +/************************************************************************* +* wanpipe_cfg_def.h * +* * +* WANPIPE(tm) Wanpipe Global configuration defines * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_DEF_H__ +# define __WANPIPE_CFG_DEF_H__ + +#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 */ +#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 */ +#endif + +typedef enum { + RFC_MODE_BRIDGED_ETH_LLC = 0, + RFC_MODE_BRIDGED_ETH_VC = 1, + RFC_MODE_ROUTED_IP_LLC = 2, + RFC_MODE_ROUTED_IP_VC = 3, + RFC_MODE_RFC1577_ENCAP = 4, + RFC_MODE_PPP_LLC = 5, + RFC_MODE_PPP_VC = 6, + RFC_MODE_STACK_VC = 7 +} RFC_MODE; + +/* 'state' defines */ +enum wan_states +{ + WAN_UNCONFIGURED, /* link/channel is not configured */ + WAN_DISCONNECTED, /* link/channel is disconnected */ + WAN_CONNECTING, /* connection is in progress */ + WAN_CONNECTED, /* link/channel is operational */ + WAN_LIMIT, /* for verification only */ + WAN_DUALPORT, /* for Dual Port cards */ + WAN_DISCONNECTING, + WAN_FT1_READY /* FT1 Configurator Ready */ +}; + +enum { + WAN_LOCAL_IP, + WAN_POINTOPOINT_IP, + WAN_NETMASK_IP, + WAN_BROADCAST_IP +}; + +/* Defines for UDP PACKET TYPE */ +#define UDP_PTPIPE_TYPE 0x01 +#define UDP_FPIPE_TYPE 0x02 +#define UDP_CPIPE_TYPE 0x03 +#define UDP_DRVSTATS_TYPE 0x04 +#define UDP_INVALID_TYPE 0x05 + +#define UDPMGMT_UDP_PROTOCOL 0x11 + +/* Command return code */ +#define WAN_CMD_OK 0 /* normal firmware return code */ +#define WAN_CMD_TIMEOUT 0xFF /* firmware command timed out */ +/* FIXME: Remove these 2 defines (use WAN_x) */ +#define CMD_OK 0 /* normal firmware return code */ +#define CMD_TIMEOUT 0xFF /* firmware command timed out */ + +/* UDP Packet Management */ +#define UDP_PKT_FRM_STACK 0x00 +#define UDP_PKT_FRM_NETWORK 0x01 + +#define WAN_UDP_FAILED_CMD 0xCF +#define WAN_UDP_INVALID_CMD 0xCE +#define WAN_UDP_TIMEOUT_CMD 0xAA +#define WAN_UDP_INVALID_NET_CMD 0xCD + +/* Maximum interrupt test counter */ +#define MAX_INTR_TEST_COUNTER 100 +#define MAX_NEW_INTR_TEST_COUNTER 5 + +/* Critical Values for RACE conditions*/ +#define CRITICAL_IN_ISR 0xA1 +#define CRITICAL_INTR_HANDLED 0xB1 + +/* Card Types */ +#define WANOPT_S50X 1 +#define WANOPT_S51X 2 +#define WANOPT_ADSL 3 +#define WANOPT_AFT 4 +#define WANOPT_AFT104 5 +#define WANOPT_AFT300 6 +#define WANOPT_AFT_ANALOG 7 +#define WANOPT_AFT108 8 +#define WANOPT_AFT_X 9 +#define WANOPT_AFT102 10 +#define WANOPT_AFT_ISDN 11 +#define WANOPT_AFT_56K 12 +#define WANOPT_AFT101 13 +#define WANOPT_AFT_SERIAL 14 + +/* + * Configuration options defines. + */ +/* general options */ +#define WANOPT_OFF 0 +#define WANOPT_ON 1 +#define WANOPT_NO 0 +#define WANOPT_YES 1 + +#define WANOPT_SIM 2 + +/* intercace options */ +#define WANOPT_RS232 0 +#define WANOPT_V35 1 + +/* data encoding options */ +#define WANOPT_NRZ 0 +#define WANOPT_NRZI 1 +#define WANOPT_FM0 2 +#define WANOPT_FM1 3 + +/* line idle option */ +#define WANOPT_IDLE_FLAG 0 +#define WANOPT_IDLE_MARK 1 + +/* link type options */ +#define WANOPT_POINTTOPOINT 0 /* RTS always active */ +#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */ + +/* clocking options */ +#define WANOPT_EXTERNAL 0 +#define WANOPT_INTERNAL 1 + +/* station options */ +#define WANOPT_DTE 0 +#define WANOPT_DCE 1 +#define WANOPT_SECONDARY 0 +#define WANOPT_PRIMARY 1 + +/* connection options */ +#define WANOPT_PERMANENT 0 /* DTR always active */ +#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */ +#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */ + +/* ASY Mode Options */ +#define WANOPT_ONE 1 +#define WANOPT_TWO 2 +#define WANOPT_ONE_AND_HALF 3 + +#define WANOPT_NONE 0 +#define WANOPT_ODD 1 +#define WANOPT_EVEN 2 + +/* ATM sync options */ +#define WANOPT_AUTO 0 +#define WANOPT_MANUAL 1 + +#define WANOPT_DSP_HPAD 0 +#define WANOPT_DSP_TPAD 1 + + +/* SS7 options */ +#define WANOPT_SS7_FISU 0 +#define WANOPT_SS7_LSSU 1 + +#define WANOPT_SS7_MODE_128 0 +#define WANOPT_SS7_MODE_4096 1 + +#define WANOPT_SS7_FISU_128_SZ 3 +#define WANOPT_SS7_FISU_4096_SZ 6 + + +/* CHDLC Protocol Options */ +/* DF Commmented out for now. + +#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT +#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT +#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT +*/ + + + +/* SS7 options */ +#define WANOPT_SS7_ANSI 1 +#define WANOPT_SS7_ITU 2 +#define WANOPT_SS7_NTT 3 + + +/* Port options */ +#define WANOPT_PRI 0 +#define WANOPT_SEC 1 +/* read mode */ +#define WANOPT_INTR 0 +#define WANOPT_POLL 1 + + +#define WANOPT_TTY_SYNC 0 +#define WANOPT_TTY_ASYNC 1 + +/* RBS Signalling Options */ +#define WAN_RBS_SIG_A 0x01 +#define WAN_RBS_SIG_B 0x02 +#define WAN_RBS_SIG_C 0x04 +#define WAN_RBS_SIG_D 0x08 + +/* Front End Ref Clock Options */ + +#define WANOPT_FE_OSC_CLOCK 0x00 +#define WANOPT_FE_LINE_CLOCK 0x01 + +#define WANOPT_NETWORK_SYNC_OUT 0x00 +#define WANOPT_NETWORK_SYNC_IN 0x01 + + + +#endif /* __WANPIPE_CFG_DEF_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_fr.h b/patches/kdrivers/include/wanpipe_cfg_fr.h new file mode 100644 index 0000000..f0d8acb --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_fr.h @@ -0,0 +1,70 @@ +/************************************************************************* +* wanpipe_cfg_fr.h * +* * +* WANPIPE(tm) Wanpipe Frame Relay Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_FR_H__ +# define __WANPIPE_CFG_FR_H__ + +/* frame relay in-channel signalling */ +#define WANOPT_FR_AUTO_SIG 0 /* Automatically find singalling */ +#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */ +#define WANOPT_FR_Q933 2 /* ITU Q.933A */ +#define WANOPT_FR_LMI 3 /* LMI */ +#define WANOPT_FR_NO_LMI 4 /* NO LMI */ + +#define WANOPT_FR_EEK_OFF 0 /* Frame Relay EEK Disabled */ +#define WANOPT_FR_EEK_REQUEST 1 /* Frame Relay EEK Request Mode */ +#define WANOPT_FR_EEK_REPLY 2 /* Frame Relay EEK Reply Mode */ + +#define WANOPT_CPE 0 +#define WANOPT_NODE 1 + +/*---------------------------------------------------------------------------- + * 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 */ + unsigned int t391; /* link integrity verification timer */ + unsigned int t392; /* polling verification timer */ + unsigned int n391; /* full status polling cycle counter */ + unsigned int n392; /* error threshold counter */ + unsigned int n393; /* monitored events counter */ + unsigned int dlci_num; /* number of DLCs (access node) */ + 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 */ +#define DLCI_NAME_LEN 20 +typedef struct wan_lip_fr_dlci +{ + unsigned short dlci; + unsigned int dlci_type; + unsigned char dlci_state; + unsigned char name[20]; + unsigned int down; + unsigned char type; +} wan_fr_dlci_t; + + +#endif /* __WANPIPE_CFG_FR_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_hdlc.h b/patches/kdrivers/include/wanpipe_cfg_hdlc.h new file mode 100644 index 0000000..eb31a37 --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_hdlc.h @@ -0,0 +1,25 @@ +/************************************************************************* +* wanpipe_cfg_hdlc.h * +* * +* WANPIPE(tm) Wanpipe HDLC Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_HDLC_H__ +# define __WANPIPE_CFG_HDLC_H__ + + +typedef struct wan_lip_hdlc_if_conf +{ + /* IMPLEMENT USER CONFIG OPTIONS HERE */ + unsigned char seven_bit_hdlc; + unsigned char rx_crc_bytes; + unsigned char lineidle; + +}wan_lip_hdlc_if_conf_t; + +#endif /* __WANPIPE_CFG_HDLC_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_lip.h b/patches/kdrivers/include/wanpipe_cfg_lip.h new file mode 100644 index 0000000..cd7a1da --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_lip.h @@ -0,0 +1,49 @@ +/************************************************************************* +* wanpipe_cfg_lip.h * +* * +* WANPIPE(tm) Wanpipe LIP Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_LIP_H__ +# define __WANPIPE_CFG_LIP_H__ + + +enum { + WPLIP_RAW, + WPLIP_IP, + WPLIP_IPV6, + WPLIP_IPX, + WPLIP_FR_ARP, + WPLIP_PPP, + WPLIP_FR, + WPLIP_ETH, + WPLIP_LAPD +}; + + +typedef struct wplip_prot_reg +{ + int (*prot_set_state) (void *, int, unsigned char *, int); + int (*chan_set_state) (void *, int, unsigned char *, int); + int (*tx_link_down) (void *, void *); + int (*tx_chan_down) (void *, void *); + int (*rx_up) (void *, void *, int type); + unsigned int (*get_ipv4_addr)(void *, int type); + int (*set_ipv4_addr)(void *, + unsigned int, + unsigned int, + unsigned int, + unsigned int); + int (*kick_task) (void *); +#if 0 + int (*set_hw_idle_frame) (void *, unsigned char *, int); +#endif + int mtu; +} wplip_prot_reg_t; + +#endif /* __WANPIPE_CFG_LIP_H__ */ diff --git a/patches/kdrivers/include/wanpipe_cfg_sppp.h b/patches/kdrivers/include/wanpipe_cfg_sppp.h new file mode 100644 index 0000000..119e978 --- /dev/null +++ b/patches/kdrivers/include/wanpipe_cfg_sppp.h @@ -0,0 +1,52 @@ +/************************************************************************* +* wanpipe_cfg_sppp.h * +* * +* WANPIPE(tm) Wanpipe SPPP Interface configuration * +* * +* Author: Alex Feldman * +*========================================================================* +* Aug 27, 2008 Alex Feldman Initial version * +* * +*************************************************************************/ + +#ifndef __WANPIPE_CFG_SPPP_H__ +# define __WANPIPE_CFG_SPPP_H__ + +#define WAN_AUTHNAMELEN 64 + +/* PPP IP Mode Options */ +#define WANOPT_PPP_STATIC 0 +#define WANOPT_PPP_HOST 1 +#define WANOPT_PPP_PEER 2 + +/* used by both PPP and CHDLC in LIP layer */ +typedef struct sppp_parms_struct { + + unsigned char dynamic_ip;/* Static/Host/Peer (the same as ip_mode) */ + unsigned int local_ip; + unsigned int remote_ip; + + unsigned int pp_auth_timer; + unsigned int sppp_keepalive_timer;/* if 0, ignore keepalive for link status */ + unsigned int pp_timer; + + unsigned char pap; + unsigned char chap; + unsigned char userid[WAN_AUTHNAMELEN]; + unsigned char passwd[WAN_AUTHNAMELEN]; +#define SYSTEM_NAME_LEN 31 + unsigned char sysname[SYSTEM_NAME_LEN]; + + unsigned int gateway; + 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; + + +#endif /* __WANPIPE_CFG_SPPP_H__ */ diff --git a/patches/kdrivers/include/wanpipe_common.h b/patches/kdrivers/include/wanpipe_common.h index 2559282..1895bf0 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.215 2008/04/16 17:23:17 sangoma Exp $ + * $Id: wanpipe_common.h,v 1.215 2008-04-16 17:23:17 sangoma Exp $ */ /**************************************************************************** @@ -583,8 +583,8 @@ void wanpipe_debugging (unsigned long data); #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); +int sdla_memdbg_push(void *mem, const char *func_name, const int line, int len); +int sdla_memdbg_pull(void *mem, const char *func_name, const int line); #endif @@ -602,8 +602,8 @@ int sdla_memdbg_pull(void *mem, char *func_name, int line); #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) +#define wan_malloc(size) __wan_malloc(size,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void* __wan_malloc(int size, const char *func_name, const int line) #else static __inline void* wan_malloc(int size) #endif @@ -630,8 +630,8 @@ static __inline void* wan_malloc(int size) } #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) +#define wan_kmalloc(size) __wan_kmalloc(size,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void* __wan_kmalloc(int size, const char *func_name, const int line) #else static __inline void* wan_kmalloc(int size) #endif @@ -661,8 +661,8 @@ 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) +#define wan_free(ptr) __wan_free(ptr,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void __wan_free(void* ptr, const char *func_name, const int line) #else static __inline void wan_free(void* ptr) #endif @@ -682,7 +682,7 @@ static __inline void wan_free(void* ptr) 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); + free(ptr, M_DEVBUF); #elif defined(__WINDOWS__) kfree(ptr); #else @@ -692,8 +692,8 @@ static __inline void wan_free(void* ptr) #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) +#define wan_vmalloc(size) __wan_vmalloc(size,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void* __wan_vmalloc(int size, const char *func_name, const int line) #else static __inline void* wan_vmalloc(int size) #endif @@ -738,8 +738,8 @@ static __inline void* wan_vmalloc(int size) #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) +#define wan_vfree(ptr) __wan_vfree(ptr,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void __wan_vfree(void* ptr, const char *func_name, const int line) #else static __inline void wan_vfree(void* ptr) #endif @@ -953,7 +953,8 @@ static __inline unsigned long wan_dma_get_paddr(void* card, wan_dma_descr_org_t* /********************** WANPIPE TIMER FUNCTION **************************/ -static __inline int wan_getcurrenttime(unsigned long *sec, unsigned long *usec) +//static __inline int wan_getcurrenttime(unsigned long *sec, unsigned long *usec) +static __inline int wan_getcurrenttime(wan_time_t *sec, wan_suseconds_t *usec) { #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct timeval tv; @@ -1189,8 +1190,8 @@ static __inline int wan_skb_len(void* skb) */ #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) +#define wan_skb_free(ptr) __wan_skb_free(ptr,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void __wan_skb_free(void* skb, const char *func_name, const int line) #else static __inline void wan_skb_free(void* skb) #endif @@ -1260,8 +1261,8 @@ static __inline int wan_skb_mark(void* pskb) ** 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) +#define wan_skb_alloc(size) __wan_skb_alloc(size,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void* __wan_skb_alloc(unsigned int len, const char *func_name, const int line) #else static __inline void* wan_skb_alloc(unsigned int len) #endif @@ -1279,37 +1280,15 @@ static __inline void* wan_skb_alloc(unsigned int len) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf *nm = NULL; -# if 1 nm = m_getcl(M_DONTWAIT,MT_DATA,M_PKTHDR); if (nm != NULL){ nm->m_data += 16; wan_skb_set_mark(nm); +# if defined(WAN_DEBUG_MEM) + sdla_memdbg_push(nm, func_name,line,sizeof(struct mbuf)); +# endif } 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; - } - 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 */ - 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){ @@ -1326,8 +1305,8 @@ static __inline void* wan_skb_alloc(unsigned int len) #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) +#define wan_skb_kalloc(size) __wan_skb_kalloc(size,(const char*)__FUNCTION__,(const int)__LINE__) +static __inline void* __wan_skb_kalloc(unsigned int len, const char *func_name, const int line) #else static __inline void* wan_skb_kalloc(unsigned int len) #endif @@ -1345,37 +1324,15 @@ static __inline void* wan_skb_kalloc(unsigned int len) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf *nm = NULL; -# if 1 nm = m_getcl(M_DONTWAIT,MT_DATA,M_PKTHDR); if (nm != NULL){ nm->m_data += 16; wan_skb_set_mark(nm); +# if defined(WAN_DEBUG_MEM) + sdla_memdbg_push(nm, func_name,line,sizeof(struct mbuf)); +# endif } 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; - } - 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 */ - 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){ @@ -1585,7 +1542,7 @@ static __inline void wan_skb_reserve(void* skb, unsigned int len) #elif defined(__WINDOWS__) skb_reserve(skb, len); #else -# error "wan_skb_free() function is not supported yet!" +# error "wan_skb_reserve() function is not supported yet!" #endif } diff --git a/patches/kdrivers/include/wanpipe_defines.h b/patches/kdrivers/include/wanpipe_defines.h index 6a0f57c..9f36032 100644 --- a/patches/kdrivers/include/wanpipe_defines.h +++ b/patches/kdrivers/include/wanpipe_defines.h @@ -167,6 +167,10 @@ typedef struct tcphdr tcphdr_t; # define w_tcp_dport dest # define w_tcp_seq seq # define w_tcp_ack_seq ack_seq + +typedef time_t wan_time_t; +typedef suseconds_t wan_suseconds_t; + #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) typedef struct ip iphdr_t; typedef struct udphdr udphdr_t; @@ -190,6 +194,13 @@ typedef struct tcphdr tcphdr_t; # define w_tcp_dport th_dport # define w_tcp_seq th_seq # define w_tcp_ack_seq th_ack +# if (__FreeBSD_version > 700000) +typedef time_t wan_time_t; +# else /* includes FreeBSD-5/6/OpenBSD/NetBSD */ +typedef long wan_time_t; +# endif +typedef suseconds_t wan_suseconds_t; + #elif defined(__WINDOWS__) /* Intel X86 */ #define __LITTLE_ENDIAN_BITFIELD @@ -226,6 +237,8 @@ struct udphdr { typedef struct iphdr iphdr_t; typedef struct udphdr udphdr_t; +typedef unsigned long wan_time_t; +typedef unsigned long wan_suseconds_t; #else # error "Unknown OS system!" #endif @@ -713,7 +726,8 @@ typedef struct wan_udp_hdr{ # define WAN_MOD_QUIESCE WAN_MOD_UNLOAD+2 # endif # define WP_DELAY DELAY -# define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg)) +# define WP_SCHEDULE(arg,name) {void*ptr=(name);tsleep(ptr,PPAUSE,(name),(arg)); } +/*# define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg))*/ # define SYSTEM_TICKS ticks # define HZ hz # define RW_LOCK_UNLOCKED 0 @@ -901,6 +915,7 @@ suitable as parameter 5 to KeWaitForSingleObject(..., TimeOut). */ #endif #if defined(__LINUX__) +/**************************** L I N U X **************************************/ typedef struct sk_buff netskb_t; typedef struct sk_buff_head wan_skb_queue_t; typedef struct timer_list wan_timer_info_t; @@ -936,6 +951,7 @@ typedef void* wan_dma_tag_t; typedef wait_queue_head_t wan_waitq_head_t; typedef void (wan_pci_ifunc_t)(void*); #elif defined(__FreeBSD__) +/**************************** F R E E B S D **********************************/ typedef struct ifnet netdevice_t; typedef struct mbuf netskb_t; # ifdef ALTQ @@ -973,6 +989,7 @@ typedef bus_dma_tag_t wan_dma_tag_t; typedef int wan_waitq_head_t; typedef void (wan_pci_ifunc_t)(void*); #elif defined(__OpenBSD__) +/**************************** O P E N B S D **********************************/ typedef struct ifnet netdevice_t; typedef struct mbuf netskb_t; # ifdef ALTQ @@ -1000,6 +1017,7 @@ typedef int wan_rwlock_t; typedef int wan_rwlock_flag_t; typedef int (wan_pci_ifunc_t)(void*); #elif defined(__NetBSD__) +/**************************** N E T B S D **********************************/ typedef struct ifnet netdevice_t; typedef struct mbuf netskb_t; # ifdef ALTQ @@ -1030,6 +1048,7 @@ typedef void (wan_pci_ifunc_t)(void*); typedef mblk_t netskb_t; #elif defined(__WINDOWS__) +/**************************** W I N D O W S **********************************/ /*********************************************************************/ diff --git a/patches/kdrivers/include/wanpipe_lip_atm_iface.h b/patches/kdrivers/include/wanpipe_lip_atm_iface.h index e3abfc5..e39321c 100644 --- a/patches/kdrivers/include/wanpipe_lip_atm_iface.h +++ b/patches/kdrivers/include/wanpipe_lip_atm_iface.h @@ -17,7 +17,7 @@ #ifndef _WANPIPE_LIP_ATM_IFACE_H #define _WANPIPE_LIP_ATM_IFACE_H -#include +//#include #define wplist_insert_dev(dev, list) do{\ dev->next = list;\ diff --git a/patches/kdrivers/include/wanpipe_version.h b/patches/kdrivers/include/wanpipe_version.h index fb891a6..daedc24 100644 --- a/patches/kdrivers/include/wanpipe_version.h +++ b/patches/kdrivers/include/wanpipe_version.h @@ -6,7 +6,7 @@ #define WANPIPE_COMPANY "Sangoma Technologies Inc" /********** LINUX **********/ -#define WANPIPE_VERSION "3.3.12" +#define WANPIPE_VERSION "3.3.14" #define WANPIPE_SUB_VERSION "0" #define WANPIPE_VERSION_BETA 1 #define WANPIPE_LITE_VERSION "1.1.1" diff --git a/patches/kdrivers/include/zapcompat.h b/patches/kdrivers/include/zapcompat.h new file mode 100644 index 0000000..34ab9a2 --- /dev/null +++ b/patches/kdrivers/include/zapcompat.h @@ -0,0 +1,147 @@ +/****************************************************************************** + * zapcompat.h + * + * Author: Moises Silva + * + * Copyright: (c) 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. + * ============================================================================ + * Sep 06, 2008 Moises Silva Initial Version + ****************************************************************************** + */ + +// Simple compat header to compile with Zaptel or DAHDI +#ifndef __ZAPCOMPAT_H +# define __ZAPCOMPAT_H + +// for DAHDI we need to map values and functions from ZT_XX to DAHDI_XX +#if defined (DAHDI_ISSUES) + +#ifdef __KERNEL__ +#include // this will bring dahdi kernel stuff plus dahdi/user.h and friends +#endif + +// defines +#define ZT_CODE DAHDI_CODE + +#define ZT_ONHOOKTRANSFER DAHDI_ONHOOKTRANSFER +#define ZT_SETPOLARITY DAHDI_SETPOLARITY +#define ZT_CHUNKSIZE DAHDI_CHUNKSIZE +#define ZT_MAX_NUM_BUFS DAHDI_MAX_NUM_BUFS + +#define ZT_EVENT_DTMFDOWN DAHDI_EVENT_DTMFDOWN +#define ZT_EVENT_DTMFUP DAHDI_EVENT_DTMFUP +#define ZT_EVENT_POLARITY DAHDI_EVENT_POLARITY + +#define ZT_TXSIG_START DAHDI_TXSIG_START +#define ZT_TXSIG_OFFHOOK DAHDI_TXSIG_OFFHOOK +#define ZT_TXSIG_ONHOOK DAHDI_TXSIG_ONHOOK +#define ZT_TXSIG_KEWL DAHDI_TXSIG_KEWL + +#define ZT_RXSIG_INITIAL DAHDI_RXSIG_INITIAL +#define ZT_RXSIG_OFFHOOK DAHDI_RXSIG_OFFHOOK +#define ZT_RXSIG_ONHOOK DAHDI_RXSIG_ONHOOK +#define ZT_RXSIG_RING DAHDI_RXSIG_RING + +#define ZT_TONEDETECT DAHDI_TONEDETECT +#define ZT_TONEDETECT_ON DAHDI_TONEDETECT_ON +#define ZT_TONEDETECT_MUTE DAHDI_TONEDETECT_MUTE + +#define ZT_IOMUX_READ DAHDI_IOMUX_READ + +#define ZT_FLAG_NOSTDTXRX DAHDI_FLAG_NOSTDTXRX +#define ZT_FLAG_HDLC DAHDI_FLAG_HDLC +#define ZT_FLAG_OPEN DAHDI_FLAG_OPEN +#define ZT_FLAG_NETDEV DAHDI_FLAG_NETDEV +#define ZT_FLAG_RBS DAHDI_FLAG_RBS +#define ZT_FLAG_RUNNING DAHDI_FLAG_RUNNING + +#define ZT_CONFIG_NOTOPEN DAHDI_CONFIG_NOTOPEN +#define ZT_CONFIG_HDB3 DAHDI_CONFIG_HDB3 +#define ZT_CONFIG_CCS DAHDI_CONFIG_CCS +#define ZT_CONFIG_CRC4 DAHDI_CONFIG_CRC4 +#define ZT_CONFIG_AMI DAHDI_CONFIG_AMI +#define ZT_CONFIG_B8ZS DAHDI_CONFIG_B8ZS +#define ZT_CONFIG_D4 DAHDI_CONFIG_D4 +#define ZT_CONFIG_ESF DAHDI_CONFIG_ESF + +#define ZT_ABIT DAHDI_ABIT +#define ZT_BBIT DAHDI_BBIT +#define ZT_CBIT DAHDI_CBIT +#define ZT_DBIT DAHDI_DBIT + +#define ZT_ALARM_NONE DAHDI_ALARM_NONE +#define ZT_ALARM_RED DAHDI_ALARM_RED +#define ZT_ALARM_YELLOW DAHDI_ALARM_YELLOW +#define ZT_ALARM_BLUE DAHDI_ALARM_BLUE +#define ZT_ALARM_NOTOPEN DAHDI_ALARM_NOTOPEN +#define ZT_ALARMSETTLE_TIME DAHDI_ALARMSETTLE_TIME +#define ZT_ALARM_RECOVER DAHDI_ALARM_RECOVER + +#define ZT_LAW_ALAW DAHDI_LAW_ALAW +#define ZT_LAW_MULAW DAHDI_LAW_MULAW + +#define ZT_MAINT_REMOTELOOP DAHDI_MAINT_REMOTELOOP +#define ZT_MAINT_NONE DAHDI_MAINT_NONE +#define ZT_MAINT_LOCALLOOP DAHDI_MAINT_LOCALLOOP +#define ZT_MAINT_LOOPUP DAHDI_MAINT_LOOPUP +#define ZT_MAINT_LOOPDOWN DAHDI_MAINT_LOOPDOWN +#define ZT_MAINT_LOOPSTOP DAHDI_MAINT_LOOPSTOP + +#define ZT_SIG_NONE DAHDI_SIG_NONE +#define ZT_SIG_CLEAR DAHDI_SIG_CLEAR +#define ZT_SIG_EM DAHDI_SIG_EM +#define ZT_SIG_EM_E1 DAHDI_SIG_EM_E1 +#define ZT_SIG_FXSLS DAHDI_SIG_FXSLS +#define ZT_SIG_FXSGS DAHDI_SIG_FXSGS +#define ZT_SIG_FXSKS DAHDI_SIG_FXSKS +#define ZT_SIG_FXOLS DAHDI_SIG_FXOLS +#define ZT_SIG_FXOGS DAHDI_SIG_FXOGS +#define ZT_SIG_FXOKS DAHDI_SIG_FXOKS +#define ZT_SIG_CAS DAHDI_SIG_CAS +#define ZT_SIG_DACS_RBS DAHDI_SIG_DACS_RBS +#define ZT_SIG_HARDHDLC DAHDI_SIG_HARDHDLC +#define ZT_SIG_HDLCRAW DAHDI_SIG_HDLCRAW +#define ZT_SIG_HDLCFCS DAHDI_SIG_HDLCFCS +#define ZT_SIG_HDLCNET DAHDI_SIG_HDLCNET +#define ZT_SIG_SLAVE DAHDI_SIG_SLAVE +#define ZT_SIG_DACS DAHDI_SIG_DACS +#define ZT_SIG_SF DAHDI_SIG_SF +#define ZT_SIG_MTP2 DAHDI_SIG_MTP2 + +#define ZT_LIN2X DAHDI_LIN2X + +// data types +#define __zt_mulaw __dahdi_mulaw +#define zt_span dahdi_span +#define zt_chan dahdi_chan +#define zt_lineconfig dahdi_lineconfig +#define zt_txsig_t enum dahdi_txsig + +// functions +#define zt_rbsbits dahdi_rbsbits +#define zt_alarm_notify dahdi_alarm_notify +#define zt_receive dahdi_receive +#define zt_transmit dahdi_transmit +#define zt_ec_chunk dahdi_ec_chunk +#define zt_register dahdi_register +#define zt_unregister dahdi_unregister +#define zt_hdlc_getbuf dahdi_hdlc_getbuf +#define zt_hooksig dahdi_hooksig +#define zt_ec_span dahdi_ec_span +#define zt_qevent_lock dahdi_qevent_lock + + +#else +// zaptel is present +// we will keep the same old names in wanpipe code, I thought of changing them +// to something like WP_XX instead of ZT_XX, but I don't see any benefit on it +// and would make this file bigger +#include +#endif + +#endif /* __ZAPCOMPAT_H */ diff --git a/patches/kdrivers/include/zapcompat_user.h b/patches/kdrivers/include/zapcompat_user.h new file mode 100644 index 0000000..ae0c0e1 --- /dev/null +++ b/patches/kdrivers/include/zapcompat_user.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * zapcompat.h + * + * Author: Moises Silva + * + * Copyright: (c) 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. + * ============================================================================ + * Sep 06, 2008 Moises Silva Initial Version + ****************************************************************************** + */ + +// Simple compat header to compile with Zaptel or DAHDI +#ifndef __ZAPCOMPAT_H +# define __ZAPCOMPAT_H + +// for DAHDI we need to map values and functions from user ZT_XX to DAHDI_XX +#if defined (DAHDI_ISSUES) +#include +#include + +#define ZT_LAW_MULAW DAHDI_LAW_MULAW +#define ZT_LAW_ALAW DAHDI_LAW_ALAW +#define ZT_LAW_DEFAULT DAHDI_LAW_DEFAULT + +#define ZT_MAX_SPANS DAHDI_MAX_SPANS +#define ZT_MAX_CHANNELS DAHDI_MAX_CHANNELS + +#define ZT_SIG_EM DAHDI_SIG_EM +#define ZT_SIG_EM_E1 DAHDI_SIG_EM_E1 +#define ZT_SIG_FXSLS DAHDI_SIG_FXSLS +#define ZT_SIG_FXSGS DAHDI_SIG_FXSGS +#define ZT_SIG_FXSKS DAHDI_SIG_FXSKS +#define ZT_SIG_FXOLS DAHDI_SIG_FXOLS +#define ZT_SIG_FXOGS DAHDI_SIG_FXOGS +#define ZT_SIG_FXOKS DAHDI_SIG_FXOKS +#define ZT_SIG_CAS DAHDI_SIG_CAS +#define ZT_SIG_DACS DAHDI_SIG_DACS +#define __ZT_SIG_DACS __DAHDI_SIG_DACS +#define ZT_SIG_DACS_RBS DAHDI_SIG_DACS_RBS +#define ZT_SIG_CLEAR DAHDI_SIG_CLEAR +#define ZT_SIG_SLAVE DAHDI_SIG_SLAVE +#define ZT_SIG_HDLCRAW DAHDI_SIG_HDLCRAW +#define ZT_SIG_HDLCFCS DAHDI_SIG_HDLCFCS +#define ZT_SIG_HDLCNET DAHDI_SIG_HDLCNET +#define ZT_SIG_MTP2 DAHDI_SIG_MPT2 + +#define ZT_ABIT DAHDI_ABIT +#define ZT_BBIT DAHDI_BBIT +#define ZT_CBIT DAHDI_CBIT +#define ZT_DBIT DAHDI_DBIT + +#define ZT_CONFIG_NOTOPEN DAHDI_CONFIG_NOTOPEN +#define ZT_CONFIG_HDB3 DAHDI_CONFIG_HDB3 +#define ZT_CONFIG_CCS DAHDI_CONFIG_CCS +#define ZT_CONFIG_CRC4 DAHDI_CONFIG_CRC4 +#define ZT_CONFIG_AMI DAHDI_CONFIG_AMI +#define ZT_CONFIG_B8ZS DAHDI_CONFIG_B8ZS +#define ZT_CONFIG_D4 DAHDI_CONFIG_D4 +#define ZT_CONFIG_ESF DAHDI_CONFIG_ESF + +// data types +#define zt_lineconfig dahdi_lineconfig +#define zt_dynamic_span dahdi_dynamic_span +#define zt_chanconfig dahdi_chanconfig + +#else +// zaptel is present +// we will keep the same old names in wanpipe code, I thought of changing them +// to something like WP_XX instead of ZT_XX, but I don't see any benefit on it +// and would make this file bigger +#include +#endif + +#endif /* __ZAPCOMPAT_H */ diff --git a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_eng.c b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_eng.c index 500a116..a29b3da 100644 --- a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_eng.c +++ b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_eng.c @@ -211,9 +211,9 @@ int wanpipe_hdlc_encode(wanpipe_hdlc_engine_t *hdlc_eng, encode_byte(chan,&chan->tx_flag_idle,2); encode_byte(chan,&chan->tx_flag_idle,2); encode_byte(chan,&chan->tx_flag_idle,2); - encode_byte(chan,&chan->tx_flag_idle,2); - encode_byte(chan,&chan->tx_flag_idle,2); #endif + encode_byte(chan,&chan->tx_flag_idle,2); + encode_byte(chan,&chan->tx_flag_idle,2); encode_byte(chan,&chan->tx_flag_offset_data,2); if (!hdlc_eng->seven_bit_hdlc || chan->tx_flag_offset < 5){ diff --git a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_iface.c b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_iface.c index a7811da..88aa542 100644 --- a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_iface.c +++ b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_hdlc_iface.c @@ -260,7 +260,11 @@ static int wp_lip_tx_idle(wp_lip_hdlc_t *prot, void * p_rx_skb, int tx_out) return 0; } - wpabs_memset(data, prot->next_idle, len); + if (prot->cfg.lineidle == WANOPT_IDLE_MARK) { + wpabs_memset(data, 0xFF, len); + } else { + wpabs_memset(data, prot->next_idle, len); + } err=prot->reg.tx_chan_down(prot->dev,p_rx_skb); if (err) { diff --git a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_lip_hdlc.h b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_lip_hdlc.h index 194d400..6a39628 100644 --- a/patches/kdrivers/src/lip/lip_hdlc/wanpipe_lip_hdlc.h +++ b/patches/kdrivers/src/lip/lip_hdlc/wanpipe_lip_hdlc.h @@ -5,7 +5,9 @@ #include "stddef.h" #include "linux/types.h" #include "wanpipe_abstr.h" -#include "wanpipe_cfg.h" +#include "wanpipe_cfg_def.h" +#include "wanpipe_cfg_hdlc.h" +#include "wanpipe_cfg_lip.h" /* This is the shared header between the LIP diff --git a/patches/kdrivers/src/lip/wanpipe_lip_bh.c b/patches/kdrivers/src/lip/wanpipe_lip_bh.c index fc39b20..c7177d9 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_bh.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c @@ -105,8 +105,6 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) 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); @@ -114,8 +112,7 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) goto wplip_bh_transmit_exit; } - 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; + /* Removed Tx statistics from here so that idle frames do not get counted */ } diff --git a/patches/kdrivers/src/lip/wanpipe_lip_iface.c b/patches/kdrivers/src/lip/wanpipe_lip_iface.c index c95c2a6..ed9e4f0 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_iface.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c @@ -72,6 +72,154 @@ extern void unregister_wanpipe_lip_protocol (void); * Global Module Interface Functions */ +# if defined(WAN_DEBUG_MEM) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +# define EXPORT_SYMBOL(symbol) +#endif +static int wan_debug_mem; + +static wan_spinlock_t 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; + +static int wanpipe_lip_memdbg_init(void); +static int wanpipe_lip_memdbg_free(void); + +static int wanpipe_lip_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, const char *func_name, const int line, int len) +{ + sdla_memdbg_el_t *sdla_mem_el = NULL; + wan_smp_flag_t flags; + +#if defined(__LINUX__) + sdla_mem_el = kmalloc(sizeof(sdla_memdbg_el_t),GFP_ATOMIC); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + sdla_mem_el = malloc(sizeof(sdla_memdbg_el_t), M_DEVBUF, M_NOWAIT); +#endif + 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, const char *func_name, const 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); +#if defined(__LINUX__) + kfree(sdla_mem_el); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(sdla_mem_el, M_DEVBUF); +#endif + 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); + +static int wanpipe_lip_memdbg_free(void) +{ + sdla_memdbg_el_t *sdla_mem_el; + int total=0; + + DEBUG_EVENT("wanpipe_lip: 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); +#if defined(__LINUX__) + kfree(tmp); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(tmp, M_DEVBUF); +#endif + } + + DEBUG_EVENT("=====================END==================================\n"); + DEBUG_EVENT("wanpipe_lip: Memory Still Allocated=%i Leaks Found=%i Missing=%i\n", + wan_debug_mem,total,wan_debug_mem-total); + + return 0; +} + +# endif + + /*============================================================= * wplip_register @@ -1576,6 +1724,9 @@ int wanpipe_lip_init(void *arg) wplip_reg_t reg; int err; +#if defined(WAN_DEBUG_MEM) + wanpipe_lip_memdbg_init(); +#endif if (WANPIPE_VERSION_BETA){ DEBUG_EVENT("%s Beta %s.%s %s\n", wplip_fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION,wplip_copyright); @@ -1627,6 +1778,10 @@ int wanpipe_lip_exit (void *arg) unregister_wanpipe_lip_protocol(); wplip_free_prot(); +#if defined(WAN_DEBUG_MEM) + wanpipe_lip_memdbg_free(); +#endif + DEBUG_EVENT("WANPIPE L.I.P: Unloaded\n"); return 0; } diff --git a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c index b50c93a..a6122d3 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c @@ -211,7 +211,8 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct wplip_dev_t *lip_dev =wplip_get_lipdev(dev); wan_api_tx_hdr_t *api_tx_hdr =NULL; int err, type; - + int len = skb?wan_skb_len(skb):0; + if (!lip_dev || !lip_dev->lip_link){ WAN_NETIF_STOP_QUEUE(dev); return 1; @@ -280,6 +281,10 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct /* Packet queued ok */ wan_netif_set_ticks(dev, SYSTEM_TICKS); WAN_NETIF_START_QUEUE(dev); + + 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; + err=0; break; diff --git a/patches/kdrivers/src/net/.aft_a104.c.swp b/patches/kdrivers/src/net/.aft_a104.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..9d7df580e949273bc261c2b14a35e5a9f8b60cdf GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/patches/kdrivers/src/net/Makefile b/patches/kdrivers/src/net/Makefile index 5c15a59..33cb8b5 100644 --- a/patches/kdrivers/src/net/Makefile +++ b/patches/kdrivers/src/net/Makefile @@ -18,7 +18,7 @@ CONFIG_WANPIPE_MULTPPP=n EXTRA_CFLAGS=$(EXTRA_FLAGS) 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_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DCONFIG_PRODUCT_WANPIPE_AFT_56K 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 -DCONFIG_PRODUCT_WANPIPE_AFT_RM diff --git a/patches/kdrivers/src/net/Module.symvers b/patches/kdrivers/src/net/Module.symvers deleted file mode 100644 index 8303ce8..0000000 --- a/patches/kdrivers/src/net/Module.symvers +++ /dev/null @@ -1,56 +0,0 @@ -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 -0xa9af1046 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 -0x6d24aad6 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 -0xbff734f9 register_wan_device /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x8195b56e wanrouter_proc_add_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x90a9f616 wp_sppp_detach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0xc9b2c3fb wp_sppp_attach /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 -0x7886518f 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 -0xfd74fadb wan_set_ip_address /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 -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 -0x2f21a326 unregister_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x6dfe07e3 wanrouter_proc_delete_interface /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 -0x00461a2f 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_analog.c b/patches/kdrivers/src/net/aft_analog.c index f317c70..550fd52 100644 --- a/patches/kdrivers/src/net/aft_analog.c +++ b/patches/kdrivers/src/net/aft_analog.c @@ -352,6 +352,10 @@ int aft_analog_global_chip_config(sdla_t *card) 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,®); + + /* Do not allow front end interrupt to start */ + card->fe_no_intr=1; + #if 0 wan_set_bit(AFT_CHIPCFG_SPI_SLOW_BIT,®); #endif @@ -379,9 +383,6 @@ int aft_analog_global_chip_config(sdla_t *card) DEBUG_EVENT("%s: Remora config done!\n",card->devname); - /* Enable global front end interrupt */ - __aft_fe_intr_ctrl(card, 1); - return 0; } diff --git a/patches/kdrivers/src/net/diff b/patches/kdrivers/src/net/diff index fac26da..0fb3533 100644 --- a/patches/kdrivers/src/net/diff +++ b/patches/kdrivers/src/net/diff @@ -1,1543 +1,193 @@ ---- /root/3.2/wanpipe/patches/kdrivers/src/net/wanpipe_tdm_api.c 2008-07-08 13:13:58.000000000 -0400 -+++ wanpipe_tdm_api.c 2008-07-08 15:09:50.000000000 -0400 -@@ -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 -@@ -13,7 +13,10 @@ - * 2 of the License, or (at your option) any later version. - * ============================================================================ - * Oct 04, 2005 Nenad Corbic Initial version. --* Jul 27, 2006 David Rokhvarg Ported to Windows. -+* Jul 27, 2006 David Rokhvarg -+* Ported to Windows. -+* Mar 10, 2008 David Rokhvarg -+* Added BRI LoopBack control. - *****************************************************************************/ +--- sdla_remora.c 2008-09-24 18:16:59.000000000 -0400 ++++ /tmp/sdla_remora.c 2008-10-01 18:05:35.000000000 -0400 +@@ -98,8 +98,7 @@ + #define WP_RM_POLL_EVENT_TIMER 10 + #define WP_RM_POLL_TONE_TIMER 5000 + #define WP_RM_POLL_RING_TIMER 10000 +-#define FXO_LINK_DEBOUNCE 1800 +-/* FXO_LINK_DEBOUNCE value changed from 200 to 1800 */ ++#define FXO_LINK_DEBOUNCE 200 + enum { + WP_RM_POLL_TONE_DIAL = 1, + WP_RM_POLL_TONE_BUSY, +@@ -401,6 +400,8 @@ - #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -@@ -24,14 +27,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 +41,10 @@ - ); - - #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 + static int ohdebounce = 64; + /* ohdebounce change from 128 to 64 */ ++//int intcount=0; /* intcount to call check_hook for one module per interrupt*/ + -+#define BUILD_TDMV_API - #elif defined(__LINUX__) - # include -@@ -52,7 +55,6 @@ - # include - #endif - --#include - - /*============================================================== - Defines -@@ -62,8 +64,8 @@ - #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 +86,12 @@ - #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 +153,7 @@ - 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,7 +229,6 @@ - wake_up_interruptible(&tdm_api->poll_wait); + /******************************************************************************* + ** FUNCTION PROTOTYPES +@@ -1557,6 +1558,7 @@ + fe->rm_param.module_map = 0; + fe->rm_param.intcount = 0; + fe->rm_param.last_watchdog = SYSTEM_TICKS; ++ fe->rm_param.access_counter = 0; + if (wp_remora_opermode(fe)){ + return -EINVAL; } +@@ -1763,7 +1765,7 @@ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + DEBUG_EVENT("%s: Running post initialization...\n", fe->name); +- return wp_remora_add_timer(fe, WP_RM_POLL_TIMER); ++ return wp_remora_add_timer(fe, HZ); } --#endif - static struct cdev wptdm_cdev = { - #ifndef LINUX_FEAT_2624 -@@ -228,7 +236,7 @@ - #endif - .owner = THIS_MODULE, - }; -- -+#endif - - static int wp_tdmapi_reg_globals(void) + /****************************************************************************** +@@ -2022,7 +2024,7 @@ + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); + DEBUG_EVENT("%s: WARNING: No FE events in a queue!\n", + fe->name); +- wp_remora_add_timer(fe, WP_RM_POLL_TIMER); ++ wp_remora_add_timer(fe, HZ); + return 0; + } + fe_event = WAN_LIST_FIRST(&fe->event); +@@ -2875,9 +2877,9 @@ + 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.ringdebounce += (WP_RM_CHUNKSIZE * 4); +- if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce >= WP_RM_CHUNKSIZE * 128) { +- ++ fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); ++ 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; + +@@ -2893,12 +2895,13 @@ + } + } + +- fe->rm_param.mod[mod_no].u.fxo.ringdebounce = WP_RM_CHUNKSIZE * 128; ++ 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 * 1; ++ ++ fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; + if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce <= 0) { + if (fe->rm_param.mod[mod_no].u.fxo.wasringing) { + +@@ -3107,7 +3110,7 @@ + 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 * 4); ++ fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); + 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; +@@ -3125,7 +3128,7 @@ + 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 * 2; ++ fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; + 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; +@@ -3410,7 +3413,8 @@ { -@@ -236,8 +244,8 @@ + int mod_no; - 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 -@@ -324,17 +332,25 @@ - - if (tdm_api->hdlc_framing) { - -- tdm_api->cfg.hw_mtu_mru =1500; -+ if (IS_BRI_CARD(card)) { -+ tdm_api->cfg.hw_mtu_mru =300; -+ tdm_api->cfg.usr_mtu_mru =300; -+ } else { -+ tdm_api->cfg.hw_mtu_mru =1500; -+ tdm_api->cfg.usr_mtu_mru =1500; +- ++ //intcount++; ++ fe->rm_param.access_counter++; + + 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)) { +@@ -3450,8 +3454,7 @@ + } + } + } +- +- } else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO) { + } -+ - tdm_api->cfg.usr_period =0; - tdm_api->cfg.tdm_codec =WP_NONE; - tdm_api->cfg.power_level =0; - tdm_api->cfg.rx_disable =0; - tdm_api->cfg.tx_disable =0; -- tdm_api->cfg.usr_mtu_mru =1500; - 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 +389,27 @@ - } - 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 +487,15 @@ - 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 +555,7 @@ - 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 +604,9 @@ - - 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,6 +777,7 @@ - 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); -@@ -760,7 +786,10 @@ - - skb_len=WP_TDM_API_MAX_LEN+sizeof(wp_tdm_api_tx_hdr_t); - } -- -+ -+ 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 +1039,7 @@ - !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 +1068,11 @@ - - 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 +1093,32 @@ - #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); -+ tdm_api->tdm_chan, -+ &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 +1126,8 @@ - #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 +1137,40 @@ - 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 +1187,7 @@ - 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 +1220,10 @@ - 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: -+ case SIOC_WP_TDM_GET_FE_STATUS: -+ case SIOC_WP_TDM_SET_FE_STATUS: -+ 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 +1334,6 @@ - } - 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; + if (wr->mod[x].fxo.echotune){ +@@ -3476,23 +3479,29 @@ + wr->mod[x].fxo.echotune = 0; + } + #endif +- /*FIXME This code is called more often than in zaptel mode. This is WRONG !!! +- Fix by calling this code one module per interrupt ! */ - -- 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 +1355,33 @@ - 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_HW_DTMF: -+ if (card->wandev.ec_enable && card->u.aft.tdmv_hw_dtmf == WANOPT_YES) { -+ usr_tdm_api.hw_dtmf = WANOPT_YES; -+ } else { -+ usr_tdm_api.hw_dtmf = WANOPT_NO; -+ } -+ break; - - case SIOC_WP_TDM_GET_STATS: - memcpy(&usr_tdm_api.stats,&tdm_api->cfg.stats,sizeof(tdm_api->cfg.stats)); -@@ -1357,6 +1392,7 @@ - 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 +1401,62 @@ - 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; -- 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; -+ 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_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; -+ -+ 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; -+ -+ 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 +1464,7 @@ - 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 +1477,6 @@ - if (usr_tdm_api.data_len && utdmapi->data) { - if (usr_tdm_api.data_len != 256) { - err=-EINVAL; +- if (fe->fe_cfg.cfg.remora.rm_mode == WAN_RM_TAPPING) { +- wp_remora_voicedaa_tapper_check_hook(fe, mod_no); +- } else { +- wp_remora_voicedaa_check_hook(fe, mod_no); +- } - - break; - } - -@@ -1665,7 +1491,8 @@ - } - - #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 +1534,8 @@ - } - - #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 +1585,237 @@ - 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; -+ -+ case WP_TDMAPI_EVENT_BRI_CHAN_LOOPBACK: -+ event_ctrl.type = WAN_EVENT_BRI_CHAN_LOOPBACK; -+ event_ctrl.channel = tdm_event->channel; -+ -+ 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; -+ } -+ -+ DEBUG_TDMAPI("%s: BRI_BCHAN_LOOPBACK: %s for channel %d!\n", -+ tdm_api->name, -+ (event_ctrl.mode == WAN_EVENT_ENABLE ? "Enable" : "Disable"), -+ event_ctrl.channel); -+ break; -+ -+ default: -+ DEBUG_EVENT("%s: Unknown TDM API Event Type %02X!\n", -+ tdm_api->name, -+ tdm_event->type); -+ return -EINVAL; -+ } -+ -+ -+ switch(tdm_event->wp_tdm_api_event_type){ -+ case WP_TDMAPI_EVENT_BRI_CHAN_LOOPBACK: -+ /* BRI FE access must be locked */ -+ { -+ sdla_t *card = (sdla_t*)tdm_api->card; -+ wan_smp_flag_t smp_flags1; -+ int rc; -+ -+ card->hw_iface.hw_lock(card->hw,&smp_flags1); -+ rc = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); -+ card->hw_iface.hw_unlock(card->hw,&smp_flags1); -+ return rc; -+ } -+ break; -+ -+ default: -+ 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 +2003,8 @@ - return -EBUSY; } -+ DEBUG_TDMAPI("%s: TDM API RX HDLC FRAME %i\n",tdm_api->name, wan_skb_len(skb)); ++ mod_no = fe->rm_param.access_counter % MAX_REMORA_MODULES; ++ ++ if ( mod_no < fe->rm_param.max_fe_channels ) {/* sanity check for valid mod_no */ ++ if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { ++ if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO) { ++ if (fe->fe_cfg.cfg.remora.rm_mode == WAN_RM_TAPPING) { ++ wp_remora_voicedaa_tapper_check_hook(fe, mod_no); ++ } else { ++ wp_remora_voicedaa_check_hook(fe, mod_no); ++ } ++ ++ } ++ ++ } ++ } + - wan_skb_queue_tail(&tdm_api->wp_rx_list,skb); - wp_wakeup_tdmapi(tdm_api); - tdm_api->cfg.stats.rx_packets++; -@@ -1960,7 +2018,10 @@ - int i = 0; - - #if defined(__WINDOWS__) -- if(fe_chan >= MAX_TDM_API_CHANNELS){ + #if defined(AFT_RM_VIRTUAL_INTR_SUPPORT) + -+ 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; -@@ -1973,16 +2034,28 @@ - } - return tdm_api; - #else -+ int tmp_fe_chan; -+ tmp_fe_chan = fe_chan; -+ - for(i = 0; i < WP_TDMAPI_HASH_SZ; i++){ - tdm_api = wp_tdmapi_hash[i]; - - if (tdm_api == NULL || tdm_api->card != card){ - continue; + 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); } -- if (wan_test_bit(fe_chan, &tdm_api->active_ch)){ -+ -+ if (IS_BRI_CARD(card)) { -+ tmp_fe_chan = (2*(tdm_api->tdm_span-1))+fe_chan; -+ } +@@ -3820,7 +3829,7 @@ + + WAN_ASSERT(fe->card == NULL); + card = fe->card; +- + -+ if (wan_test_bit(tmp_fe_chan, &tdm_api->active_ch)){ - return tdm_api; + status = READ_RM_REG(mod_no, 4); + if (status & 0x80){ + u_int8_t mode; +@@ -3870,15 +3879,17 @@ + static int wp_remora_intr(sdla_fe_t *fe) + { + int mod_no = 0; +- +- for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ +- if (!wan_test_bit(mod_no, &fe->rm_param.module_map)) { +- continue; +- } +- if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ +- wp_remora_intr_fxs(fe, mod_no); +- }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ +- wp_remora_intr_fxo(fe, mod_no); ++ ++ /* calling per module per interupt */ ++ mod_no = fe->rm_param.access_counter % MAX_REMORA_MODULES; ++ ++ if ( mod_no < fe->rm_param.max_fe_channels ) { /*sanity check for mod_no */ ++ if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { ++ if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ ++ wp_remora_intr_fxs(fe, mod_no); ++ }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ ++ wp_remora_intr_fxo(fe, mod_no); ++ } } } -+ DEBUG_EVENT("%s: Error: Received EVENT on invalid chan:%d\n", -+ card->devname, -+ fe_chan); -+ - return NULL; - #endif - } -@@ -2007,62 +2080,57 @@ - 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 +2144,53 @@ - 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 +2208,53 @@ - */ - 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 +2272,54 @@ - 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 +2334,29 @@ - { - int i; - -- TDM_FUNC_DBG -- -- if (IS_TE1_CARD(card)) { -- 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)){ -- -- 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; -- } -+ TDM_FUNC_DBG(); - -- 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() -+ DEBUG_TDMAPI("%s(): original_active_ch: 0x%X\n", __FUNCTION__, tdm_api->original_active_ch); - -- }else{ -- DEBUG_TDMAPI("Not a TE1 card\n"); -+ for(i = 0; i < NUM_OF_E1_CHANNELS; i++){ -+ if(tdm_api->original_active_ch & (1 << i)){ - -- DEBUG_TDMAPI("%s(): tdm_api->tdm_chan: %d\n", __FUNCTION__, tdm_api->tdm_chan); -+ DEBUG_TDMAPI("%s(): setting channel: %d\n", __FUNCTION__, i); - -- 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(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[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 +2365,7 @@ - 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 +2376,27 @@ - return 1; - } - -- 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(): 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() -- }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[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[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 +2557,4 @@ - return -EINVAL; - } - --#endif -+#endif /* #if defined(BUILD_TDMV_API) */ diff --git a/patches/kdrivers/src/net/sdla_56k.c b/patches/kdrivers/src/net/sdla_56k.c index aa9bcbb..b77c008 100644 --- a/patches/kdrivers/src/net/sdla_56k.c +++ b/patches/kdrivers/src/net/sdla_56k.c @@ -91,6 +91,7 @@ static void display_Rx_code_condition(sdla_fe_t* fe); static int sdla_56k_print_alarm(sdla_fe_t* fe, unsigned int); static int sdla_56k_update_alarm_info(sdla_fe_t *fe, struct seq_file* m, int* stop_cnt); +static int sdla_56k_polling(sdla_fe_t* fe); 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); @@ -150,7 +151,8 @@ static int sdla_56k_get_fe_status(sdla_fe_t *fe, unsigned char *status, int notu u_int32_t sdla_56k_alarm(sdla_fe_t *fe, int manual_read) { - unsigned short status = 0x00; + unsigned short status = 0x00; + sdla_t *card = (sdla_t *)fe->card; AFT_FUNC_DEBUG(); @@ -213,6 +215,10 @@ u_int32_t sdla_56k_alarm(sdla_fe_t *fe, int manual_read) } DEBUG_EVENT("%s: 56k Connected\n", fe->name); + + if (card->wandev.te_link_state){ + card->wandev.te_link_state(card); + } } }else{ if((fe->fe_status == FE_CONNECTED) || @@ -228,6 +234,10 @@ u_int32_t sdla_56k_alarm(sdla_fe_t *fe, int manual_read) } DEBUG_EVENT("%s: 56k Disconnected (loopback)\n", fe->name); + + if (card->wandev.te_link_state){ + card->wandev.te_link_state(card); + } } } } @@ -258,6 +268,7 @@ int sdla_56k_iface_init(void *p_fe, void* pfe_iface) fe_iface->config = &sdla_56k_config; fe_iface->unconfig = &sdla_56k_unconfig; + fe_iface->polling = &sdla_56k_polling; fe_iface->get_fe_status = &sdla_56k_get_fe_status; fe_iface->get_fe_media = &sdla_56k_get_fe_media; @@ -289,6 +300,8 @@ static int sdla_56k_intr(sdla_fe_t *fe) return 0; } + + /* Called from ISR. On AFT card there is only on 56 port, it means the interrupt is always ours. Returns: 1 @@ -404,6 +417,14 @@ static int sdla_56k_unconfig(void* pfe) return 0; } +static int sdla_56k_polling(sdla_fe_t* fe) +{ + + sdla_56k_alarm(fe, 1); + + return 0; +} + static void display_Rx_code_condition(sdla_fe_t* fe) { sdla_56k_param_t *k56_param = &fe->fe_param.k56_param; @@ -493,7 +514,7 @@ static void display_Rx_code_condition(sdla_fe_t* fe) ****************************************************************************** */ static int -sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) +sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char mode, unsigned char enable) { //unsigned char loop=BIT_RX_CTRL_DSU_LOOP|BIT_RX_CTRL_CSU_LOOP; @@ -501,7 +522,7 @@ sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) //unsigned char loop=BIT_RX_CTRL_CSU_LOOP; unsigned char loop=0x00; - if(type==WAN_TE1_PAYLB_MODE){ + if(mode==WAN_TE1_PAYLB_MODE){ loop=BIT_RX_CTRL_DSU_LOOP; }else{ loop=BIT_RX_CTRL_CSU_LOOP; @@ -510,7 +531,7 @@ sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (enable == WAN_TE1_LB_ENABLE){ WRITE_REG(REG_RX_CTRL, READ_REG(REG_RX_CTRL) | loop); DEBUG_EVENT("%s: %s Diagnostic Digital Loopback mode activated (0x%X).\n", @@ -543,16 +564,18 @@ sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) static int sdla_56k_udp(sdla_fe_t *fe, void* pudp_cmd, unsigned char* data) { wan_cmd_t *udp_cmd = (wan_cmd_t*)pudp_cmd; + wan_femedia_t *fe_media; int err; AFT_FUNC_DEBUG(); switch(udp_cmd->wan_cmd_command){ case WAN_GET_MEDIA_TYPE: - data[0] = (IS_56K_FEMEDIA(fe) ? WAN_MEDIA_56K : - WAN_MEDIA_NONE); + fe_media = (wan_femedia_t*)data; + memset(fe_media, 0, sizeof(wan_femedia_t)); + fe_media->media = WAN_MEDIA_56K; udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(unsigned char); + udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t); break; case WAN_FE_GET_STAT: diff --git a/patches/kdrivers/src/net/sdla_8te1.c b/patches/kdrivers/src/net/sdla_8te1.c index 6ec2d84..b5bf690 100644 --- a/patches/kdrivers/src/net/sdla_8te1.c +++ b/patches/kdrivers/src/net/sdla_8te1.c @@ -52,36 +52,19 @@ /****************************************************************************** * INCLUDE FILES ******************************************************************************/ -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -# include -# if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -# include -# endif -# include -# include /* WANPIPE common user API definitions */ -# include -#elif (defined __WINDOWS__) -# include -# include -# include -# include -# include /* WANPIPE common user API definitions */ -#define _DEBUG_EVENT DBG_8TE1 +# include "wanpipe_includes.h" +# include "wanpipe_defines.h" +# include "wanpipe_debug.h" +# include "wanproc.h" -#elif (defined __LINUX__) || (defined __KERNEL__) -# include -# include -# include -# include # if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -# include +# include "wanpipe_snmp.h" # endif -# include -# include /* WANPIPE common user API definitions */ -#else -# error "No OS Defined" -#endif + +# include "sdla_te1_ds.h" +# include "wanpipe.h" /* WANPIPE common user API definitions */ + /****************************************************************************** * DEFINES AND MACROS @@ -1494,7 +1477,7 @@ static int sdla_ds_te1_post_init(void* pfe) event.type = TE_LINKDOWN_TIMER; event.delay = POLLING_TE1_TIMER; sdla_ds_te1_add_event(fe, &event); - sdla_ds_te1_add_timer(fe, HZ); + sdla_ds_te1_add_timer(fe, POLLING_TE1_TIMER); return 0; } @@ -3223,7 +3206,7 @@ static void sdla_ds_te1_timer(unsigned long pfe) sdla_ds_te1_polling(fe); } }else{ - sdla_ds_te1_add_timer(fe, 1000); + sdla_ds_te1_add_timer(fe, POLLING_TE1_TIMER); } return; } @@ -3377,7 +3360,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) 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); + sdla_ds_te1_add_timer(fe, POLLING_TE1_TIMER); return 0; } event = WAN_LIST_FIRST(&fe->event); @@ -3610,7 +3593,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) if (event){ sdla_ds_te1_add_timer(fe, event->delay); }else{ - sdla_ds_te1_add_timer(fe, HZ); + sdla_ds_te1_add_timer(fe, POLLING_TE1_TIMER); } return 0; } @@ -3769,7 +3752,7 @@ static int sdla_ds_te1_liu_alb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_LMCR); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (mode == WAN_TE1_LB_ENABLE){ value |= BIT_LMCR_ALB; }else{ value &= ~BIT_LMCR_ALB; @@ -3795,7 +3778,7 @@ static int sdla_ds_te1_liu_llb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_LMCR); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (mode == WAN_TE1_LB_ENABLE){ value |= BIT_LMCR_LLB; }else{ value &= ~BIT_LMCR_LLB; @@ -3821,7 +3804,7 @@ static int sdla_ds_te1_liu_rlb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_LMCR); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (mode == WAN_TE1_LB_ENABLE){ value |= BIT_LMCR_RLB; }else{ value &= ~BIT_LMCR_RLB; @@ -3847,7 +3830,7 @@ static int sdla_ds_te1_fr_flb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_RCR3); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (mode == WAN_TE1_LB_ENABLE){ value |= BIT_RCR3_FLB; }else{ value &= ~BIT_RCR3_FLB; @@ -3873,7 +3856,7 @@ static int sdla_ds_te1_fr_plb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_RCR3); - if (mode == WAN_TE1_ACTIVATE_LB){ + if (mode == WAN_TE1_LB_ENABLE){ value |= BIT_RCR3_PLB; }else{ value &= ~BIT_RCR3_PLB; @@ -3898,10 +3881,6 @@ sdla_ds_te1_set_lb(sdla_fe_t *fe, unsigned char mode, unsigned char action) WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - DEBUG_EVENT("%s: %s %s mode...\n", - fe->name, - 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, action); @@ -3909,37 +3888,41 @@ sdla_ds_te1_set_lb(sdla_fe_t *fe, unsigned char mode, unsigned char action) case WAN_TE1_LIU_LLB_MODE: err = sdla_ds_te1_liu_llb(fe, action); break; - case WAN_TE1_LIU_RLB_MODE: - case WAN_TE1_LINELB_MODE: - err = sdla_ds_te1_liu_rlb(fe, action); - break; + //case WAN_TE1_LIU_RLB_MODE: + // err = sdla_ds_te1_liu_rlb(fe, action); + // break; case WAN_TE1_LIU_DLB_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, action); + case WAN_TE1_LINELB_MODE: + err = sdla_ds_te1_liu_rlb(fe, action); break; case WAN_TE1_PAYLB_MODE: - case WAN_TE1_FR_PLB_MODE: err = sdla_ds_te1_fr_plb(fe, action); break; - case WAN_TE1_FR_RLB_MODE: + case WAN_TE1_DDLB_MODE: + err = sdla_ds_te1_fr_flb(fe, action); + break; default: - DEBUG_EVENT("%s: Unsupport loopback mode (%s)!\n", + DEBUG_EVENT("%s: Unsupported loopback mode (%s)!\n", fe->name, WAN_TE1_LB_MODE_DECODE(mode)); return -EINVAL; } if (!err){ - if (action == WAN_TE1_ACTIVATE_LB){ + if (action == WAN_TE1_LB_ENABLE){ wan_set_bit(mode, &fe->te_param.lb_mode); }else{ wan_clear_bit(mode, &fe->te_param.lb_mode); } } + DEBUG_EVENT("%s: %s %s mode... %s\n", + fe->name, + WAN_TE1_LB_ACTION_DECODE(action), + WAN_TE1_LB_MODE_DECODE(mode), + (!err) ? "Done" : "Failed"); return err; } @@ -3961,11 +3944,11 @@ static u32 sdla_ds_te1_get_lb(sdla_fe_t *fe) lmcr = READ_REG(REG_LMCR); if (lmcr & BIT_LMCR_ALB) wan_set_bit(WAN_TE1_LIU_ALB_MODE, &mode); if (lmcr & BIT_LMCR_LLB) wan_set_bit(WAN_TE1_LIU_LLB_MODE, &mode); - if (lmcr & BIT_LMCR_RLB) wan_set_bit(WAN_TE1_LIU_RLB_MODE, &mode); + if (lmcr & BIT_LMCR_RLB) wan_set_bit(WAN_TE1_LINELB_MODE, &mode); rcr3 = READ_REG(REG_RCR3); - if (rcr3 & BIT_RCR3_FLB) wan_set_bit(WAN_TE1_FR_FLB_MODE, &mode); - if (rcr3 & BIT_RCR3_PLB) wan_set_bit(WAN_TE1_FR_PLB_MODE, &mode); + if (rcr3 & BIT_RCR3_FLB) wan_set_bit(WAN_TE1_DDLB_MODE, &mode); + if (rcr3 & BIT_RCR3_PLB) wan_set_bit(WAN_TE1_PAYLB_MODE, &mode); return mode; } @@ -3981,17 +3964,21 @@ static u32 sdla_ds_te1_get_lb(sdla_fe_t *fe) static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) { wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; + wan_femedia_t *fe_media; sdla_fe_debug_t *fe_debug; sdla_fe_timer_event_t event; int err = 0; switch(udp_cmd->wan_cmd_command){ case WAN_GET_MEDIA_TYPE: - data[0] = (IS_T1_FEMEDIA(fe) ? WAN_MEDIA_T1 : - IS_E1_FEMEDIA(fe) ? WAN_MEDIA_E1 : - WAN_MEDIA_NONE); + fe_media = (wan_femedia_t*)data; + memset(fe_media, 0, sizeof(wan_femedia_t)); + fe_media->media = fe->fe_cfg.media; + fe_media->sub_media = fe->fe_cfg.sub_media; + fe_media->chip_id = WAN_TE_CHIP_DM; + fe_media->max_ports = fe->fe_max_ports; udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(unsigned char); + udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t); break; case WAN_FE_LB_MODE: @@ -4005,13 +3992,13 @@ static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) break; } #if 1 + err = sdla_ds_te1_set_lb(fe, data[0], data[1]); +#else event.type = TE_SET_LB_MODE; event.te_event.lb_type = data[0]; /* LB type */ 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_lb(fe, data[0], data[1]); #endif udp_cmd->wan_cmd_return_code = (!err) ? WAN_CMD_OK : WAN_UDP_FAILED_CMD; diff --git a/patches/kdrivers/src/net/sdla_aft_te1.c b/patches/kdrivers/src/net/sdla_aft_te1.c index 688aa47..c3d9322 100644 --- a/patches/kdrivers/src/net/sdla_aft_te1.c +++ b/patches/kdrivers/src/net/sdla_aft_te1.c @@ -515,6 +515,7 @@ static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event); #endif static void callback_front_end_state(void *card_id); +static int aft_hwec_config_ch (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int fe_chan, int ctrl); #if 0 static void aft_list_descriptors(private_area_t *chan); @@ -546,6 +547,7 @@ 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); +static void aft_tx_dma_skb_init(private_area_t *chan, netskb_t *skb); #if defined(NETGRAPH) extern void wan_ng_link_state(wanpipe_common_t *common, int state); @@ -938,6 +940,8 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) card->devname); return -EINVAL; } + memset(&card->fe, 0, sizeof(sdla_fe_t)); + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); /* TE1 Make special hardware initialization for T1/E1 board */ if (IS_TE1_MEDIA(&conf->fe_cfg)){ @@ -1025,6 +1029,8 @@ int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) card->devname); return -EINVAL; } + memset(&card->fe, 0, sizeof(sdla_fe_t)); + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); if (IS_56K_MEDIA(&conf->fe_cfg)){ @@ -1989,15 +1995,23 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* #endif #if defined(AFT_API_SUPPORT) - } else if( strcmp(conf->usedby, "API") == 0) { + } else if( strcmp(conf->usedby, "API") == 0 || strcmp(conf->usedby, "TDM_SPAN_VOICE_API") == 0) { chan->common.usedby = API; - DEBUG_EVENT( "%s:%s: Running in API mode\n", - wandev->name,chan->if_name); + DEBUG_EVENT( "%s:%s: Running in %s mode\n", + wandev->name,chan->if_name, conf->usedby); 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; + + if (strcmp(conf->usedby, "TDM_SPAN_VOICE_API") == 0) { + chan->tdm_span_voice_api=1; + chan->cfg.data_mux=1; + conf->hdlc_streaming=0; + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + } #endif #if defined(AFT_XMTP2_API_SUPPORT) @@ -3236,6 +3250,10 @@ static int if_open (netdevice_t* dev) /* Increment the module usage count */ wanpipe_open(card); + if (card->wandev.config_id == WANCONFIG_AFT_56K) { + wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } /* Wait for the front end interrupt * before enabling the card */ @@ -4262,7 +4280,11 @@ static void aft_dev_enable(sdla_t *card, private_area_t *chan) DEBUG_CFG("%s: Enabling FOR NON CHANNELIZED !\n",chan->if_name); - aft_channel_txintr_ctrl(card,chan,1); + if (chan->tdm_span_voice_api) { + aft_channel_txintr_ctrl(card,chan,0); + } else { + aft_channel_txintr_ctrl(card,chan,1); + } aft_channel_rxintr_ctrl(card,chan,1); } @@ -4492,6 +4514,27 @@ static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, in return; } +static void aft_tx_dma_skb_init(private_area_t *chan, netskb_t *skb) +{ + + if (chan->tx_idle_skb == skb) { + return; + } + + if (chan->common.usedby == XMTP2_API) { + /* Requeue the tx buffer because it came from rx_free_list */ + aft_init_requeue_free_skb(chan, skb); + + } else if (chan->channelized_cfg && !chan->hdlc_eng){ + /* Requeue the tx buffer because it came from rx_free_list */ + aft_init_requeue_free_skb(chan, skb); + + }else{ + wan_skb_free(skb); + } +} + + /*=============================================== * aft_tx_post_complete * @@ -6160,6 +6203,11 @@ static void __wp_aft_per_per_port_isr(sdla_t *card, u32 dma_rx_reg, u32 dma_tx_r DEBUG_TEST("%s: RX Interrupt pend. \n", card->devname); aft_dma_rx_complete(card,chan,0); + + if (chan->tdm_span_voice_api) { + wan_set_bit(i,&dma_tx_voice); + aft_dma_tx_complete(card,chan,0,0); + } #if 0 @@ -6532,6 +6580,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, unsigned short buffer_length; wan_udp_pkt_t *wan_udp_pkt; wan_trace_t *trace_info=NULL; + wan_if_cfg_t *if_cfg; wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; @@ -6551,9 +6600,30 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, 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; + if_cfg = (wan_if_cfg_t*)&wan_udp_pkt->wan_udp_data[0]; + memset(if_cfg,0,sizeof(wan_if_cfg_t)); + if_cfg->usedby = chan->common.usedby; + if_cfg->media=card->wandev.fe_iface.get_fe_media(&card->fe); + if_cfg->active_ch=chan->time_slot_map; + if_cfg->chunk_sz=chan->mru/chan->num_of_time_slots; + if_cfg->interface_number=chan->logic_ch_num; + + if (chan->hdlc_eng) { + if_cfg->hw_coding=WAN_TDMV_HDLC; + } else { + if_cfg->hw_coding=card->fe.fe_cfg.tdmv_law; + if (IS_T1_CARD(card)){ + if_cfg->hw_coding=WAN_TDMV_MULAW; + } else if (IS_E1_CARD(card)) { + if_cfg->hw_coding=WAN_TDMV_ALAW; + } + } + + memcpy(&if_cfg->fe_cfg, &card->fe.fe_cfg, sizeof(sdla_fe_cfg_t)); + + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data_len=sizeof(wan_if_cfg_t); + break; case READ_CODE_VERSION: wan_udp_pkt->wan_udp_return_code = 0; @@ -6769,7 +6839,8 @@ 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; - + +#if 0 case WAN_GET_MEDIA_TYPE: if (card->wandev.fe_iface.get_fe_media){ wan_udp_pkt->wan_udp_data[0] = @@ -6780,6 +6851,9 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; } break; + +#endif + #if 0 case WAN_FE_GET_STAT: case WAN_FE_LB_MODE: @@ -6827,7 +6901,8 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, break; default: - if ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START){ + if ((wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE) || + ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START)){ /* FE udp calls */ wan_smp_flag_t smp_flags,smp_flags1; @@ -7799,7 +7874,11 @@ static int update_comms_stats(sdla_t* card) static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan) { - if (chan->channelized_cfg && !chan->hdlc_eng){ + /* Igore fifo errors in transpared mode. There is nothing + that we can do to make it better. The check below + will be covered by this statement, leaving it for + information sake */ + if (!chan->hdlc_eng){ return; } @@ -7847,11 +7926,13 @@ static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan) } static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) -{ - if (chan->channelized_cfg && !chan->hdlc_eng){ - return; - } - +{ + /* Igore fifo errors in transpared mode. There is nothing + that we can do to make it better. */ + if (!chan->hdlc_eng){ + return; + } + #if 0 if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s:%s Tx Fifo Recovery!\n", @@ -8395,22 +8476,7 @@ static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) 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 if (chan->common.usedby == XMTP2_API) { - - /* XMTP2 API 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); - } + aft_tx_dma_skb_init(chan,dma_chain->skb); dma_chain->skb=NULL; } @@ -8595,6 +8661,7 @@ static int aft_dma_chain_tx(wan_dma_descr_t *dma_chain,private_area_t *chan, int #undef card } + /*=============================================== * aft_dma_chain_init * @@ -8614,20 +8681,7 @@ aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) if (dma_chain->skb){ if (!chan->hdlc_eng){ - if (dma_chain->skb != chan->tx_idle_skb){ - - if (chan->common.usedby == XMTP2_API) { - /* Requeue the tx buffer because it came from rx_free_list */ - aft_init_requeue_free_skb(chan, dma_chain->skb); - - } else if (chan->channelized_cfg && !chan->hdlc_eng){ - /* Requeue the tx buffer because it came from rx_free_list */ - aft_init_requeue_free_skb(chan, dma_chain->skb); - - }else{ - wan_skb_free(dma_chain->skb); - } - } + aft_tx_dma_skb_init(chan,dma_chain->skb); dma_chain->skb=NULL; }else{ wan_skb_free(dma_chain->skb); @@ -9882,7 +9936,11 @@ static void aft_free_tx_descriptors(private_area_t *chan) chan->tx_chain_indx = chan->tx_pending_chain_indx; while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ - wan_skb_free(skb); + if (!chan->hdlc_eng) { + aft_tx_dma_skb_init(chan,skb); + } else { + wan_skb_free(skb); + } } } @@ -12077,19 +12135,37 @@ static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *co { int err = 0; int fe_chan = 0; - unsigned int tdmv_hwec_option=0; + int i; /* If not hardware echo nothing to configure */ if (!card->wandev.ec_enable) { return 0; } - if (conf) { - tdmv_hwec_option=conf->hwec.enable; - } + if (chan->tdm_span_voice_api) { + u32 map=chan->time_slot_map; + for (i=0;i<31;i++) { + if (wan_test_bit(i,&map)) { + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ + fe_chan = i+1; + }else{ + fe_chan = i; + } + } else if (IS_FXOFXS_CARD(card)) { + fe_chan = i+1; + } else { + fe_chan = i+1; + } + err=aft_hwec_config_ch(card,chan,conf,fe_chan,ctrl); + if (err) { + return err; + } + } + } - if (chan->common.usedby == TDM_VOICE_API || - chan->common.usedby == TDM_VOICE){ + } else 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)) { @@ -12104,49 +12180,63 @@ static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *co fe_chan = chan->first_time_slot+1; } + err=aft_hwec_config_ch(card,chan,conf,fe_chan,ctrl); + if (err) { + return err; + } + } + + return err; +} + +static int aft_hwec_config_ch (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int fe_chan, int ctrl) +{ + int err = 0; + unsigned int tdmv_hwec_option=0; + + if (conf) { + tdmv_hwec_option=conf->hwec.enable; + } #if defined(CONFIG_WANPIPE_HWEC) - if (ctrl == 0) { + if (ctrl == 0) { - if (IS_BRI_CARD(card)) { - DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); - - /* translate channel to be 1 or 2, nothing else!! */ - fe_chan = (fe_chan % 2); - if (fe_chan == 0) { - fe_chan=2; - } - DEBUG_HWEC("%s(): new fe_chan: %d\n", __FUNCTION__, fe_chan); + if (IS_BRI_CARD(card)) { + DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); + /* translate channel to be 1 or 2, nothing else!! */ + fe_chan = (fe_chan % 2); + if (fe_chan == 0) { + fe_chan=2; } - - card->wandev.ec_enable(card, 0, fe_chan); + DEBUG_HWEC("%s(): new fe_chan: %d\n", __FUNCTION__, fe_chan); + } + card->wandev.ec_enable(card, 0, fe_chan); - } else if (tdmv_hwec_option) { + } else if (tdmv_hwec_option) { - if (IS_BRI_CARD(card)){ - DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); + if (IS_BRI_CARD(card)){ + DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); - /* translate channel to be 1 or 2, nothing else!! */ - fe_chan = (fe_chan % 2); - if (fe_chan == 0) { - fe_chan=2; - } - DEBUG_HWEC("%s(): new fe_chan: %d\n", __FUNCTION__, fe_chan); + /* translate channel to be 1 or 2, nothing else!! */ + fe_chan = (fe_chan % 2); + if (fe_chan == 0) { + 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, - fe_chan); + DEBUG_HWEC("[HWEC] %s: Enable Echo Canceller on fe_chan %d\n", + chan->if_name, + fe_chan); - err = card->wandev.ec_enable(card, 1, fe_chan); - if (err) { - DEBUG_EVENT("%s: Failed to enable HWEC on fe chan %d\n", - chan->if_name,fe_chan); - return err; - } - } + err = card->wandev.ec_enable(card, 1, fe_chan); + if (err) { + DEBUG_EVENT("%s: Failed to enable HWEC on fe chan %d\n", + chan->if_name,fe_chan); + return err; + } + } #endif - } return err; } diff --git a/patches/kdrivers/src/net/sdla_aft_te3.c b/patches/kdrivers/src/net/sdla_aft_te3.c index b0153af..57e7f6e 100644 --- a/patches/kdrivers/src/net/sdla_aft_te3.c +++ b/patches/kdrivers/src/net/sdla_aft_te3.c @@ -105,7 +105,7 @@ enum { #endif #define MAX_AFT_DMA_CHAINS 16 -#define MAX_TX_BUF (MAX_AFT_DMA_CHAINS)+1 +#define MAX_TX_BUF ((MAX_AFT_DMA_CHAINS)*2)+1 #define MAX_RX_BUF ((MAX_AFT_DMA_CHAINS)*8)+1 #define MAX_RX_SCHAIN_BUF (MAX_RX_BUF)*2 @@ -116,6 +116,7 @@ enum { * 0=Remove Disabled */ + static int aft_rx_copyback=1000; /******Data Structures*****************************************************/ @@ -169,13 +170,13 @@ typedef struct private_area aft_comm_err_stats_t errstats; #if 1 int tracing_enabled; /* For enabling Tracing */ - unsigned long router_start_time; + wan_time_t 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; + wan_time_t router_up_time; unsigned char mc; /* Mulitcast support on/off */ unsigned char udp_pkt_src; /* udp packet processing */ @@ -291,6 +292,7 @@ static int if_change_mtu(netdevice_t *dev, int new_mtu); static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt); #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 if_tx_timeout (netdevice_t *dev); @@ -372,7 +374,7 @@ 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 xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan,netskb_t *skb); +static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan); 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 *); @@ -408,6 +410,8 @@ 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); +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl); + /* Procfs functions */ static int wan_aft3_get_info(void* pcard, struct seq_file* m, int* stop_cnt); @@ -498,6 +502,9 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) card->devname); } + 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); + /* Obtain hardware configuration parameters */ card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; @@ -529,7 +536,7 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) card->fe.read_fe_reg = card->hw_iface.fe_read; card->wandev.fe_enable_timer = enable_timer; - card->wandev.te_link_state = handle_front_end_state; + card->wandev.te_link_state = callback_front_end_state; //ALEX conf->electrical_interface = // IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; @@ -617,7 +624,7 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) * After seting the state to DISCONNECTED this * function must return 0 i.e. success */ - DEBUG_EVENT( "%s: Init Done.\n",card->devname); + DEBUG_EVENT( "%s: Init Done. Firm=%02X\n",card->devname,card->u.aft.firm_ver); return 0; } @@ -866,6 +873,10 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) chan->hdlc_eng = conf->hdlc_streaming; if (!chan->hdlc_eng){ + + /* Enable single dma chain on Transparent mode */ + chan->single_dma_chain=1; + if (card->wandev.mtu&0x03){ DEBUG_EVENT("%s:%s: Error, Transparent MTU must be word aligned!\n", card->devname,chan->if_name); @@ -1118,6 +1129,12 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) chan->tx_realign_buf=NULL; } + if (chan->tx_idle_skb){ + wan_skb_free(chan->tx_idle_skb); + chan->tx_idle_skb=NULL; + } + + wan_spin_unlock_irq(&card->wandev.lock,&flags); /* Delete interface name from proc fs. */ @@ -1416,9 +1433,12 @@ static void disable_comm (sdla_t *card) /* Unconfiging, only on shutdown */ if (IS_TE3(&card->fe.fe_cfg)) { + 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); - } + } } wan_spin_lock_irq(&card->wandev.lock,&flags); @@ -1618,21 +1638,28 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - err=xilinx_dma_te3_tx(card,chan,skb); + if (wan_skb_queue_len(&chan->wp_tx_pending_list) > MAX_TX_BUF){ + WAN_NETIF_STOP_QUEUE(dev); + xilinx_dma_te3_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); + + err=xilinx_dma_te3_tx(card,chan); switch (err){ + case -EBUSY: 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 @@ -1642,12 +1669,13 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct * to start the interface again. * This SHOULD NEVER happen */ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: TE3 Failed to send: Should never happend!\n", + 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; + break; } wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); @@ -1795,6 +1823,7 @@ if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t 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; + chan->if_stats.tx_carrier_errors=0; wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); break; @@ -2098,6 +2127,10 @@ static void xilinx_dma_tx_complete (sdla_t *card, private_area_t *chan, int wtd) aft_tx_dma_chain_handler((unsigned long)chan); + + if (!wtd) { + xilinx_dma_te3_tx(card,chan); + } if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ WAN_NETIF_WAKE_QUEUE(chan->common.dev); @@ -2110,6 +2143,10 @@ static void xilinx_dma_tx_complete (sdla_t *card, private_area_t *chan, int wtd) #endif } + if (!wtd) { + wan_set_bit(0,&chan->idle_start); + } + if (!chan->single_dma_chain){ aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); } @@ -2129,8 +2166,11 @@ static void xilinx_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_ (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); + /* We can get tx latency timeout thus dont print in that case */ + if (!(reg & TxDMA_HI_DMA_PCI_ERROR_DS_TOUT)){ + 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,®)){ @@ -2159,8 +2199,10 @@ static void xilinx_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_ card->devname,chan->if_name); } if (reg & TxDMA_HI_DMA_PCI_ERROR_DS_TOUT){ + if (WAN_NET_RATELIMIT()) { DEBUG_EVENT("%s:%s: Tx Warning: PCI Latency Timeout!\n", card->devname,chan->if_name); + } chan->errstats.Tx_pci_latency++; goto tx_post_ok; } @@ -2393,13 +2435,18 @@ static void xilinx_rx_post_complete (sdla_t *card, private_area_t *chan, } } - wan_skb_pull(skb, sizeof(wp_rx_element_t)); + //ORG 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 */ + 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); @@ -2417,6 +2464,9 @@ static void xilinx_rx_post_complete (sdla_t *card, private_area_t *chan, } 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); @@ -2476,21 +2526,21 @@ static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num) 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, smp_flags1; +#endif DEBUG_TEST("%s: %s Sdla Polling!\n",__FUNCTION__,card->devname); -#if defined(__LINUX__) +#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 - { - 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; } @@ -2618,8 +2668,8 @@ static void wp_bh (void* data, int dummy) if (SYSTEM_TICKS-timeout > 3){ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: BH Squeeze! %li\n", - chan->if_name,SYSTEM_TICKS-timeout); + DEBUG_EVENT("%s: BH Squeeze! %ld\n", + chan->if_name,(unsigned long)(SYSTEM_TICKS-timeout)); } break; } @@ -2686,25 +2736,33 @@ static int fifo_error_interrupt(sdla_t *card, u32 reg, u32 tx_status, u32 rx_sta chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[i]; if (!chan){ + if (WAN_NET_RATELIMIT()) { DEBUG_EVENT("Warning: ignoring tx error intr: no dev!\n"); + } continue; } if (!wan_test_bit(0,&chan->up)){ + if (WAN_NET_RATELIMIT()) { 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){ + if (WAN_NET_RATELIMIT()) { 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 (WAN_NET_RATELIMIT()) { + 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); } @@ -2805,7 +2863,7 @@ static void front_end_interrupt(sdla_t *card, unsigned long reg) static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card) { int i; - u32 reg; + u32 reg,cfg_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; @@ -2823,6 +2881,7 @@ static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card) * -- "FiFo/Line Abort Error" interrupt disable * --------------------------------------------------*/ card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); + cfg_reg=reg; DEBUG_TEST("\n"); DEBUG_TEST("%s: ISR (0x%X) = 0x%08X \n", @@ -2879,7 +2938,7 @@ static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card) 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__) +#if defined(__LINUX__) || defined(__FreeBSD__) wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); @@ -3016,6 +3075,11 @@ isr_skb_rx: dma_tx_reg,card->u.xilinx.logic_ch_map); } } + + if (!wan_test_bit(ERROR_INTR_ENABLE_BIT,&cfg_reg)) { + DEBUG_EVENT("%s: Enabling FIFO Interrupt\n",card->devname); + aft_fifo_intr_ctrl(card, 1); + } } isr_skb_tx: @@ -3314,6 +3378,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, wan_udp_pkt->wan_udp_return_code = 0xCD; break; +#if 0 case WAN_GET_MEDIA_TYPE: if (card->wandev.fe_iface.get_fe_media){ wan_udp_pkt->wan_udp_data[0] = @@ -3324,9 +3389,10 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; } break; - +#endif default: - if ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START){ + if ((wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE) || + ((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, @@ -3402,6 +3468,30 @@ 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 * @@ -3833,6 +3923,11 @@ static void enable_data_error_intr(sdla_t *card) xilinx_dma_rx(card,chan,-1); + if (!chan->hdlc_eng) { + aft_reset_tx_chain_cnt(chan); + xilinx_dma_te3_tx(card,chan); + } + aft_list_descriptors(chan); DEBUG_TEST("%s: Clearing Fifo and idle_flag %s\n", @@ -3853,7 +3948,9 @@ static void enable_data_error_intr(sdla_t *card) 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,®); + + /* Enable Fifo interrupt after first successful DMA */ + wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); @@ -4329,6 +4426,17 @@ static int xilinx_t3_exar_chip_configure(sdla_t *card) FE_MEDIA_DECODE(&card->fe)); 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); + } else { + DEBUG_EVENT("%s: Internal Error (%s:%d)\n", + card->devname, + __FUNCTION__,__LINE__); + return -EINVAL; + } + }else{ DEBUG_EVENT("%s: Internal Error (%s:%d)\n", card->devname, @@ -4640,14 +4748,15 @@ static void aft_tx_dma_chain_handler(unsigned long data) DEBUG_TEST("%s: TX DMA Handler Chain %i\n",chan->if_name,dma_chain->index); if (dma_chain->skb){ -#if 1 - wan_skb_set_csum(dma_chain->skb, reg); - wan_skb_queue_tail(&chan->wp_tx_complete_list,dma_chain->skb); + + if (dma_chain->skb == chan->tx_idle_skb) { + chan->if_stats.tx_carrier_errors++; + } else { + 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); @@ -4796,7 +4905,9 @@ static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_cha if (dma_chain->skb){ - wan_skb_free(dma_chain->skb); + if (dma_chain->skb != chan->tx_idle_skb) { + wan_skb_free(dma_chain->skb); + } dma_chain->skb=NULL; } @@ -4883,10 +4994,12 @@ static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb) * xilinx_dma_te3_tx * */ -static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) + +static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan) { int err=0, intr=0; aft_dma_chain_t *dma_chain; + netskb_t *skb=NULL; if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ DEBUG_EVENT("%s: SMP Critical in %s\n", @@ -4904,9 +5017,7 @@ static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) return -EBUSY; } - dma_chain = &chan->tx_dma_chain_table[chan->tx_chain_indx]; - - aft_reset_tx_watchdog(card); + dma_chain = &chan->tx_dma_chain_table[chan->tx_chain_indx]; /* If the current DMA chain is in use,then * all chains are busy */ @@ -4914,6 +5025,28 @@ static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); return -EBUSY; } + + skb=wan_skb_dequeue(&chan->wp_tx_pending_list); + if (!skb) { + if (!chan->hdlc_eng) { + skb=chan->tx_idle_skb; + if (!skb) { + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error: Tx Idle not allocated\n", + card->devname); + } + wan_clear_bit(0,&dma_chain->init); + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + return 0; + } + } else { + wan_clear_bit(0,&dma_chain->init); + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + return 0; + } + } + + aft_reset_tx_watchdog(card); if ((unsigned long)wan_skb_data(skb) & 0x03){ err=aft_realign_skb_pkt(chan,skb); @@ -4957,12 +5090,12 @@ static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) 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)){ @@ -5055,7 +5188,10 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in wan_clear_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); }else{ - + + if (card->u.aft.firm_ver >= AFT_IFT_FIMR_VER) { + wan_set_bit(DMA_HI_TE3_IFT_INTR_ENB_BIT,®); + } wan_set_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); if (intr){ @@ -5847,6 +5983,9 @@ static void aft_port_task (void * card_ptr, int arg) 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); + + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&isr_flags); card->hw_iface.hw_unlock(card->hw,&smp_flags); @@ -5886,6 +6025,9 @@ static void aft_critical_shutdown (sdla_t *card) /* Unconfiging, only on shutdown */ if (IS_TE3(&card->fe.fe_cfg)) { + 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); } @@ -5900,6 +6042,32 @@ static void aft_critical_shutdown (sdla_t *card) } + +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl) +{ + u32 reg; + card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_TX_INTR_PENDING_REG,®); + card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_RX_INTR_PENDING_REG,®); + + card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG,®); + if (ctrl) { + wan_set_bit(ERROR_INTR_ENABLE_BIT,®); + } else { + wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); + } + card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); + + + + if (!ctrl){ + card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_TX_INTR_PENDING_REG,®); + card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_RX_INTR_PENDING_REG,®); + } + + return 0; +} + + #if 0 static int aft_hdlc_core_ready(sdla_t *card) { diff --git a/patches/kdrivers/src/net/sdla_asyhdlc.c b/patches/kdrivers/src/net/sdla_asyhdlc.c index cc2f618..61e5fa6 100644 --- a/patches/kdrivers/src/net/sdla_asyhdlc.c +++ b/patches/kdrivers/src/net/sdla_asyhdlc.c @@ -376,7 +376,7 @@ int wp_asyhdlc_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 = card->hw_iface.fe_write; @@ -393,7 +393,7 @@ int wp_asyhdlc_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 = card->hw_iface.fe_write; @@ -1652,7 +1652,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); + card->wandev.fe_iface.read_pmon(&card->fe,0); }else if (IS_56K_CARD(card)) { /* 56K Update CSU/DSU alarms */ card->wandev.fe_iface.read_alarm(&card->fe, 1); @@ -2607,7 +2607,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_atm.c b/patches/kdrivers/src/net/sdla_atm.c index efe9ea0..d9df39b 100644 --- a/patches/kdrivers/src/net/sdla_atm.c +++ b/patches/kdrivers/src/net/sdla_atm.c @@ -3269,7 +3269,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_bitstrm.c b/patches/kdrivers/src/net/sdla_bitstrm.c index 77d2485..d7af1a8 100644 --- a/patches/kdrivers/src/net/sdla_bitstrm.c +++ b/patches/kdrivers/src/net/sdla_bitstrm.c @@ -4551,7 +4551,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_bri_tdmv.c b/patches/kdrivers/src/net/sdla_bri_tdmv.c index abfee15..3391290 100644 --- a/patches/kdrivers/src/net/sdla_bri_tdmv.c +++ b/patches/kdrivers/src/net/sdla_bri_tdmv.c @@ -13,6 +13,7 @@ * * ============================================================================ * June 5, 2007 David Rokhvarg Initial version. + * Sep 06, 2008 Moises Silva DAHDI support. ****************************************************************************** */ @@ -27,9 +28,9 @@ # include # include # include -# include +# include /* Map of Zaptel -> DAHDI definitions */ #else -# include +# include /* Map of Zaptel -> DAHDI definitions */ # include # include # include @@ -104,6 +105,9 @@ typedef struct wp_tdmv_bri_ { int spanno; struct zt_span span; +#ifdef DAHDI_ISSUES + struct zt_chan *chans_ptrs[MAX_BRI_LINES]; +#endif struct zt_chan chans[MAX_BRI_LINES]; unsigned long reg_module_map; /* Registered modules */ @@ -457,7 +461,11 @@ wr->span.deflaw = ZT_LAW_ALAW;//FIXME: hardcoded }/* for() */ wr->span.pvt = wr; +#ifdef DAHDI_ISSUES + wr->span.chans = wr->chans_ptrs; +#else wr->span.chans = wr->chans; +#endif 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 */ @@ -573,6 +581,9 @@ 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; +#ifdef DAHDI_ISSUES + int i; +#endif BRI_FUNC(); @@ -621,6 +632,11 @@ static int wp_tdmv_bri_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) 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"); +#ifdef DAHDI_ISSUES + for (i = 0; i < sizeof(wr->chans)/sizeof(wr->chans[0]); i++) { + wr->chans_ptrs[i] = &wr->chans[i]; + } +#endif /* BRI signalling is selected with hw HDLC (dchan is not 0) */ wr->dchan = 3;/* MUST be 3! */ @@ -1119,14 +1135,26 @@ static void wp_tdmv_bri_dtmf (void* card_id, wan_event_t *event) } if (event->dtmf_type == WAN_EC_TONE_PRESENT){ wr->dtmfactive |= (1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFDOWN | event->digit)); +#else zt_qevent_lock( &wr->span.chans[event->channel-1], (ZT_EVENT_DTMFDOWN | event->digit)); +#endif }else{ wr->dtmfactive &= ~(1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFUP | event->digit)); +#else zt_qevent_lock( &wr->span.chans[event->channel-1], (ZT_EVENT_DTMFUP | event->digit)); +#endif } return; } diff --git a/patches/kdrivers/src/net/sdla_fr.c b/patches/kdrivers/src/net/sdla_fr.c index 6e81208..678259f 100644 --- a/patches/kdrivers/src/net/sdla_fr.c +++ b/patches/kdrivers/src/net/sdla_fr.c @@ -4937,7 +4937,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, void *local_dev) &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_mp_fr.c b/patches/kdrivers/src/net/sdla_mp_fr.c index f243710..4dd5dc8 100644 --- a/patches/kdrivers/src/net/sdla_mp_fr.c +++ b/patches/kdrivers/src/net/sdla_mp_fr.c @@ -3052,7 +3052,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, void *local_dev) &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_ppp.c b/patches/kdrivers/src/net/sdla_ppp.c index a1ee2f1..368bc8f 100644 --- a/patches/kdrivers/src/net/sdla_ppp.c +++ b/patches/kdrivers/src/net/sdla_ppp.c @@ -3245,7 +3245,7 @@ static void process_udp_mgmt_pkt(sdla_t *card, netdevice_t *dev, &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdla_remora.c b/patches/kdrivers/src/net/sdla_remora.c index d468db3..925e854 100644 --- a/patches/kdrivers/src/net/sdla_remora.c +++ b/patches/kdrivers/src/net/sdla_remora.c @@ -98,8 +98,7 @@ #define WP_RM_POLL_EVENT_TIMER 10 #define WP_RM_POLL_TONE_TIMER 5000 #define WP_RM_POLL_RING_TIMER 10000 -#define FXO_LINK_DEBOUNCE 1800 -/* FXO_LINK_DEBOUNCE value changed from 200 to 1800 */ +#define FXO_LINK_DEBOUNCE 200 enum { WP_RM_POLL_TONE_DIAL = 1, WP_RM_POLL_TONE_BUSY, @@ -401,6 +400,8 @@ static int battthresh = DEFAULT_BATT_THRESH; static int ohdebounce = 64; /* ohdebounce change from 128 to 64 */ +//int intcount=0; /* intcount to call check_hook for one module per interrupt*/ + /******************************************************************************* ** FUNCTION PROTOTYPES @@ -1557,6 +1558,7 @@ 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; + fe->rm_param.access_counter = 0; if (wp_remora_opermode(fe)){ return -EINVAL; } @@ -1763,7 +1765,7 @@ static int wp_remora_post_init(void *pfe) sdla_fe_t *fe = (sdla_fe_t*)pfe; DEBUG_EVENT("%s: Running post initialization...\n", fe->name); - return wp_remora_add_timer(fe, HZ); + return wp_remora_add_timer(fe, WP_RM_POLL_TIMER); } /****************************************************************************** @@ -2000,8 +2002,11 @@ static int wp_remora_polling(sdla_fe_t* fe) sdla_fe_timer_event_t *fe_event; wan_event_t event; wan_smp_flag_t smp_flags; - int pending = 0, mod_no = 0, err = 0; + int pending = 0, mod_no = 0; u8 imask; +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + int err = 0; +#endif WAN_ASSERT_RC(fe->write_fe_reg == NULL,0); WAN_ASSERT_RC(fe->read_fe_reg == NULL, 0); @@ -2019,7 +2024,7 @@ static int wp_remora_polling(sdla_fe_t* fe) wan_spin_unlock_irq(&fe->lockirq,&smp_flags); DEBUG_EVENT("%s: WARNING: No FE events in a queue!\n", fe->name); - wp_remora_add_timer(fe, HZ); + wp_remora_add_timer(fe, WP_RM_POLL_TIMER); return 0; } fe_event = WAN_LIST_FIRST(&fe->event); @@ -2872,9 +2877,9 @@ static void wp_remora_voicedaa_tapper_check_hook(sdla_fe_t *fe, int mod_no) 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.ringdebounce += (WP_RM_CHUNKSIZE * 4); - if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce >= WP_RM_CHUNKSIZE * 128) { - + fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); + 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; @@ -2890,12 +2895,13 @@ static void wp_remora_voicedaa_tapper_check_hook(sdla_fe_t *fe, int mod_no) } } - fe->rm_param.mod[mod_no].u.fxo.ringdebounce = WP_RM_CHUNKSIZE * 128; + 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 * 1; + + fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce <= 0) { if (fe->rm_param.mod[mod_no].u.fxo.wasringing) { @@ -3104,7 +3110,7 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) 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 * 4); + fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); 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; @@ -3122,7 +3128,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 * 2; + fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; 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; @@ -3407,7 +3413,8 @@ static int wp_remora_watchdog(sdla_fe_t *fe) { int mod_no; - + //intcount++; + fe->rm_param.access_counter++; 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)) { @@ -3447,8 +3454,7 @@ static int wp_remora_watchdog(sdla_fe_t *fe) } } } - - } else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO) { + } #if 0 if (wr->mod[x].fxo.echotune){ @@ -3473,23 +3479,29 @@ static int wp_remora_watchdog(sdla_fe_t *fe) wr->mod[x].fxo.echotune = 0; } #endif - /*FIXME This code is called more often than in zaptel mode. This is WRONG !!! - Fix by calling this code one module per interrupt ! */ - - - if (fe->fe_cfg.cfg.remora.rm_mode == WAN_RM_TAPPING) { - wp_remora_voicedaa_tapper_check_hook(fe, mod_no); - } else { - wp_remora_voicedaa_check_hook(fe, mod_no); - } - - } + } + mod_no = fe->rm_param.access_counter % MAX_REMORA_MODULES; + + if ( mod_no < fe->rm_param.max_fe_channels ) {/* sanity check for valid mod_no */ + if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO) { + if (fe->fe_cfg.cfg.remora.rm_mode == WAN_RM_TAPPING) { + wp_remora_voicedaa_tapper_check_hook(fe, mod_no); + } else { + wp_remora_voicedaa_check_hook(fe, mod_no); + } + + } + + } + } + #if defined(AFT_RM_VIRTUAL_INTR_SUPPORT) + 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); } @@ -3817,7 +3829,7 @@ static int wp_remora_intr_fxo(sdla_fe_t *fe, int mod_no) WAN_ASSERT(fe->card == NULL); card = fe->card; - + status = READ_RM_REG(mod_no, 4); if (status & 0x80){ u_int8_t mode; @@ -3867,15 +3879,17 @@ static int wp_remora_intr_fxo(sdla_fe_t *fe, int mod_no) static int wp_remora_intr(sdla_fe_t *fe) { int mod_no = 0; - - for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ - if (!wan_test_bit(mod_no, &fe->rm_param.module_map)) { - continue; - } - if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ - wp_remora_intr_fxs(fe, mod_no); - }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ - wp_remora_intr_fxo(fe, mod_no); + + /* calling per module per interupt */ + mod_no = fe->rm_param.access_counter % MAX_REMORA_MODULES; + + if ( mod_no < fe->rm_param.max_fe_channels ) { /*sanity check for mod_no */ + if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ + wp_remora_intr_fxs(fe, mod_no); + }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ + wp_remora_intr_fxo(fe, mod_no); + } } } diff --git a/patches/kdrivers/src/net/sdla_remora_tdmv.c b/patches/kdrivers/src/net/sdla_remora_tdmv.c index 7564e50..4b20b4b 100644 --- a/patches/kdrivers/src/net/sdla_remora_tdmv.c +++ b/patches/kdrivers/src/net/sdla_remora_tdmv.c @@ -12,6 +12,7 @@ * 2 of the License, or (at your option) any later version. * ============================================================================ * Oct 6, 2005 Alex Feldman Initial version. + * Sep 06, 2008 Moises Silva DAHDI support. ****************************************************************************** */ @@ -27,9 +28,9 @@ # include # include # include -# include +# include /* Map of Zaptel -> DAHDI definitions */ #else -# include +# include /* Map of Zaptel -> DAHDI definitions */ # include # include # include @@ -60,7 +61,7 @@ #define OHT_TIMER 6000 /* How long after RING to retain OHT */ -#define FXO_LINK_DEBOUNCE 200 +#define FXO_LINK_DEBOUNCE 20 #define MAX_ALARMS 10 @@ -99,7 +100,9 @@ typedef struct { int wasringing; int echotune; /* echo tune */ - struct wan_rm_echo_coefs echoregs; /* echo tune */ + struct wan_rm_echo_coefs echoregs; /* echo tune */ + int readcid; + unsigned int cidtimer; } tdmv_fxo_t; typedef struct { @@ -128,6 +131,9 @@ typedef struct wp_tdmv_remora_ { int spanno; struct zt_span span; +#ifdef DAHDI_ISSUES + struct zt_chan *chans_ptrs[MAX_REMORA_MODULES]; +#endif struct zt_chan chans[MAX_REMORA_MODULES]; unsigned long reg_module_map; /* Registered modules */ @@ -707,6 +713,8 @@ 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->mod[mod_no].fxo.readcid = 0; + wr->mod[mod_no].fxo.cidtimer = wr->intcount; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); DEBUG_TDMV("%s: Module %d: NO RING on span %d!\n", wr->devname, @@ -733,30 +741,33 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) } #endif - if (abs(b) <= 1){ - fe->rm_param.mod[mod_no].u.fxo.statusdebounce ++; - if (fe->rm_param.mod[mod_no].u.fxo.statusdebounce >= FXO_LINK_DEBOUNCE){ - if (fe->rm_param.mod[mod_no].u.fxo.status != FE_DISCONNECTED){ - DEBUG_EVENT( - "%s: Module %d: FXO Line is disconnnected!\n", - wr->devname, - mod_no + 1); - fe->rm_param.mod[mod_no].u.fxo.status = FE_DISCONNECTED; - } - fe->rm_param.mod[mod_no].u.fxo.statusdebounce = FXO_LINK_DEBOUNCE; - } - }else{ + if (abs(b) > 1){ fe->rm_param.mod[mod_no].u.fxo.statusdebounce--; if (fe->rm_param.mod[mod_no].u.fxo.statusdebounce <= 0) { if (fe->rm_param.mod[mod_no].u.fxo.status != FE_CONNECTED){ DEBUG_EVENT( - "%s: Module %d: FXO Line is connected!\n", + "%s: Module %d: Line connected on span %d!\n", wr->devname, - mod_no + 1); + mod_no + 1, + wr->span.spanno); fe->rm_param.mod[mod_no].u.fxo.status = FE_CONNECTED; } fe->rm_param.mod[mod_no].u.fxo.statusdebounce = 0; } + }else if (!wr->mod[mod_no].fxo.wasringing){ + fe->rm_param.mod[mod_no].u.fxo.statusdebounce ++; + if (fe->rm_param.mod[mod_no].u.fxo.statusdebounce >= FXO_LINK_DEBOUNCE){ + if (fe->rm_param.mod[mod_no].u.fxo.status != FE_DISCONNECTED){ + DEBUG_EVENT( + "%s: Module %d: Line disconnected on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + fe->rm_param.mod[mod_no].u.fxo.status = FE_DISCONNECTED; + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_INITIAL); + } + fe->rm_param.mod[mod_no].u.fxo.statusdebounce = FXO_LINK_DEBOUNCE; + } } if (abs(b) < wr->battthresh) { @@ -1112,7 +1123,11 @@ static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv) } } wr->span.pvt = wr; +#ifdef DAHDI_ISSUES + wr->span.chans = wr->chans_ptrs; +#else wr->span.chans = wr->chans; +#endif wr->span.channels = num/*wr->max_timeslots*/; wr->span.hooksig = wp_remora_zap_hooksig; wr->span.open = wp_remora_zap_open; @@ -1221,6 +1236,9 @@ static int wp_tdmv_remora_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) sdla_t *card = (sdla_t*)pcard; wp_tdmv_remora_t *wr = NULL; wan_tdmv_t *tmp = NULL; +#ifdef DAHDI_ISSUES + int i; +#endif WAN_ASSERT(card == NULL); WAN_ASSERT(tdmv_conf->span_no == 0); @@ -1265,6 +1283,11 @@ static int wp_tdmv_remora_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) wr->max_rxtx_len = 0; wan_spin_lock_irq_init(&wr->lockirq, "wan_rmtdmv_lock"); wan_spin_lock_irq_init(&wr->tx_rx_lockirq, "wan_rmtdmv_txrx_lock"); +#ifdef DAHDI_ISSUES + for (i = 0; i < sizeof(wr->chans)/sizeof(wr->chans[0]); i++) { + wr->chans_ptrs[i] = &wr->chans[i]; + } +#endif if (tmp){ WAN_LIST_INSERT_AFTER(tmp, &card->wan_tdmv, next); @@ -1484,6 +1507,39 @@ static int wp_tdmv_remora_is_rbsbits(wan_tdmv_t *wan_tdmv) return 0; } + +#ifdef WAN_FAKE_POLARITY +#warning "WAN_FAKE_POLARITY Enabled - Experimental" +static inline void wp_tdmv_dtmfcheck_fakepolarity(wp_tdmv_remora_t *wr, int channo, unsigned char *rxbuf) +{ + sdla_t *card = wr->card; + sdla_fe_t *fe = &card->fe; + int sample; + int dtmf=1; + + /* only look for sound on the line if dtmf flag is on, it is an fxo card and line is onhook */ + if (!dtmf || !(fe->rm_param.mod[channo].type == MOD_TYPE_FXO) || wr->mod[channo].fxo.offhook) { + return; + } + + /* don't look for noise if we're already processing it, or there is a ringing tone */ + if(!wr->mod[channo].fxo.readcid && !wr->mod[channo].fxo.wasringing && + wr->intcount > wr->mod[channo].fxo.cidtimer + 400 ) { + sample = ZT_XLAW((*rxbuf), (&(wr->chans[channo]))); + if (sample > 16000 || sample < -16000) { + wr->mod[channo].fxo.readcid = 1; + wr->mod[channo].fxo.cidtimer = wr->intcount; + DEBUG_EVENT("DTMF CLIP on %i\n",channo+1); + zt_qevent_lock(&wr->chans[channo], ZT_EVENT_POLARITY); + } + } else if(wr->mod[channo].fxo.readcid && wr->intcount > wr->mod[channo].fxo.cidtimer + 2000) { + /* reset flags if it's been a while */ + wr->mod[channo].fxo.cidtimer = wr->intcount; + wr->mod[channo].fxo.readcid = 0; + } +} +#endif + /****************************************************************************** ** wp_tdmv_rx_chan() - ** @@ -1552,6 +1608,10 @@ DEBUG_EVENT("Module %d: RX: %02X %02X %02X %02X %02X %02X %02X %02X\n", wr->chans[channo].readchunk = rxbuf; wr->chans[channo].writechunk = txbuf; +#ifdef WAN_FAKE_POLARITY + wp_tdmv_dtmfcheck_fakepolarity(wr,channo,rxbuf); +#endif + #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER wp_tdmv_echo_check(wan_tdmv, &wr->chans[channo], channo); @@ -1824,14 +1884,26 @@ static void wp_tdmv_remora_dtmf (void* card_id, wan_event_t *event) if (event->dtmf_type == WAN_EC_TONE_PRESENT){ wr->dtmfactive |= (1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFDOWN | event->digit)); +#else zt_qevent_lock( &wr->span.chans[event->channel-1], (ZT_EVENT_DTMFDOWN | event->digit)); +#endif }else{ wr->dtmfactive &= ~(1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFUP | event->digit)); +#else zt_qevent_lock( &wr->span.chans[event->channel-1], (ZT_EVENT_DTMFUP | event->digit)); +#endif } return; } diff --git a/patches/kdrivers/src/net/sdla_remora_tdmv.c.orig b/patches/kdrivers/src/net/sdla_remora_tdmv.c.orig new file mode 100644 index 0000000..1594b15 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_remora_tdmv.c.orig @@ -0,0 +1,1960 @@ +/*************************************************************************** + * sdla_remora_tdmv.c WANPIPE(tm) Multiprotocol WAN Link Driver. + * AFT REMORA and FXO/FXS support module. + * + * Author: Alex Feldman + * + * Copyright: (c) 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. + * ============================================================================ + * Oct 6, 2005 Alex Feldman Initial version. + ****************************************************************************** + */ + +/******************************************************************************* +** INCLUDE FILES +*******************************************************************************/ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +#endif + +/******************************************************************************* +** DEFINES AND MACROS +*******************************************************************************/ +#define REG_SHADOW +#define REG_WRITE_SHADOW +#define NEW_PULSE_DIALING +#undef PULSE_DIALING + +#if 0 +# define SPI2STEP +#endif +/* The constants below control the 'debounce' periods enforced by the +** check_hook routines; these routines are called once every 4 interrupts +** (the interrupt cycles around the four modules), so the periods are +** specified in _4 millisecond_ increments +*/ +#define RING_DEBOUNCE 16 /* Ringer Debounce (64 ms) */ +#define DEFAULT_BATT_DEBOUNCE 16 /* Battery debounce (64 ms) */ +#define POLARITY_DEBOUNCE 16 /* Polarity debounce (64 ms) */ +#define DEFAULT_BATT_THRESH 3 /* Anything under this is "no battery" */ + +#define OHT_TIMER 6000 /* How long after RING to retain OHT */ + +#define FXO_LINK_DEBOUNCE 20 + +#define MAX_ALARMS 10 + +/* Interrupt flag enable */ +#if 0 +# define WAN_REMORA_FXS_LCIP +#endif +#if 0 +# define WAN_REMORA_FXS_DTMF +#endif + + +/* 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 */ + int readcid; + unsigned int cidtimer; +} 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_remora_ { + void *card; + char *devname; + int num; + int flags; + wan_spinlock_t lockirq; + wan_spinlock_t tx_rx_lockirq; + union { + tdmv_fxo_t fxo; + tdmv_fxs_t fxs; + } mod[MAX_REMORA_MODULES]; + + int spanno; + struct zt_span span; + struct zt_chan chans[MAX_REMORA_MODULES]; + unsigned long reg_module_map; /* Registered modules */ + + unsigned char reg0shadow[MAX_REMORA_MODULES]; /* read> fxs: 68 fxo: 5 */ + unsigned char reg1shadow[MAX_REMORA_MODULES]; /* read> fxs: 64 fxo: 29 */ + unsigned char reg2shadow[MAX_REMORA_MODULES]; /* read> fxs: 64 fxo: 29 */ + + unsigned char reg0shadow_write[MAX_REMORA_MODULES]; /* write> fxs: 68 fxo: 5 */ + int reg0shadow_update[MAX_REMORA_MODULES]; + + /* 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_REMORA_MODULES */ + int max_rxtx_len; + int channelized; + unsigned char hwec; + unsigned long echo_off_map; + + int battdebounce; /* global for FXO */ + int battthresh; /* global for FXO */ + + u_int8_t dtmfsupport; + unsigned int dtmfactive; + unsigned int dtmfmask; + unsigned int dtmfmutemask; + +} wp_tdmv_remora_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_remora_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu); +static int wp_tdmv_remora_create(void* pcard, wan_tdmv_conf_t*); +static int wp_tdmv_remora_remove(void* pcard); +static int wp_tdmv_remora_reg(void* pcard, wan_tdmv_if_conf_t*, unsigned int, unsigned char,netdevice_t*); +static int wp_tdmv_remora_unreg(void* pcard, unsigned long ts_map); +static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_remora_state(void* pcard, int state); +static int wp_tdmv_remora_running(void* pcard); +static int wp_tdmv_remora_is_rbsbits(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_remora_rx_tx_span(void *pcard); +static int wp_tdmv_remora_rx_chan(wan_tdmv_t*, int,unsigned char*,unsigned char*); +static int wp_tdmv_remora_ec_span(void *pcard); + +static void wp_tdmv_remora_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); + + +#if 0 +#define WAN_SYNC_RX_TX_TEST 1 +#warning "WAN_SYNC_RX_TX_TEST: Test option Enabled" +static int wp_tdmv_remora_rx_chan_sync_test(sdla_t *card, wp_tdmv_remora_t *wr, int channo, + unsigned char *rxbuf, + unsigned char *txbuf); +#else +#undef WAN_SYNC_RX_TX_TEST +#endif + +/******************************************************************************* +** FUNCTION DEFINITIONS +*******************************************************************************/ + +static int +#if defined(__FreeBSD__) || defined(__OpenBSD__) +wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, caddr_t data) +#else +wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) +#endif +{ + 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); + card = wr->card; + fe = &card->fe; + + switch (cmd) { + case ZT_ONHOOKTRANSFER: + if (fe->rm_param.mod[chan->chanpos - 1].type != MOD_TYPE_FXS) { + return -EINVAL; + } + err = WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int)); + /*err = get_user(x, (int *)data);*/ + if (err) return -EFAULT; + wr->mod[chan->chanpos - 1].fxs.ohttimer = x << 3; + if (fe->fe_cfg.cfg.remora.reversepolarity){ + /* OHT mode when idle */ + fe->rm_param.mod[chan->chanpos - 1].u.fxs.idletxhookstate = 0x6; + }else{ + fe->rm_param.mod[chan->chanpos - 1].u.fxs.idletxhookstate = 0x2; + } + if (wr->mod[chan->chanpos - 1].fxs.lasttxhook == 0x1) { + /* Apply the change if appropriate */ + if (fe->fe_cfg.cfg.remora.reversepolarity){ + wr->mod[chan->chanpos - 1].fxs.lasttxhook = 0x6; + }else{ + wr->mod[chan->chanpos - 1].fxs.lasttxhook = 0x2; + } +#if defined(REG_WRITE_SHADOW) + wr->mod[chan->chanpos-1].fxs.lasttxhook_update = 1; +#else + WRITE_RM_REG(chan->chanpos - 1, 64, wr->mod[chan->chanpos - 1].fxs.lasttxhook); +#endif + } + break; + + case ZT_SETPOLARITY: + err = WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int)); + /*err = get_user(x, (int *)data);*/ + if (err) return -EFAULT; + if (fe->rm_param.mod[chan->chanpos - 1].type != MOD_TYPE_FXS) { + return -EINVAL; + } + /* Can't change polarity while ringing or when open */ + if ((wr->mod[chan->chanpos - 1].fxs.lasttxhook == 0x04) || + (wr->mod[chan->chanpos - 1 ].fxs.lasttxhook == 0x00)){ + return -EINVAL; + } + + if ((x && !fe->fe_cfg.cfg.remora.reversepolarity) || (!x && fe->fe_cfg.cfg.remora.reversepolarity)){ + wr->mod[chan->chanpos - 1].fxs.lasttxhook |= 0x04; + }else{ + wr->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04; + } +#if defined(REG_WRITE_SHADOW) + wr->mod[chan->chanpos-1].fxs.lasttxhook_update = 1; +#else + WRITE_RM_REG(chan->chanpos - 1, 64, wr->mod[chan->chanpos - 1].fxs.lasttxhook); +#endif + break; + + case WAN_RM_SET_ECHOTUNE: + if (fe->rm_param.mod[chan->chanpos - 1].type == MOD_TYPE_FXO) { + + err = WAN_COPY_FROM_USER( + &wr->mod[chan->chanpos-1].fxo.echoregs, + (struct wan_rm_echo_coefs*)data, + sizeof(struct wan_rm_echo_coefs)); + if (err) return -EFAULT; + +#if 1 + wr->mod[chan->chanpos-1].fxo.echotune = 1; +#else + DEBUG_EVENT("%s: Module %d: Setting echo registers: \n", + wr->devname, chan->chanpos-1); + /* Set the ACIM register */ + WRITE_RM_REG(chan->chanpos - 1, 30, echoregs.acim); + + /* Set the digital echo canceller registers */ + WRITE_RM_REG(chan->chanpos - 1, 45, echoregs.coef1); + WRITE_RM_REG(chan->chanpos - 1, 46, echoregs.coef2); + WRITE_RM_REG(chan->chanpos - 1, 47, echoregs.coef3); + WRITE_RM_REG(chan->chanpos - 1, 48, echoregs.coef4); + WRITE_RM_REG(chan->chanpos - 1, 49, echoregs.coef5); + WRITE_RM_REG(chan->chanpos - 1, 50, echoregs.coef6); + WRITE_RM_REG(chan->chanpos - 1, 51, echoregs.coef7); + WRITE_RM_REG(chan->chanpos - 1, 52, echoregs.coef8); + + DEBUG_EVENT("%s: Module %d: Set echo registers successfully\n", + wr->devname, chan->chanpos-1); +#endif + break; + } else { + return -EINVAL; + + } + break; + + case ZT_TONEDETECT: + + if (WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int))){ + return -EFAULT; + } + + if (wr->dtmfsupport != WANOPT_YES || card->wandev.ec_dev == NULL){ + return -ENOSYS; + } + 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){ + wr->dtmfmask |= (1 << (chan->chanpos - 1)); + }else{ + wr->dtmfmask &= ~(1 << (chan->chanpos - 1)); + } + if (x & ZT_TONEDETECT_MUTE){ + wr->dtmfmutemask |= (1 << (chan->chanpos - 1)); + }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: + return -ENOTTY; + break; + } + return 0; +} + +static int wp_remora_zap_hooksig(struct zt_chan *chan, zt_txsig_t txsig) +{ + wp_tdmv_remora_t *wr = chan->pvt; + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + + WAN_ASSERT(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + if (fe->rm_param.mod[chan->chanpos - 1].type == MOD_TYPE_FXO) { + /* XXX Enable hooksig for FXO XXX */ + switch(txsig) { + case ZT_TXSIG_START: + case ZT_TXSIG_OFFHOOK: + DEBUG_TDMV("%s: Module %d: goes off-hook (txsig %d)\n", + wr->devname, chan->chanpos, txsig); + wr->mod[chan->chanpos - 1].fxo.offhook = 1; +#if defined(REG_WRITE_SHADOW) + wr->reg0shadow[chan->chanpos-1] = 0x09; + wr->reg0shadow_update[chan->chanpos-1] = 1; +#else + WRITE_RM_REG(chan->chanpos - 1, 5, 0x9); +#endif + break; + case ZT_TXSIG_ONHOOK: + DEBUG_TDMV("%s: Module %d: goes on-hook (txsig %d)\n", + wr->devname, chan->chanpos, txsig); + wr->mod[chan->chanpos - 1].fxo.offhook = 0; +#if defined(REG_WRITE_SHADOW) + wr->reg0shadow[chan->chanpos-1] = 0x08; + wr->reg0shadow_update[chan->chanpos-1] = 1; +#else + WRITE_RM_REG(chan->chanpos - 1, 5, 0x8); +#endif + break; + default: + DEBUG_TDMV("%s: Can't set tx state to %d (chan %d)\n", + wr->devname, txsig, chan->chanpos); + } + }else if (fe->rm_param.mod[chan->chanpos - 1].type == MOD_TYPE_FXS) { + switch(txsig) { + case ZT_TXSIG_ONHOOK: + DEBUG_TDMV("%s: Module %d: goes on-hook (txsig %d).\n", + wr->devname, chan->chanpos, txsig); + switch(chan->sig) { + case ZT_SIG_EM: + case ZT_SIG_FXOKS: + case ZT_SIG_FXOLS: + wr->mod[chan->chanpos-1].fxs.lasttxhook = + fe->rm_param.mod[chan->chanpos-1].u.fxs.idletxhookstate; + break; + case ZT_SIG_FXOGS: + wr->mod[chan->chanpos-1].fxs.lasttxhook = 3; + break; + } + break; + case ZT_TXSIG_OFFHOOK: + DEBUG_TDMV("%s: Module %d: goes off-hook (txsig %d).\n", + wr->devname, chan->chanpos, txsig); + switch(chan->sig) { + case ZT_SIG_EM: + wr->mod[chan->chanpos-1].fxs.lasttxhook = 5; + break; + default: + wr->mod[chan->chanpos-1].fxs.lasttxhook = + fe->rm_param.mod[chan->chanpos-1].u.fxs.idletxhookstate; + break; + } + break; + case ZT_TXSIG_START: + DEBUG_TDMV("%s: Module %d: txsig START (txsig %d).\n", + wr->devname, chan->chanpos, txsig); + wr->mod[chan->chanpos-1].fxs.lasttxhook = 4; + break; + case ZT_TXSIG_KEWL: + wr->mod[chan->chanpos-1].fxs.lasttxhook = 0; + break; + default: + DEBUG_EVENT("%s: Can't set tx state to %d\n", + wr->devname, txsig); + return 0; + break; + } +#if defined(REG_WRITE_SHADOW) + wr->mod[chan->chanpos-1].fxs.lasttxhook_update = 1; +#else + WRITE_RM_REG(chan->chanpos - 1, 64, wr->mod[chan->chanpos-1].fxs.lasttxhook); +#endif + } + + return 0; +} + +static int wp_remora_zap_open(struct zt_chan *chan) +{ + wp_tdmv_remora_t *wr = NULL; + + 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_remora_zap_close(struct zt_chan *chan) +{ + sdla_t *card = NULL; + wp_tdmv_remora_t* wr = NULL; + sdla_fe_t *fe = NULL; + + 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); + +#if 1 + if (fe->rm_param.mod[chan->chanpos - 1].type == MOD_TYPE_FXS) { + if (fe->fe_cfg.cfg.remora.reversepolarity) + fe->rm_param.mod[chan->chanpos - 1].u.fxs.idletxhookstate = 5; + else + fe->rm_param.mod[chan->chanpos - 1].u.fxs.idletxhookstate = 1; + } +#endif + return 0; +} + +static int wp_remora_zap_watchdog(struct zt_span *span, int event) +{ +#if 0 + printk("TDM: Restarting DMA\n"); + wctdm_restart_dma(span->pvt); +#endif + return 0; +} + +/****************************************************************************** +** wp_remora_zap_hwec() - +** +** OK +*/ +static int wp_remora_zap_hwec(struct zt_chan *chan, int enable) +{ + wp_tdmv_remora_t *wr = NULL; + sdla_t *card = NULL; + int fe_chan = chan->chanpos; + int err = -ENODEV; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wr = chan->pvt; + WAN_ASSERT2(wr->card == NULL, -ENODEV); + card = wr->card; + + fe_chan--; + + if (enable) { + wan_set_bit(fe_chan,&card->wandev.rtp_tap_call_map); + } else { + wan_clear_bit(fe_chan,&card->wandev.rtp_tap_call_map); + } + + if (card->wandev.ec_enable){ + /* The ec persist flag enables and disables + * persistent echo control. In persist mode + * echo cancellation is enabled regardless of + * asterisk. In persist mode off asterisk + * controls hardware echo cancellation */ + if (card->hwec_conf.persist_disable) { + err = card->wandev.ec_enable(card, enable, fe_chan); + } else { + err = 0; + } + DEBUG_TDMV("[TDMV_RM]: %s: %s HW echo canceller on channel %d\n", + wr->devname, + (enable) ? "Enable" : "Disable", + fe_chan); + } + return err; +} + +static void +wp_tdmv_remora_proslic_recheck_sanity(wp_tdmv_remora_t *wr, int mod_no) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + int res; + + WAN_ASSERT1(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + /* Check loopback */ +#if 0 +#if defined(REG_SHADOW) + res = wr->reg2shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 8); +#endif + if (res) { + DEBUG_EVENT( + "%s: Module %d: Ouch, part reset, quickly restoring reality (%02X) -- Comment out\n", + wr->devname, mod_no, res); + wp_init_proslic(fe, mod_no, 1, 1); + return; + } +#endif + +#if defined(REG_SHADOW) + res = wr->reg1shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 64); +#endif + if (!res && (res != wr->mod[mod_no].fxs.lasttxhook)) { +#if defined(REG_SHADOW) + res = wr->reg2shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 8); +#endif + if (res) { + DEBUG_EVENT( + "%s: Module %d: Ouch, part reset, quickly restoring reality\n", + wr->devname, mod_no+1); + wp_init_proslic(fe, mod_no, 1, 1); + } else { + if (wr->mod[mod_no].fxs.palarms++ < MAX_ALARMS) { + DEBUG_EVENT( + "%s: Module %d: Power alarm, resetting!\n", + wr->devname, mod_no + 1); + if (wr->mod[mod_no].fxs.lasttxhook == 4) + wr->mod[mod_no].fxs.lasttxhook = 1; + WRITE_RM_REG(mod_no, 64, wr->mod[mod_no].fxs.lasttxhook); + } else { + if (wr->mod[mod_no].fxs.palarms == MAX_ALARMS) + DEBUG_EVENT( + "%s: Module %d: Too many power alarms, NOT resetting!\n", + wr->devname, mod_no + 1); + } + } + } + return; +} + +static void +wp_tdmv_remora_voicedaa_recheck_sanity(wp_tdmv_remora_t *wr, int mod_no) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + int res; + + WAN_ASSERT1(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + /* Check loopback */ +#if defined(REG_SHADOW) + res = wr->reg2shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 34); +#endif + if (!res) { + DEBUG_EVENT( + "%s: Module %d: Ouch, part reset, quickly restoring reality\n", + wr->devname, mod_no+1); + wp_init_voicedaa(fe, mod_no, 1, 1); + } + return; +} + +static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; +#ifndef AUDIO_RINGCHECK + unsigned char res; +#endif + signed char b; + int poopy = 0; + + WAN_ASSERT1(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + /* Try to track issues that plague slot one FXO's */ +#if defined(REG_SHADOW) + b = wr->reg0shadow[mod_no]; +#else + b = READ_RM_REG(mod_no, 5); +#endif + if ((b & 0x2) || !(b & 0x8)) { + /* Not good -- don't look at anything else */ + DEBUG_TDMV("%s: Module %d: Poopy (%02x)!\n", + wr->devname, mod_no + 1, b); + poopy++; + } + b &= 0x9b; + if (wr->mod[mod_no].fxo.offhook) { + if (b != 0x9){ + WRITE_RM_REG(mod_no, 5, 0x9); + } + } else { + if (b != 0x8){ + WRITE_RM_REG(mod_no, 5, 0x8); + } + } + if (poopy) + return; +#ifndef AUDIO_RINGCHECK + if (!wr->mod[mod_no].fxo.offhook) { +#if defined(REG_SHADOW) + res = wr->reg0shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 5); +#endif + if ((res & 0x60) && wr->mod[mod_no].fxo.battery) { + wr->mod[mod_no].fxo.ringdebounce += (ZT_CHUNKSIZE * 16); + if (wr->mod[mod_no].fxo.ringdebounce >= ZT_CHUNKSIZE * 64) { + if (!wr->mod[mod_no].fxo.wasringing) { + wr->mod[mod_no].fxo.wasringing = 1; + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_RING); + DEBUG_TDMV("%s: Module %d: RING on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + } + wr->mod[mod_no].fxo.ringdebounce = ZT_CHUNKSIZE * 64; + } + } else { + wr->mod[mod_no].fxo.ringdebounce -= ZT_CHUNKSIZE * 4; + if (wr->mod[mod_no].fxo.ringdebounce <= 0) { + if (wr->mod[mod_no].fxo.wasringing) { + wr->mod[mod_no].fxo.wasringing = 0; + wr->mod[mod_no].fxo.readcid = 0; + wr->mod[mod_no].fxo.cidtimer = wr->intcount; + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); + DEBUG_TDMV("%s: Module %d: NO RING on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + } + wr->mod[mod_no].fxo.ringdebounce = 0; + } + } + } +#endif +#if defined(REG_SHADOW) + b = wr->reg1shadow[mod_no]; +#else + b = READ_RM_REG(mod_no, 29); +#endif +#if 0 + { + static int count = 0; + if (!(count++ % 100)) { + printk("mod_no %d: Voltage: %d Debounce %d\n", mod_no + 1, + b, wr->mod[mod_no].fxo.battdebounce); + } + } +#endif + + if (abs(b) > 1){ + fe->rm_param.mod[mod_no].u.fxo.statusdebounce--; + if (fe->rm_param.mod[mod_no].u.fxo.statusdebounce <= 0) { + if (fe->rm_param.mod[mod_no].u.fxo.status != FE_CONNECTED){ + DEBUG_EVENT( + "%s: Module %d: Line connected on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + fe->rm_param.mod[mod_no].u.fxo.status = FE_CONNECTED; + } + fe->rm_param.mod[mod_no].u.fxo.statusdebounce = 0; + } + }else if (!wr->mod[mod_no].fxo.wasringing){ + fe->rm_param.mod[mod_no].u.fxo.statusdebounce ++; + if (fe->rm_param.mod[mod_no].u.fxo.statusdebounce >= FXO_LINK_DEBOUNCE){ + if (fe->rm_param.mod[mod_no].u.fxo.status != FE_DISCONNECTED){ + DEBUG_EVENT( + "%s: Module %d: Line disconnected on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + fe->rm_param.mod[mod_no].u.fxo.status = FE_DISCONNECTED; + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_INITIAL); + } + fe->rm_param.mod[mod_no].u.fxo.statusdebounce = FXO_LINK_DEBOUNCE; + } + } + + if (abs(b) < wr->battthresh) { + 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); +#endif + if (wr->mod[mod_no].fxo.battery && !wr->mod[mod_no].fxo.battdebounce) { + DEBUG_TDMV( + "%s: Module %d: NO BATTERY on span %d!\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + wr->mod[mod_no].fxo.battery = 0; +#ifdef JAPAN + if ((!wr->mod[mod_no].fxo.ohdebounce) && + wr->mod[mod_no].fxo.offhook) { + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); + DEBUG_TDMV( + "%s: Module %d: Signalled On Hook span %d\n", + wr->devname, + mod_no + 1, + wr->span.spanno); +#ifdef ZERO_BATT_RING + wr->mod[mod_no].fxo.onhook++; +#endif + } +#else + DEBUG_TDMV( + "%s: Module %d: Signalled On Hook span %d\n", + wr->devname, + mod_no + 1, + wr->span.spanno); + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); +#endif + wr->mod[mod_no].fxo.battdebounce = wr->battdebounce; + } else if (!wr->mod[mod_no].fxo.battery) + wr->mod[mod_no].fxo.battdebounce = wr->battdebounce; + } else if (abs(b) > wr->battthresh) { + if (!wr->mod[mod_no].fxo.battery && !wr->mod[mod_no].fxo.battdebounce) { + DEBUG_TDMV( + "%s: Module %d: BATTERY on span %d (%s)!\n", + wr->devname, + mod_no + 1, + wr->span.spanno, + (b < 0) ? "-" : "+"); +#ifdef ZERO_BATT_RING + if (wr->mod[mod_no].fxo.onhook) { + wr->mod[mod_no].fxo.onhook = 0; + 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); + } +#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); +#endif + wr->mod[mod_no].fxo.battery = 1; + wr->mod[mod_no].fxo.nobatttimer = 0; + wr->mod[mod_no].fxo.battdebounce = wr->battdebounce; + } else if (wr->mod[mod_no].fxo.battery) + wr->mod[mod_no].fxo.battdebounce = wr->battdebounce; + + if (wr->mod[mod_no].fxo.lastpol >= 0) { + if (b < 0) { + wr->mod[mod_no].fxo.lastpol = -1; + wr->mod[mod_no].fxo.polaritydebounce = POLARITY_DEBOUNCE; + } + } + if (wr->mod[mod_no].fxo.lastpol <= 0) { + if (b > 0) { + wr->mod[mod_no].fxo.lastpol = 1; + wr->mod[mod_no].fxo.polaritydebounce = POLARITY_DEBOUNCE; + } + } + } else { + /* 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) { + wr->mod[mod_no].fxo.polaritydebounce--; + 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 (%u)\n", + wr->devname, + mod_no + 1, + wr->mod[mod_no].fxo.polarity, + wr->mod[mod_no].fxo.lastpol, + (u32)SYSTEM_TICKS); + if (wr->mod[mod_no].fxo.polarity){ + zt_qevent_lock(&wr->chans[mod_no], + ZT_EVENT_POLARITY); + } + wr->mod[mod_no].fxo.polarity = + wr->mod[mod_no].fxo.lastpol; + } + } + } + return; +} + +static void wp_tdmv_remora_proslic_check_hook(wp_tdmv_remora_t *wr, int mod_no) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + int hook; + char res; + + WAN_ASSERT1(wr->card == NULL); + card = wr->card; + fe = &card->fe; + /* For some reason we have to debounce the + hook detector. */ + +#if defined(REG_SHADOW) + res = wr->reg0shadow[mod_no]; +#else + res = READ_RM_REG(mod_no, 68); +#endif + hook = (res & 1); + if (hook != wr->mod[mod_no].fxs.lastrxhook) { + /* Reset the debounce (must be multiple of 4ms) */ + wr->mod[mod_no].fxs.debounce = 4 * (4 * 8); + DEBUG_TDMV( + "%s: Module %d: Resetting debounce hook %d, %d\n", + wr->devname, mod_no + 1, hook, + wr->mod[mod_no].fxs.debounce); + } else { + if (wr->mod[mod_no].fxs.debounce > 0) { + wr->mod[mod_no].fxs.debounce-= 16 * ZT_CHUNKSIZE; + DEBUG_TDMV( + "%s: Module %d: Sustaining hook %d, %d\n", + wr->devname, mod_no + 1, + hook, wr->mod[mod_no].fxs.debounce); + if (!wr->mod[mod_no].fxs.debounce) { + DEBUG_TDMV( + "%s: Module %d: Counted down debounce, newhook: %d\n", + wr->devname, + mod_no + 1, + hook); + wr->mod[mod_no].fxs.debouncehook = hook; + } + if (!wr->mod[mod_no].fxs.oldrxhook && wr->mod[mod_no].fxs.debouncehook) { + /* Off hook */ + DEBUG_TDMV( + "%s: Module %d: Going off hook\n", + wr->devname, mod_no + 1); + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); +#if 0 + if (robust) + wp_init_proslic(wc, card, 1, 0, 1); +#endif + wr->mod[mod_no].fxs.oldrxhook = 1; + + } else if (wr->mod[mod_no].fxs.oldrxhook && !wr->mod[mod_no].fxs.debouncehook) { + /* On hook */ + DEBUG_TDMV( + "%s: Module %d: Going on hook\n", + wr->devname, mod_no + 1); + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); + wr->mod[mod_no].fxs.oldrxhook = 0; + } + } + } + wr->mod[mod_no].fxs.lastrxhook = hook; +} + +static int wp_tdmv_remora_check_hook(sdla_fe_t *fe, int mod_no) +{ + sdla_t *card = fe->card; + wan_tdmv_t *wan_tdmv = NULL; + wp_tdmv_remora_t *wr = NULL; + + wan_tdmv = &card->wan_tdmv; + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS) { + wp_tdmv_remora_proslic_check_hook(wr, mod_no); + } else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO) { + wp_tdmv_remora_voicedaa_check_hook(wr, mod_no); + } + + return 0; +} + +static int wp_tdmv_remora_hook(sdla_fe_t *fe, int mod_no, int off_hook) +{ + sdla_t *card = fe->card; + wan_tdmv_t *wan_tdmv = NULL; + wp_tdmv_remora_t *wr = NULL; + + wan_tdmv = &card->wan_tdmv; + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + if (off_hook){ + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); + }else{ + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); + } + wr->mod[mod_no].fxs.lastrxhook = off_hook; + return 0; +} + + +/****************************************************************************** +** wp_tdmv_remora_init() - +** +** OK +*/ +int wp_tdmv_remora_init(wan_tdmv_iface_t *iface) +{ + WAN_ASSERT(iface == NULL); + + memset(iface, 0, sizeof(wan_tdmv_iface_t)); + iface->check_mtu = wp_tdmv_remora_check_mtu; + iface->create = wp_tdmv_remora_create; + iface->remove = wp_tdmv_remora_remove; + iface->reg = wp_tdmv_remora_reg; + iface->unreg = wp_tdmv_remora_unreg; + iface->software_init = wp_tdmv_remora_software_init; + iface->state = wp_tdmv_remora_state; + iface->running = wp_tdmv_remora_running; + iface->is_rbsbits = wp_tdmv_remora_is_rbsbits; + iface->rx_tx_span = wp_tdmv_remora_rx_tx_span; + iface->rx_chan = wp_tdmv_remora_rx_chan; + iface->ec_span = wp_tdmv_remora_ec_span; + + return 0; +} + +static int wp_remora_chanconfig(struct zt_chan *chan, int sigtype) +{ + wp_tdmv_remora_t *wr = NULL; + sdla_t *card = NULL; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wr = chan->pvt; + card = wr->card; + + DEBUG_TDMV("%s: Configuring chan %d SigType %i..\n", wr->devname, chan->chanpos, sigtype); + +#ifdef ZT_POLICY_WHEN_FULL + if (WAN_FE_NETWORK_SYNC(&card->fe)) { + chan->txbufpolicy = ZT_POLICY_WHEN_FULL; + chan->txdisable = 1; + } +#endif + + return 0; +} + +static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + wp_tdmv_remora_t *wr = wan_tdmv->sc; + int x = 0, num = 0; + + WAN_ASSERT(wr == NULL); + WAN_ASSERT(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + if (wan_test_bit(WP_TDMV_REGISTER, &wr->flags)){ + 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, "WRTDM/%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->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)){ + + sprintf(wr->chans[x].name, "WRTDM/%d/%d", wr->num, x); + DEBUG_TDMV("%s: Configure Module %d for voice (%s, type %s)!\n", + wr->devname, + x + 1, + wr->chans[x].name, + WP_REMORA_DECODE_TYPE(fe->rm_param.mod[x].type)); + if (fe->rm_param.mod[x].type == MOD_TYPE_FXO){ + wr->chans[x].sigcap = ZT_SIG_FXSKS | + ZT_SIG_FXSLS | + ZT_SIG_SF | + ZT_SIG_CLEAR; + }else if (fe->rm_param.mod[x].type == MOD_TYPE_FXS){ + wr->chans[x].sigcap = ZT_SIG_FXOKS | + ZT_SIG_FXOLS | + ZT_SIG_FXOGS | + ZT_SIG_SF | + ZT_SIG_EM | + ZT_SIG_CLEAR; + } + wr->chans[x].chanpos = x+1; + wr->chans[x].pvt = wr; + + num++; + }else{ + + sprintf(wr->chans[x].name, "WRTDM/%d/%d", wr->num, x); + DEBUG_TEST("%s: Not used module %d!\n", + wr->devname, + x + 1); + wr->chans[x].sigcap = ZT_SIG_CLEAR; + wr->chans[x].chanpos = x+1; + wr->chans[x].pvt = wr; + num++; + } + } + wr->span.pvt = wr; + wr->span.chans = wr->chans; + wr->span.channels = num/*wr->max_timeslots*/; + wr->span.hooksig = wp_remora_zap_hooksig; + wr->span.open = wp_remora_zap_open; + wr->span.close = wp_remora_zap_close; + wr->span.flags = ZT_FLAG_RBS; + wr->span.ioctl = wp_remora_zap_ioctl; + wr->span.watchdog = wp_remora_zap_watchdog; + + wr->span.chanconfig = wp_remora_chanconfig; + + /* Set this pointer only if card has hw echo canceller module */ + if (wr->hwec == WANOPT_YES && card->wandev.ec_dev){ + wr->span.echocan = wp_remora_zap_hwec; + } + +#if defined(__LINUX__) + init_waitqueue_head(&wr->span.maintq); +#endif + if (zt_register(&wr->span, 0)) { + DEBUG_EVENT("%s: Unable to register span with zaptel\n", + wr->devname); + 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_remora_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("%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; +} + +/****************************************************************************** +** wp_tdmv_release() - +** +** OK +*/ +static void wp_tdmv_release(wp_tdmv_remora_t *wr) +{ + 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_remora_t *wan_remora_search(sdla_t * card) +{ + return NULL; +} + +/****************************************************************************** +** wp_tdmv_remora_check_mtu() - +** +** OK +*/ +static int wp_tdmv_remora_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu) +{ + sdla_t *card = (sdla_t*)pcard; + int x, num_of_channels = 0, max_channels; + + max_channels = WAN_FE_MAX_CHANNELS(&card->fe); + for (x = 0; x < max_channels; x++) { + if (wan_test_bit(x,×lot_map)){ + num_of_channels++; + } + } + *mtu = ZT_CHUNKSIZE * num_of_channels; + return 0; +} + +/****************************************************************************** +** wp_tdmv_remora_create() - +*tdmv_* +** OK +*/ +static int wp_tdmv_remora_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) +{ + sdla_t *card = (sdla_t*)pcard; + wp_tdmv_remora_t *wr = NULL; + wan_tdmv_t *tmp = NULL; + + WAN_ASSERT(card == NULL); + WAN_ASSERT(tdmv_conf->span_no == 0); + wr = wan_remora_search(card); + if (wr){ + DEBUG_EVENT("%s: AFT remora FXO/FXS card already configured!\n", + card->devname); + return -EINVAL; + } + /* 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.rm_param.max_fe_channels; + card->wan_tdmv.spanno = tdmv_conf->span_no; + card->wandev.fe_notify_iface.hook_state = wp_tdmv_remora_hook; + card->wandev.fe_notify_iface.check_hook_state = wp_tdmv_remora_check_hook; + + wr = wan_malloc(sizeof(wp_tdmv_remora_t)); + if (wr == NULL){ + return -ENOMEM; + } + memset(wr, 0x0, sizeof(wp_tdmv_remora_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.rm_param.max_fe_channels; + wr->max_rxtx_len = 0; + 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); + }else{ + WAN_LIST_INSERT_HEAD(&wan_tdmv_head, &card->wan_tdmv, next); + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_reg() - +** +** Returns: 0-31 - Return TDM Voice channel number. +** -EINVAL - otherwise +** OK +*/ +static int wp_tdmv_remora_reg( void *pcard, + wan_tdmv_if_conf_t *tdmv_conf, + unsigned int active_ch, + unsigned char 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_remora_t *wr = NULL; + int i, channo = 0; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + if (wan_test_bit(WP_TDMV_REGISTER, &wr->flags)){ + DEBUG_EVENT( + "%s: Error: Master device has already been configured!\n", + card->devname); + return -EINVAL; + } + + for(i = 0; i < wr->max_timeslots; i++){ + if (wan_test_bit(i, &active_ch) && + wan_test_bit(i, &fe->rm_param.module_map)){ + if (tdmv_conf->tdmv_echo_off){ + wan_set_bit(i, &wr->echo_off_map); + } + channo = i; + break; + } + } + + if (i == wr->max_timeslots){ + DEBUG_EVENT( + "%s: Error: TDMV iface %s failed to configure for %08X timeslots!\n", + card->devname, + wan_netif_name(dev), + active_ch); + return -EINVAL; + } + + DEBUG_EVENT( + "%s: Registering TDMV %s iface to module %d!\n", + card->devname, + WP_REMORA_DECODE_TYPE(fe->rm_param.mod[channo].type), + channo+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; + wr->hwec = ec_enable; + wp_tdmv_remora_check_mtu(card, active_ch, &wr->max_rxtx_len); + return channo; +} + + +/****************************************************************************** +** wp_tdmv_unreg() - +** +** OK +*/ +static int wp_tdmv_remora_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_remora_t *wr = NULL; + int channo = 0; + + 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_REMORA_DECODE_TYPE(fe->rm_param.mod[channo].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_remora_remove(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_remora_t *wr = NULL; + + 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; + WAN_LIST_REMOVE(wan_tdmv, next); + wp_tdmv_release(wr); + }else{ + wan_tdmv->sc = NULL; + } + return 0; +} + +static int wp_tdmv_remora_state(void* pcard, int state) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_remora_t *wr = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = (wp_tdmv_remora_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_remora_running(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_remora_t *wr = NULL; + + 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_remora_is_rbsbits() - +** +** OK +*/ +static int wp_tdmv_remora_is_rbsbits(wan_tdmv_t *wan_tdmv) +{ + return 0; +} + + +#ifdef WAN_FAKE_POLARITY +#warning "WAN_FAKE_POLARITY Enabled - Experimental" +static inline void wp_tdmv_dtmfcheck_fakepolarity(wp_tdmv_remora_t *wr, int channo, unsigned char *rxbuf) +{ + sdla_t *card = wr->card; + sdla_fe_t *fe = &card->fe; + int sample; + int dtmf=1; + + /* only look for sound on the line if dtmf flag is on, it is an fxo card and line is onhook */ + if (!dtmf || !(fe->rm_param.mod[channo].type == MOD_TYPE_FXO) || wr->mod[channo].fxo.offhook) { + return; + } + + /* don't look for noise if we're already processing it, or there is a ringing tone */ + if(!wr->mod[channo].fxo.readcid && !wr->mod[channo].fxo.wasringing && + wr->intcount > wr->mod[channo].fxo.cidtimer + 400 ) { + sample = ZT_XLAW((*rxbuf), (&(wr->chans[channo]))); + if (sample > 16000 || sample < -16000) { + wr->mod[channo].fxo.readcid = 1; + wr->mod[channo].fxo.cidtimer = wr->intcount; + DEBUG_EVENT("DTMF CLIP on %i\n",channo+1); + zt_qevent_lock(&wr->chans[channo], ZT_EVENT_POLARITY); + } + } else if(wr->mod[channo].fxo.readcid && wr->intcount > wr->mod[channo].fxo.cidtimer + 2000) { + /* reset flags if it's been a while */ + wr->mod[channo].fxo.cidtimer = wr->intcount; + wr->mod[channo].fxo.readcid = 0; + } +} +#endif + +/****************************************************************************** +** wp_tdmv_rx_chan() - +** +** OK +*/ + + +static int wp_tdmv_remora_rx_chan(wan_tdmv_t *wan_tdmv, int channo, + unsigned char *rxbuf, + unsigned char *txbuf) +{ + wp_tdmv_remora_t *wr = wan_tdmv->sc; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + 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); + + if (!IS_TDMV_UP(wr)){ + return -EINVAL; + } + card = wr->card; + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + pwr_rxtx = &wan_tdmv->chan_pwr[channo]; +#endif + +#if 0 +if (channo == 1){ +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 + +#ifdef ZT_POLICY_WHEN_FULL + /* This feature is used to change zaptel buffering that improves + faxing between analog & SMG. Enable this feature ONLY when + network sync is ON */ + if (WAN_FE_NETWORK_SYNC(&card->fe) && + wr->chans[channo].txbufpolicy != ZT_POLICY_WHEN_FULL) { + DEBUG_EVENT("%s: RX CHAN %i Setting FULL POLICY\n", + card->devname,channo); + wr->chans[channo].txbufpolicy = ZT_POLICY_WHEN_FULL; + } +#endif + +#ifdef WAN_SYNC_RX_TX_TEST + /* This feature should be used with HWDTMF enabled, otherwise + * analog will not be able to dial. This is a debugging feature + * should NEVER be used in production only for testing */ + wp_tdmv_remora_rx_chan_sync_test(card,wr,channo,rxbuf,txbuf); +#endif + + wr->chans[channo].readchunk = rxbuf; + wr->chans[channo].writechunk = txbuf; + +#ifdef WAN_FAKE_POLARITY + wp_tdmv_dtmfcheck_fakepolarity(wr,channo,rxbuf); +#endif + + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wp_tdmv_echo_check(wan_tdmv, &wr->chans[channo], channo); +#endif + + + if ((!card->wandev.ec_enable || card->wandev.ec_enable_map == 0) && + !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 (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 */ + zt_ec_chunk( + &wr->chans[channo], + wr->chans[channo].readchunk, + wr->chans[channo].writechunk); + } else { + /* This should be used without SWRING 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); + } + +#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_remora_rx_tx_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + sdla_fe_t *fe = &card->fe; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_remora_t *wr = NULL; + u_int16_t x; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + wr->intcount++; + for (x = 0; x < wr->max_timeslots; x++) { + if (!wan_test_bit(x, &wr->reg_module_map)){ + continue; + } + if (fe->rm_param.mod[x].type == MOD_TYPE_FXS){ +#if defined(REG_WRITE_SHADOW) + if (wr->mod[x].fxs.lasttxhook_update){ + WRITE_RM_REG(x, 64, wr->mod[x].fxs.lasttxhook); + wr->mod[x].fxs.lasttxhook_update = 0; + continue; + } +#endif + + if (wr->mod[x].fxs.lasttxhook == 0x4) { + /* RINGing, prepare for OHT */ + wr->mod[x].fxs.ohttimer = OHT_TIMER << 3; + if (fe->fe_cfg.cfg.remora.reversepolarity){ + /* OHT mode when idle */ + fe->rm_param.mod[x].u.fxs.idletxhookstate = 0x6; + }else{ + fe->rm_param.mod[x].u.fxs.idletxhookstate = 0x2; + } + } else { + if (wr->mod[x].fxs.ohttimer) { + wr->mod[x].fxs.ohttimer-= ZT_CHUNKSIZE; + if (!wr->mod[x].fxs.ohttimer) { + if (fe->fe_cfg.cfg.remora.reversepolarity){ + /* Switch to active */ + fe->rm_param.mod[x].u.fxs.idletxhookstate = 0x5; + }else{ + fe->rm_param.mod[x].u.fxs.idletxhookstate = 0x1; + } + if ((wr->mod[x].fxs.lasttxhook == 0x2) || (wr->mod[x].fxs.lasttxhook == 0x6)) { + /* Apply the change if appropriate */ + if (fe->fe_cfg.cfg.remora.reversepolarity){ + wr->mod[x].fxs.lasttxhook = 0x5; + }else{ + wr->mod[x].fxs.lasttxhook = 0x1; + } + WRITE_RM_REG(x, 64, wr->mod[x].fxs.lasttxhook); + } + } + } + } + + } else if (fe->rm_param.mod[x].type == MOD_TYPE_FXO) { + + if (wr->mod[x].fxo.echotune){ + DEBUG_RM("%s: Module %d: Setting echo registers: \n", + fe->name, x); + + /* Set the ACIM register */ + WRITE_RM_REG(x, 30, wr->mod[x].fxo.echoregs.acim); + + /* Set the digital echo canceller registers */ + WRITE_RM_REG(x, 45, wr->mod[x].fxo.echoregs.coef1); + WRITE_RM_REG(x, 46, wr->mod[x].fxo.echoregs.coef2); + WRITE_RM_REG(x, 47, wr->mod[x].fxo.echoregs.coef3); + WRITE_RM_REG(x, 48, wr->mod[x].fxo.echoregs.coef4); + WRITE_RM_REG(x, 49, wr->mod[x].fxo.echoregs.coef5); + WRITE_RM_REG(x, 50, wr->mod[x].fxo.echoregs.coef6); + WRITE_RM_REG(x, 51, wr->mod[x].fxo.echoregs.coef7); + WRITE_RM_REG(x, 52, wr->mod[x].fxo.echoregs.coef8); + + DEBUG_RM("%s: Module %d: Set echo registers successfully\n", + fe->name, x); + wr->mod[x].fxo.echotune = 0; + } +#if defined(REG_WRITE_SHADOW) + if (wr->reg0shadow_update[x]){ + /* Read first shadow reg */ + WRITE_RM_REG(x, 5, wr->reg0shadow[x]); + wr->reg0shadow_update[x] = 0; + } +#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 + } + + x = wr->intcount % MAX_REMORA_MODULES; + if (wan_test_bit(x, &wr->reg_module_map)) { +#if defined(REG_SHADOW) + if (fe->rm_param.mod[x].type == MOD_TYPE_FXS) { + /* Read first shadow reg */ + wr->reg0shadow[x] = READ_RM_REG(x, 68); + /* Read second shadow reg */ + wr->reg1shadow[x] = READ_RM_REG(x, 64); + /* Read third shadow reg */ + wr->reg2shadow[x] = READ_RM_REG(x, 8); + }else if (fe->rm_param.mod[x].type == MOD_TYPE_FXO) { + /* Read first shadow reg */ + wr->reg0shadow[x] = READ_RM_REG(x, 5); + /* Read second shadow reg */ + wr->reg1shadow[x] = READ_RM_REG(x, 29); + /* Read third shadow reg */ + wr->reg2shadow[x] = READ_RM_REG(x, 34); + } +#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) { + wp_tdmv_remora_proslic_recheck_sanity(wr, x); + }else if (fe->rm_param.mod[x].type == MOD_TYPE_FXO) { + wp_tdmv_remora_voicedaa_recheck_sanity(wr, x); + } + } + } + + if (!(wr->intcount % 10000)) { + /* Accept an alarm once per 10 seconds */ + for (x = 0; x < wr->max_timeslots; x++) + if (wan_test_bit(x, &wr->reg_module_map) && + (fe->rm_param.mod[x].type == MOD_TYPE_FXS)) { + if (wr->mod[x].fxs.palarms){ + wr->mod[x].fxs.palarms--; + } + } + } + + zt_receive(&wr->span); + zt_transmit(&wr->span); + + return 0; +} + +static int wp_tdmv_remora_ec_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_remora_t *wr = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + zt_ec_span(&wr->span); + + return 0; + +} + +static void wp_tdmv_remora_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_remora_t *wr = NULL; + + WAN_ASSERT1(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + if (event->type == WAN_EVENT_EC_DTMF){ + 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_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( + "[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( + &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; +} + + +#ifdef WAN_SYNC_RX_TX_TEST + +#warning "WAN_SYNC_RX_TX_TEST: Test option Enabled" + +static unsigned char gstat_rx_chan[1024]; +static unsigned char gstat_tx_chan[1024]; +static unsigned char gstat_sync[1024]; +static unsigned char gstat_sync_stat[1024]; + +static int wp_tdmv_remora_rx_chan_sync_test(sdla_t *card, wp_tdmv_remora_t *wr, int channo, + unsigned char *rxbuf, + unsigned char *txbuf) + +{ + + /* This feature should be used with HWDTMF enabled, otherwise + * analog will not be able to dial. This is a debugging feature + * should NEVER be used in production only for testing */ + if (1 || wan_test_bit(channo,&card->wandev.rtp_tap_call_map)) { + +#if 0 + if (*(unsigned int*)&wr->chans[channo].writechunk[0] == 0xD5D5D5D5 && + *(unsigned int*)&wr->chans[channo].writechunk[4] == 0xD5D5D5D5) { + DEBUG_EVENT("%s: Chan %i Rx Frame Slip!\n", + card->devname,channo); + } +#endif + + int i; + + /* Pass up a sequence */ + for (i=0;i<8;i++) { + rxbuf[i]=++gstat_rx_chan[channo]; + } + + + /* Check for incoming sequence */ + if (gstat_sync_stat[channo] == 0) { + DEBUG_EVENT("%s: Starting to hunt for sync on %i map=0x%lX\n", + card->devname,channo, card->wandev.rtp_tap_call_map); + gstat_sync_stat[channo]++; + } + + for (i=0;i<8;i++) { + + if (gstat_sync[channo] == 0) { + + if (wr->chans[channo].writechunk[i] == 0x01) { + gstat_sync[channo] = 1; + gstat_tx_chan[channo]=wr->chans[channo].writechunk[i]; + DEBUG_EVENT("%s: Chan=%i Sync got=%i offset=%i\n", + card->devname,channo,wr->chans[channo].writechunk[i],i); + } + + } else { + + gstat_tx_chan[channo]++; + if (gstat_tx_chan[channo] != wr->chans[channo].writechunk[i]) { + int x; + DEBUG_EVENT("%s: Chan=%i Out of Sync expecting=%i got=%i offset=%i\n", + card->devname,channo, + gstat_tx_chan[channo],wr->chans[channo].writechunk[i],i); + + gstat_tx_chan[channo] = wr->chans[channo].writechunk[i]; + gstat_sync[channo] = 0; + + for (x=0;x<8;x++){ + DEBUG_EVENT("chan=%i off=%i data=%i\n",channo,x,wr->chans[channo].writechunk[x]); + } + } + } + } + } + + return 0; +} +#endif diff --git a/patches/kdrivers/src/net/sdla_tdmv.c b/patches/kdrivers/src/net/sdla_tdmv.c index 96e318d..656110d 100644 --- a/patches/kdrivers/src/net/sdla_tdmv.c +++ b/patches/kdrivers/src/net/sdla_tdmv.c @@ -16,6 +16,7 @@ * Jul 22, 2001 Nenad Corbic Initial version. * Oct 01, 2001 Gideon Hack Modifications for interrupt usage. * Aug 9, 2005 David Rokhvarg Added Echo Detection and Control (EDAC). + * Sep 06, 2008 Moises Silva DAHDI support. ****************************************************************************** */ /* @@ -33,11 +34,11 @@ # include # include # include /* WANPIPE TDM Voice definitions */ -# include +# include /* Map of Zaptel -> DAHDI definitions */ #elif (defined __WINDOWS__) # include #else -# include +# include /* Map of Zaptel -> DAHDI definitions */ # include # include # include @@ -162,6 +163,9 @@ typedef struct wp_tdmv_pvt_area #endif /* T1 signalling */ struct zt_span span; /* Span */ +#ifdef DAHDI_ISSUES + struct zt_chan *chans_ptrs[31]; /* Channel ptrs */ +#endif struct zt_chan chans[31]; /* Channels */ unsigned char ec_chunk1[31][ZT_CHUNKSIZE]; unsigned char ec_chunk2[31][ZT_CHUNKSIZE]; @@ -334,6 +338,9 @@ static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) sdla_t *card = (sdla_t*)pcard; wp_tdmv_softc_t *wp = NULL; wan_tdmv_t *tmp = NULL; +#ifdef DAHDI_ISSUES + int i; +#endif WAN_ASSERT(card == NULL); WAN_ASSERT(tdmv_conf->span_no == 0); @@ -376,6 +383,11 @@ static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) wp->max_rxtx_len = 0; wan_spin_lock_irq_init(&wp->lockirq, "wan_te1tdmv_lock"); wan_spin_lock_irq_init(&wp->tx_rx_lockirq, "wan_te1tdmv_txrx_lock"); +#ifdef DAHDI_ISSUES + for (i = 0; i < sizeof(wp->chans)/sizeof(wp->chans[0]); i++) { + wp->chans_ptrs[i] = &wp->chans[i]; + } +#endif /* AHDLC */ if (tdmv_conf->dchan){ /* PRI signalling is selected with hw HDLC (dchan is not 0) */ @@ -770,11 +782,11 @@ static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_DDLB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_ACTIVATE_LB); + WAN_TE1_LB_ENABLE); wp->span.maintstat = ZT_MAINT_REMOTELOOP; } }else{ @@ -787,11 +799,11 @@ static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_DDLB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); wp->span.maintstat = ZT_MAINT_NONE; } }else{ @@ -1071,7 +1083,11 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) wp->span.open = wp_tdmv_open; wp->span.close = wp_tdmv_close; wp->span.channels = wp->max_timeslots; +#ifdef DAHDI_ISSUES + wp->span.chans = wp->chans_ptrs; +#else wp->span.chans = wp->chans; +#endif wp->span.flags = ZT_FLAG_RBS; wp->span.ioctl = wp_tdmv_ioctl; @@ -1109,12 +1125,17 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) wp->chans[x].name); wp->chans[x].sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_EM_E1 | - ZT_SIG_FXSLS | ZT_SIG_FXSGS | - ZT_SIG_FXSKS | ZT_SIG_FXOLS | - ZT_SIG_FXOGS | ZT_SIG_FXOKS | - ZT_SIG_CAS | ZT_SIG_DACS_RBS + ZT_SIG_FXSLS | ZT_SIG_FXSGS | + ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_DACS_RBS | + ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) - | ZT_SIG_HARDHDLC + | ZT_SIG_HARDHDLC +#endif +#if defined(ZT_SIG_MTP2) + | ZT_SIG_MTP2 +#endif +#if defined(ZT_SIG_SF) + | ZT_SIG_SF #endif ; }else{ @@ -1200,10 +1221,17 @@ static int wp_tdmv_startup(struct zt_span *span) /* initialize the start value for the entire chunk of last ec buffer */ for(i = 0; i < span->channels; i++){ +#ifdef DAHDI_ISSUES + memset(wp->ec_chunk1[i], + ZT_LIN2X(0,span->chans[i]),ZT_CHUNKSIZE); + memset(wp->ec_chunk2[i], + ZT_LIN2X(0,span->chans[i]),ZT_CHUNKSIZE); +#else memset(wp->ec_chunk1[i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); memset(wp->ec_chunk2[i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); +#endif } @@ -1290,11 +1318,11 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_DDLB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); break; case ZT_MAINT_LOCALLOOP: DEBUG_EVENT("%s: T1: Set to local loopback mode (local/no remote loop)\n", @@ -1302,11 +1330,11 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_DDLB_MODE, - WAN_TE1_ACTIVATE_LB); + WAN_TE1_LB_ENABLE); break; case ZT_MAINT_REMOTELOOP: DEBUG_EVENT("%s: T1: Set to remote loopback mode (no local/remote loop)\n", @@ -1314,11 +1342,11 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_ACTIVATE_LB); + WAN_TE1_LB_ENABLE); card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_LINELB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); break; case ZT_MAINT_LOOPUP: DEBUG_EVENT("%s: T1: Send loopup code\n", @@ -1326,7 +1354,7 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_TX_LB_MODE, - WAN_TE1_ACTIVATE_LB); + WAN_TE1_LB_ENABLE); break; case ZT_MAINT_LOOPDOWN: DEBUG_EVENT("%s: T1: Send loopdown code\n", @@ -1334,7 +1362,7 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) card->wandev.fe_iface.set_fe_lbmode( &wp->card->fe, WAN_TE1_TX_LB_MODE, - WAN_TE1_DEACTIVATE_LB); + WAN_TE1_LB_DISABLE); break; case ZT_MAINT_LOOPSTOP: DEBUG_EVENT("%s: T1: Stop sending loop code\n", @@ -2513,14 +2541,26 @@ static void wp_tdmv_callback_dtmf (void* card_id, wan_event_t *event) if (event->dtmf_type == WAN_EC_TONE_PRESENT){ wp->dtmfactive |= (1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wp->span.chans[event->channel-1], + (ZT_EVENT_DTMFDOWN | event->digit)); +#else zt_qevent_lock( &wp->span.chans[event->channel-1], (ZT_EVENT_DTMFDOWN | event->digit)); +#endif }else{ wp->dtmfactive &= ~(1 << event->channel); +#ifdef DAHDI_ISSUES + zt_qevent_lock( + wp->span.chans[event->channel-1], + (ZT_EVENT_DTMFUP | event->digit)); +#else zt_qevent_lock( &wp->span.chans[event->channel-1], (ZT_EVENT_DTMFUP | event->digit)); +#endif } return; } diff --git a/patches/kdrivers/src/net/sdla_tdmv_dummy.c b/patches/kdrivers/src/net/sdla_tdmv_dummy.c index 8f7d96a..616e4c1 100644 --- a/patches/kdrivers/src/net/sdla_tdmv_dummy.c +++ b/patches/kdrivers/src/net/sdla_tdmv_dummy.c @@ -12,6 +12,7 @@ * 2 of the License, or (at your option) any later version. * ============================================================================ * Mar 12, 2008 David Yat Sin Initial Version +* Sep 06, 2008 Moises Silva DAHDI support *****************************************************************************/ #if defined(__FreeBSD__) || defined(__OpenBSD__) @@ -24,7 +25,7 @@ # include # include /* WANPIPE TDM Voice definitions */ # include -# include +# include /* Map of Zaptel -> DAHDI definitions */ #elif (defined __WINDOWS__) # include #else @@ -34,12 +35,15 @@ # include # include /* WANPIPE TDM Voice definitions */ # include -# include +# include /* Map of Zaptel -> DAHDI definitions */ #endif typedef struct sdla_tdmv_dummy { struct zt_span span; +#ifdef DAHDI_ISSUES + struct zt_chan *chan_ptr; +#endif struct zt_chan chan; }sdla_tdmv_dummy_t; @@ -75,7 +79,12 @@ void* sdla_tdmv_dummy_register(void) sprintf(wpd->span.name, "SDLA_DUMMY"); snprintf(wpd->span.desc, sizeof(wpd->span.desc) - 1, "%s (source: AFT-HW) %d", wpd->span.name, 1); +#ifdef DAHDI_ISSUES + wpd->chan_ptr = &wpd->chan; + wpd->span.chans = &wpd->chan_ptr; +#else wpd->span.chans = &wpd->chan; +#endif wpd->span.channels = 0; /* no channels */ wpd->span.deflaw = ZT_LAW_MULAW; wpd->span.pvt = wpd; diff --git a/patches/kdrivers/src/net/sdla_te1.c b/patches/kdrivers/src/net/sdla_te1.c index 83860ee..bb45a7a 100644 --- a/patches/kdrivers/src/net/sdla_te1.c +++ b/patches/kdrivers/src/net/sdla_te1.c @@ -4536,7 +4536,7 @@ static int sdla_te_post_init(void *pfe) fe_event.type = TE_LINKDOWN_TIMER; fe_event.delay = POLLING_TE1_TIMER; sdla_te_add_event(fe, &fe_event); - sdla_te_add_timer(fe, HZ); + sdla_te_add_timer(fe, POLLING_TE1_TIMER); return 0; } @@ -6240,28 +6240,37 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) ****************************************************************************** */ static int -sdla_te_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) +sdla_te_set_lbmode(sdla_fe_t *fe, unsigned char mode, unsigned char enable) { int err = 1; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - switch(type){ + switch(mode){ case WAN_TE1_LINELB_MODE: - err = sdla_te_linelb(fe, mode); + err = sdla_te_linelb(fe, enable); break; case WAN_TE1_PAYLB_MODE: - err = sdla_te_paylb(fe, mode); + err = sdla_te_paylb(fe, enable); break; case WAN_TE1_DDLB_MODE: - err = sdla_te_ddlb(fe, mode); + err = sdla_te_ddlb(fe, enable); break; case WAN_TE1_TX_LB_MODE: - err = sdla_te_lb(fe, mode); + err = sdla_te_lb(fe, enable); break; + default: + DEBUG_EVENT("%s: Unsupported loopback mode (%s)!\n", + fe->name, + WAN_TE1_LB_MODE_DECODE(mode)); + return -EINVAL; } - + DEBUG_EVENT("%s: %s %s mode... %s\n", + fe->name, + WAN_TE1_LB_ACTION_DECODE(enable), + WAN_TE1_LB_MODE_DECODE(mode), + (!err) ? "Done" : "Failed"); return err; } @@ -6279,16 +6288,10 @@ static int sdla_te_linelb(sdla_fe_t* fe, unsigned char mode) WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - if (mode == WAN_TE1_ACTIVATE_LB){ - DEBUG_EVENT("%s: %s Line Loopback mode activated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); + if (mode == WAN_TE1_LB_ENABLE){ WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) | BIT_MASTER_DIAG_LINELB); }else{ - DEBUG_EVENT("%s: %s Line Loopback mode deactivated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) & ~BIT_MASTER_DIAG_LINELB); } @@ -6308,16 +6311,10 @@ static int sdla_te_paylb(sdla_fe_t* fe, unsigned char mode) { WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - if (mode == WAN_TE1_ACTIVATE_LB){ - DEBUG_EVENT("%s: %s Payload Loopback mode activated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); + if (mode == WAN_TE1_LB_ENABLE){ WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) | BIT_MASTER_DIAG_PAYLB); }else{ - DEBUG_EVENT("%s: %s Payload Loopback mode deactivated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) & ~BIT_MASTER_DIAG_PAYLB); } @@ -6337,16 +6334,10 @@ static int sdla_te_ddlb(sdla_fe_t* fe, unsigned char mode) { WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - if (mode == WAN_TE1_ACTIVATE_LB){ - DEBUG_EVENT("%s: %s Diagnostic Digital Loopback mode activated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); + if (mode == WAN_TE1_LB_ENABLE){ WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) | BIT_MASTER_DIAG_DDLB); }else{ - DEBUG_EVENT("%s: %s Diagnostic Digital Loopback mode deactivated.\n", - fe->name, - FE_MEDIA_DECODE(fe)); WRITE_REG(REG_MASTER_DIAG, READ_REG(REG_MASTER_DIAG) & ~BIT_MASTER_DIAG_DDLB); } @@ -6439,7 +6430,7 @@ static void sdla_te_timer(unsigned long pfe) sdla_te_polling(fe); } }else{ - sdla_te_add_timer(fe, 1000); + sdla_te_add_timer(fe, POLLING_TE1_TIMER); } return; } @@ -6555,7 +6546,7 @@ static int sdla_te_polling(sdla_fe_t* fe) 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); + sdla_te_add_timer(fe, POLLING_TE1_TIMER); return 0; } fe_event = WAN_LIST_FIRST(&fe->event); @@ -6575,7 +6566,7 @@ static int sdla_te_polling(sdla_fe_t* fe) /* Sending T1 activation/deactivation loopback signal */ if (fe->te_param.lb_tx_cnt > 11){ WRITE_REG(REG_T1_XBOC_CODE, - (fe->te_param.lb_tx_cmd == WAN_TE1_ACTIVATE_LB) ? + (fe->te_param.lb_tx_cmd == WAN_TE1_LB_ENABLE) ? LINELB_ACTIVATE_CODE : LINELB_DEACTIVATE_CODE); }else if (fe->te_param.lb_tx_cnt){ WRITE_REG(REG_T1_XBOC_CODE, LINELB_DS1LINE_ALL); @@ -6590,7 +6581,7 @@ static int sdla_te_polling(sdla_fe_t* fe) }else{ DEBUG_EVENT("%s: T1 loopback %s signal sent.\n", fe->name, - (fe->te_param.lb_tx_cmd == WAN_TE1_ACTIVATE_LB) ? + (fe->te_param.lb_tx_cmd == WAN_TE1_LB_ENABLE) ? "activation" : "deactivation"); wan_clear_bit(LINELB_WAITING,(void*)&fe->te_param.critical); fe->te_param.lb_tx_cmd = 0x00; @@ -6689,7 +6680,7 @@ static int sdla_te_polling(sdla_fe_t* fe) if (fe_event){ sdla_te_add_timer(fe, fe_event->delay); }else{ - sdla_te_add_timer(fe, HZ); + sdla_te_add_timer(fe, POLLING_TE1_TIMER); } return 0; } @@ -6723,7 +6714,7 @@ static int sdla_te_lb(sdla_fe_t* fe, unsigned char mode) DEBUG_TE1("%s: Sending %s loopback %s signal...\n", fe->name, FE_MEDIA_DECODE(fe), - (mode == WAN_TE1_ACTIVATE_LB) ? + (mode == WAN_TE1_LB_ENABLE) ? "activation" : "deactivation"); fe->te_param.lb_tx_cmd = mode; fe->te_param.lb_tx_cnt = LINELB_CODE_CNT + LINELB_CHANNEL_CNT + 1; @@ -6750,17 +6741,21 @@ static int sdla_te_lb(sdla_fe_t* fe, unsigned char mode) static int sdla_te_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) { wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; + wan_femedia_t *fe_media; sdla_fe_debug_t *fe_debug; sdla_fe_timer_event_t fe_event; int err = 0; switch(udp_cmd->wan_cmd_command){ case WAN_GET_MEDIA_TYPE: - data[0] = (IS_T1_FEMEDIA(fe) ? WAN_MEDIA_T1 : - IS_E1_FEMEDIA(fe) ? WAN_MEDIA_E1 : - WAN_MEDIA_NONE); + fe_media = (wan_femedia_t*)data; + memset(fe_media, 0, sizeof(wan_femedia_t)); + fe_media->media = fe->fe_cfg.media; + fe_media->sub_media = fe->fe_cfg.sub_media; + fe_media->chip_id = WAN_TE_CHIP_PMC; + fe_media->max_ports = fe->fe_max_ports; udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(unsigned char); + udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t); break; case WAN_FE_LB_MODE: diff --git a/patches/kdrivers/src/net/sdla_te3.c b/patches/kdrivers/src/net/sdla_te3.c index c2fcf48..bb4f1ed 100644 --- a/patches/kdrivers/src/net/sdla_te3.c +++ b/patches/kdrivers/src/net/sdla_te3.c @@ -79,10 +79,16 @@ WAN_TE3_BIT_OOF_ALARM)) /* DS3: Define E3 alarm states: LOS OOF YEL */ +#if 0 #define IS_E3_ALARM(alarm) ((alarm) & \ (WAN_TE3_BIT_LOS_ALARM | \ WAN_TE3_BIT_YEL_ALARM | \ WAN_TE3_BIT_OOF_ALARM)) +#endif + +#define IS_E3_ALARM(alarm) ((alarm) & \ + (WAN_TE3_BIT_YEL_ALARM | \ + WAN_TE3_BIT_OOF_ALARM)) /****************************************************************************** ** FUNCTION DEFINITIONS @@ -99,10 +105,33 @@ static int sdla_te3_udp(sdla_fe_t *fe, void*, unsigned char*); 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_post_init(void* pfe); +static int sdla_te3_pre_release(void* pfe); 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); +static int sdla_te3_old_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode); +static int sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode); + +static int sdla_te3_set_lb_modes_all(sdla_fe_t *fe, unsigned char type, unsigned char mode) +{ + int err; + sdla_t *card=fe->card; + + DEBUG_TEST("%s: NENAD %s LOOP\n",fe->name, + mode==WAN_TE3_LB_DISABLE?"Disable":"Enable"); + + if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ + err = sdla_te3_old_set_lb_modes(fe, type,mode); + }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ + err = sdla_te3_set_lb_modes(fe, type,mode); + } + + return 0; +} + + /****************************************************************************** * sdla_te3_get_fe_status() * @@ -157,9 +186,9 @@ static int sdla_te3_get_fe_status(sdla_fe_t *fe, unsigned char *status, int notu */ 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; + int err; + err=sdla_te3_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); + return err; } /****************************************************************************** @@ -189,16 +218,39 @@ static int sdla_te3_set_status(sdla_fe_t *fe) }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_param.te3.e3_connect_delay=0; + + if (fe->fe_param.te3.e3_lb_ctrl == 1) { + fe->fe_param.te3.e3_lb_ctrl = 2; + } else { + sdla_te3_set_lb_modes_all(fe,WAN_TE3_LIU_LB_REMOTE,WAN_TE3_LB_ENABLE); + fe->fe_param.te3.e3_lb_ctrl=0; + } + //sdla_te3_set_lb_modes_all(fe,WAN_TE3_LIU_LB_REMOTE,WAN_TE3_LB_DISABLE); + + DEBUG_EVENT("%s: E3 disconnected! State=%i\n", + fe->name,fe->fe_param.te3.e3_lb_ctrl); 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; + + fe->fe_param.te3.e3_connect_delay++; + if (fe->fe_param.te3.e3_connect_delay >= 5) { + fe->fe_param.te3.e3_connect_delay=0; + + if (fe->fe_param.te3.e3_lb_ctrl == 0) { + fe->fe_param.te3.e3_lb_ctrl=1; + sdla_te3_set_lb_modes_all(fe,WAN_TE3_LIU_LB_REMOTE,WAN_TE3_LB_DISABLE); + } + + DEBUG_EVENT("%s: E3 connected! State=%i\n", + fe->name,fe->fe_param.te3.e3_lb_ctrl); + fe->fe_status = FE_CONNECTED; + } } + } }else{ return -EINVAL; @@ -243,7 +295,7 @@ static int sdla_ds3_rx_isr(sdla_fe_t *fe) /* 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_FE_FRAME(fe) == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_CPBIT_ERR){ DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", fe->name); } @@ -291,7 +343,7 @@ static int sdla_ds3_rx_isr(sdla_fe_t *fe) 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_FE_FRAME(fe) == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_AIC){ DEBUG_TE3("%s: AIC bit-field status %s!\n", fe->name, (status & BIT_RxDS3_STATUS_RxAIC) ? "ON" : "OFF"); @@ -699,10 +751,10 @@ 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_ACTION_DECODE(mode), WAN_TE3_LB_TYPE_DECODE(type)); - if (mode == WAN_TE3_DEACTIVATE_LB){ + if (mode == WAN_TE3_LB_DISABLE){ fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_LLB; fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_RLB; }else{ @@ -739,11 +791,11 @@ sdla_te3_set_lb_modes(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_TE3_LB_MODE_DECODE(mode), + WAN_TE3_LB_ACTION_DECODE(mode), WAN_TE3_LB_TYPE_DECODE(type)); data = READ_REG(REG_LINE_INTERFACE_DRIVE); - if (mode == WAN_TE3_DEACTIVATE_LB){ + if (mode == WAN_TE3_LB_DISABLE){ data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; }else{ @@ -772,6 +824,58 @@ sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) return 0; } +/****************************************************************************** + * sdla_te3_old_get_lb() + * + * Description: + * Arguments: + * Returns: + *****************************************************************************/ +static u32 sdla_te3_old_get_lb(sdla_fe_t *fe) +{ + u32 type = 0; + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + if ((fe->te3_param.cpld_status & BIT_CPLD_STATUS_LLB) && + (fe->te3_param.cpld_status & BIT_CPLD_STATUS_RLB)){ + wan_set_bit(WAN_TE3_LIU_LB_DIGITAL, &type); + }else if (fe->te3_param.cpld_status & BIT_CPLD_STATUS_LLB){ + wan_set_bit(WAN_TE3_LIU_LB_ANALOG, &type); + }else if (fe->te3_param.cpld_status & BIT_CPLD_STATUS_RLB){ + wan_set_bit(WAN_TE3_LIU_LB_REMOTE, &type); + } + return type; +} + +/****************************************************************************** + * sdla_tee_get_lb() + * + * Description: + * Arguments: + * Returns: + *****************************************************************************/ +static u32 sdla_te3_get_lb(sdla_fe_t *fe) +{ + u32 type = 0; + u8 data; + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + data = READ_REG(REG_LINE_INTERFACE_DRIVE); + if ((data & BIT_LINE_INTERFACE_DRIVE_LLOOP) && (data & BIT_LINE_INTERFACE_DRIVE_RLOOP)){ + wan_set_bit(WAN_TE3_LIU_LB_DIGITAL, &type); + }else if (data & BIT_LINE_INTERFACE_DRIVE_LLOOP){ + wan_set_bit(WAN_TE3_LIU_LB_ANALOG, &type); + }else if (data & BIT_LINE_INTERFACE_DRIVE_RLOOP){ + wan_set_bit(WAN_TE3_LIU_LB_REMOTE, &type); + } + return type; +} + + /****************************************************************************** * sdla_te3_udp() * @@ -782,18 +886,34 @@ sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) */ 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; + sdla_t *card = (sdla_t*)fe->card; + wan_femedia_t *fe_media = NULL; + sdla_fe_debug_t *fe_debug = NULL; + 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; + fe_media = (wan_femedia_t*)data; + memset(fe_media, 0, sizeof(wan_femedia_t)); + fe_media->media = fe->fe_cfg.media; udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(unsigned char); + udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t); break; case WAN_FE_LB_MODE: + if (!data[0]){ + u32 mode = 0; + if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ + mode = sdla_te3_old_get_lb(fe); + }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ + mode = sdla_te3_get_lb(fe); + } + memcpy(&data[0], (u8*)&mode, sizeof(mode)); + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + udp_cmd->wan_cmd_data_len = sizeof(mode); + break; + } /* Activate/Deactivate Line Loopback modes */ if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ err = sdla_te3_old_set_lb_modes(fe, data[0], data[1]); @@ -835,6 +955,26 @@ static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) udp_cmd->wan_cmd_data_len = sizeof(sdla_te_cfg_t); break; + case WAN_FE_SET_DEBUG_MODE: + fe_debug = (sdla_fe_debug_t*)&data[0]; + switch(fe_debug->type){ + case WAN_FE_DEBUG_REG: + if (fe_debug->fe_debug_reg.read){ + fe_debug->fe_debug_reg.value = + READ_REG(fe_debug->fe_debug_reg.reg); + }else{ + WRITE_REG(fe_debug->fe_debug_reg.reg, fe_debug->fe_debug_reg.value); + } + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + break; + + default: + udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; + break; + } + udp_cmd->wan_cmd_data_len = 0; + break; + default: udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; udp_cmd->wan_cmd_data_len = 0; @@ -1015,6 +1155,8 @@ int sdla_te3_iface_init(void *p_fe_iface) /* Inialize Front-End interface functions */ fe_iface->config = &sdla_te3_config; fe_iface->unconfig = &sdla_te3_unconfig; + fe_iface->post_init = &sdla_te3_post_init; + fe_iface->pre_release = &sdla_te3_pre_release; fe_iface->polling = &sdla_te3_polling; fe_iface->isr = &sdla_te3_isr; fe_iface->process_udp = &sdla_te3_udp; @@ -1074,7 +1216,7 @@ static int sdla_te3_config(void *p_fe) return -EINVAL; } - switch(fe_cfg->frame){ + switch(WAN_FE_FRAME(fe)){ case WAN_FR_E3_G751: if (fe_cfg->media != WAN_MEDIA_E3){ DEBUG_EVENT("%s: (T3/E3) Invalid Frame Format!\n", @@ -1125,7 +1267,7 @@ static int sdla_te3_config(void *p_fe) WRITE_REG(REG_OPMODE, data); data = 0x00; - switch(fe_cfg->lcode){ + switch(WAN_FE_LCODE(fe)){ case WAN_LCODE_AMI: DEBUG_TE3("%s: (T3/E3) Line code AMI\n", fe->name); @@ -1151,13 +1293,125 @@ static int sdla_te3_config(void *p_fe) data |= BIT_IO_CONTROL_RxLINECLK; WRITE_REG(REG_IO_CONTROL, data); + if (IS_E3(&fe->fe_cfg)){ + sdla_te3_set_lb_modes_all(fe,WAN_TE3_LIU_LB_REMOTE,WAN_TE3_LB_ENABLE); + } + + fe->fe_param.te3.e3_lb_ctrl=0; + fe->fe_param.te3.e3_connect_delay=10; + /* Initialize Front-End parameters */ fe->fe_status = FE_DISCONNECTED; + DEBUG_EVENT("%s: %s disconnected!\n", fe->name, FE_MEDIA_DECODE(fe)); sdla_te3_read_alarms(fe, 1); - sdla_te3_set_intr(fe); + //sdla_te3_set_intr(fe); + return 0; +} + + +static int sdla_te3_add_timer(sdla_fe_t* fe, unsigned long delay) +{ + int err=0; + + 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 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; +} + + + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void sdla_te3_timer(void* pfe) +#elif defined(__WINDOWS__) +static void sdla_te3_timer(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3) +#else +static void sdla_te3_timer(unsigned long pfe) +#endif +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_t *card = (sdla_t*)fe->card; + wan_device_t *wandev = &card->wandev; + + DEBUG_TEST("[TE3] %s: TE3 timer!\n", fe->name); + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ + wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); + return; + } + if (!wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)){ + /* Somebody clear this bit */ + DEBUG_EVENT("WARNING: %s: Timer bit is cleared (should never happened)!\n", + fe->name); + return; + } + wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); + + if (wandev->fe_enable_timer){ + wandev->fe_enable_timer(fe->card); + } + + + sdla_te3_add_timer(fe, 1000); + + + return; +} + + +static int sdla_te3_post_init(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + + /* Initialize and start T1/E1 timer */ + wan_set_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical); + + wan_init_timer( + &fe->timer, + sdla_te3_timer, + (wan_timer_arg_t)fe); + + /* Initialize T1/E1 timer */ + wan_clear_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical); + + /* Start T1/E1 timer */ + if (IS_E3(&fe->fe_cfg)){ + sdla_te3_add_timer(fe, 5000); + } else { + sdla_te3_add_timer(fe, 1000); + } + return 0; +} + +static int sdla_te3_pre_release(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + + /* Kill TE timer poll command */ + wan_set_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical); + if (wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)){ + wan_del_timer(&fe->timer); + } + wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); + return 0; } @@ -1213,7 +1467,7 @@ static int sdla_te3_update_pmon_info(sdla_fe_t* fe, struct seq_file* m, int* sto "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){ + if (WAN_FE_FRAME(fe) == WAN_FR_DS3_Cbit){ PROC_ADD_LINE(m, PROC_STATS_PMON_FORMAT, "Parity Error", fe->fe_stats.u.te3_pmon.pmon_parity, diff --git a/patches/kdrivers/src/net/sdla_xilinx.c b/patches/kdrivers/src/net/sdla_xilinx.c index b715a27..93eb56e 100644 --- a/patches/kdrivers/src/net/sdla_xilinx.c +++ b/patches/kdrivers/src/net/sdla_xilinx.c @@ -125,12 +125,12 @@ typedef struct private_area struct net_device_stats if_stats; int tracing_enabled; /* For enabling Tracing */ - unsigned long router_start_time; + wan_time_t router_start_time; /*unsigned long router_start_time;*/ unsigned long trace_timeout; unsigned char route_removed; unsigned long tick_counter; /* For 5s timeout counter */ - unsigned long router_up_time; + wan_time_t router_up_time; /* unsigned long router_up_time; */ unsigned char mc; /* Mulitcast support on/off */ unsigned char udp_pkt_src; /* udp packet processing */ @@ -5350,7 +5350,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, card->hw_iface.hw_unlock(card->hw,&smp_flags); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/sdladrv.c b/patches/kdrivers/src/net/sdladrv.c index 7b44311..00f985c 100644 --- a/patches/kdrivers/src/net/sdladrv.c +++ b/patches/kdrivers/src/net/sdladrv.c @@ -443,6 +443,7 @@ volatile extern int ticks; /* This line will causes redundant otherwise loop in calibrate_delay() will never finished (optimization) */ #endif +static int sdladrv_mode = SDLADRV_MODE_WANPIPE; /* SDLA ISA/PCI varibles */ extern int Sangoma_cards_no; /* total number of SDLA cards */ @@ -626,7 +627,10 @@ typedef struct sdla_memdbg_el WAN_LIST_ENTRY(sdla_memdbg_el) next; }sdla_memdbg_el_t; -int sdla_memdbg_init(void) +static int sdla_memdbg_init(void); +static int sdla_memdbg_free(void); + +static int sdla_memdbg_init(void) { wan_spin_lock_init(&wan_debug_mem_lock,"wan_debug_mem_lock"); WAN_LIST_INIT(&sdla_memdbg_head); @@ -634,12 +638,16 @@ int sdla_memdbg_init(void) } -int sdla_memdbg_push(void *mem, char *func_name, int line, int len) +int sdla_memdbg_push(void *mem, const char *func_name, const int line, int len) { - sdla_memdbg_el_t *sdla_mem_el; + sdla_memdbg_el_t *sdla_mem_el = NULL; wan_smp_flag_t flags; +#if defined(__LINUX__) sdla_mem_el = kmalloc(sizeof(sdla_memdbg_el_t),GFP_ATOMIC); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + sdla_mem_el = malloc(sizeof(sdla_memdbg_el_t), M_DEVBUF, M_NOWAIT); +#endif if (!sdla_mem_el) { DEBUG_EVENT("%s:%d Critical failed to allocate memory!\n", __FUNCTION__,__LINE__); @@ -653,7 +661,6 @@ int sdla_memdbg_push(void *mem, char *func_name, int line, int len) 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); @@ -662,13 +669,12 @@ int sdla_memdbg_push(void *mem, char *func_name, int line, int len) 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) +int sdla_memdbg_pull(void *mem, const char *func_name, const int line) { sdla_memdbg_el_t *sdla_mem_el; wan_smp_flag_t flags; @@ -692,8 +698,11 @@ int sdla_memdbg_pull(void *mem, char *func_name, int line) func_name,line, sdla_mem_el->mem, sdla_mem_el->len, wan_debug_mem, sdla_mem_el->cmd_func,sdla_mem_el->line); - +#if defined(__LINUX__) kfree(sdla_mem_el); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(sdla_mem_el, M_DEVBUF); +#endif err=0; } else { wan_spin_unlock_irq(&wan_debug_mem_lock,&flags); @@ -708,7 +717,7 @@ int sdla_memdbg_pull(void *mem, char *func_name, int line) } EXPORT_SYMBOL(sdla_memdbg_pull); -int sdla_memdbg_free(void) +static int sdla_memdbg_free(void) { sdla_memdbg_el_t *sdla_mem_el; int total=0; @@ -729,7 +738,11 @@ int sdla_memdbg_free(void) sdla_mem_el = WAN_LIST_NEXT(sdla_mem_el, next); WAN_LIST_REMOVE(tmp, next); +#if defined(__LINUX__) kfree(tmp); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(tmp, M_DEVBUF); +#endif } DEBUG_EVENT("=====================END==================================\n"); @@ -851,6 +864,13 @@ int sdladrv_exit (void *arg) return 0; } +EXPORT_SYMBOL(sdladrv_hw_mode); +int sdladrv_hw_mode(int mode) +{ + sdladrv_mode = mode; + return 0; +} + /* ***************************************************************************** ***************************************************************************** @@ -1584,10 +1604,22 @@ static int sdla_pcibridge_info(sdlahw_t* hw) hwcard = hwcpu->hwcard; sdla_pci_bridge_read_config_word(hw, PCI_VENDOR_ID_WORD, &vendor_id); - if (vendor_id == PLX_VENDOR_ID){ + if (vendor_id == PLX_VENDOR_ID && sdladrv_mode == SDLADRV_MODE_WANPIPE){ u_int16_t val16; u_int8_t val8; +#if 1 + sdla_plxctrl_read8(hw, PLX_EEPROM_VENDOR_OFF, &val8); + val16 = val8 << 8; + sdla_plxctrl_read8(hw, PLX_EEPROM_VENDOR_OFF+1, &val8); + val16 |= val8; + if (val16 != SANGOMA_PCI_VENDOR){ + hwcard->pci_bridge_dev = NULL; + hwcard->pci_bridge_bus = 0; + hwcard->pci_bridge_slot = 0; + } + +#else sdla_plxctrl_read8(hw, 0x00, &val8); /* For now, all PLX with blank EEPROM is our new ** cards from production. */ @@ -1603,6 +1635,7 @@ static int sdla_pcibridge_info(sdlahw_t* hw) hwcard->pci_bridge_slot = 0; } } +#endif }else if (vendor_id == TUNDRA_VENDOR_ID){ /* Skip extra verification for TUNDRA PCI Express Bridge */ } @@ -2588,7 +2621,6 @@ sdla_pci_probe_aft(sdlahw_t *hw, int slot_no, int bus_no, int irq) return 0; } hwcard->pci_dev = tmp_hwcard->pci_dev; -#if defined(__LINUX__) /* Detect PCI Express cards (only valid for production test) */ switch(PCI_subsys_vendor){ case A200_REMORA_SHARK_SUBSYS_VENDOR: @@ -2606,7 +2638,6 @@ sdla_pci_probe_aft(sdlahw_t *hw, int slot_no, int bus_no, int irq) sdla_pcibridge_detect(hwcard); break; } -#endif hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); diff --git a/patches/kdrivers/src/net/sdladrv_utils.c b/patches/kdrivers/src/net/sdladrv_utils.c index fcd11b2..ed4e648 100644 --- a/patches/kdrivers/src/net/sdladrv_utils.c +++ b/patches/kdrivers/src/net/sdladrv_utils.c @@ -59,23 +59,24 @@ **** 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 +#define SDLA_PLXE_CTL 0x1004 //Change this accordingly.!!! -#define SDLA_PLX_EEPROM_SIZE 0xFF +#define SDLA_PLXE_SIZE 0x7F -#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 +#define SDLA_PLXE_SHIFT_WRITE_DATA 0 +#define SDLA_PLXE_SHIFT_READ_DATA 8 + +#define SDLA_PLXE_MASK_BYTE_WRITE_START (1<<16) +#define SDLA_PLXE_MASK_BYTE_READ_START (1<<17) +#define SDLA_PLXE_MASK_CS_ENABLE (1<<18) +#define SDLA_PLXE_MASK_BUSY (1<<19) //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 +#define SDLA_PLXE_OPCODE_WRITE 0x02 +#define SDLA_PLXE_OPCODE_READ 0x03 +#define SDLA_PLXE_OPCODE_READ_STATUS 0x05 +#define SDLA_PLXE_OPCODE_WREN 0x06 /*************************************************************************** @@ -89,17 +90,17 @@ /*************************************************************************** **** 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); +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 int sdla_plx_EE_readbyte(void *phw,unsigned char*); +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); +int sdla_plxctrl_status(void *phw, unsigned char*); +int sdla_plxctrl_read8(void *phw, short, unsigned char*); +int sdla_plxctrl_write8(void *phw, short, unsigned char); +int 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); @@ -146,15 +147,16 @@ static int sdla_plx_EE_waitidle(void *phw) WAN_ASSERT(phw == NULL); for (ii = 0; ii < 100; ii++){ /* read current value in EECTL */ - sdla_plx_8111Read(phw, SDLA_PLX_EECTL, &eeCtl); + sdla_plx_8111Read(phw, SDLA_PLXE_CTL, &eeCtl); /* loop until idle */ - if ((eeCtl & (1 << SDLA_PLX_EEPROM_BUSY)) == 0){ + if ((eeCtl & SDLA_PLXE_MASK_BUSY) == 0){ return(eeCtl); } + WP_DELAY(1000); } DEBUG_EVENT("%s: ERROR: EEPROM Busy timeout!\n", hw->devname); - return -EINVAL; + return SDLA_PLXE_MASK_BUSY; } /////////////////////////////////////////////////////////////////// @@ -164,43 +166,41 @@ 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); + /* turn off everything (especially SDLA_PLXE_MASK_CS_ENABLE)*/ + sdla_plx_8111Write(phw, SDLA_PLXE_CTL, 0); return 0; } /////////////////////////////////////////////////////////////////// -static unsigned char sdla_plx_EE_readbyte(void *phw) +static int sdla_plx_EE_readbyte(void *phw, unsigned char *data) { 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); + WAN_ASSERT(phw == NULL); - 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 */ + if (sdla_plx_EE_waitidle(phw) & SDLA_PLXE_MASK_BUSY){ + return -EINVAL; + } + + eeCtl = (SDLA_PLXE_MASK_CS_ENABLE | SDLA_PLXE_MASK_BYTE_READ_START); + sdla_plx_8111Write(phw, SDLA_PLXE_CTL, 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){ + sdla_plx_8111Read(phw, SDLA_PLXE_CTL, &eeCtl); + if ((eeCtl & SDLA_PLXE_MASK_BYTE_READ_START) == 0){ break; } } - if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_READ_START)) != 0){ - DEBUG_EVENT("%s: Timeout on PLX READ!\n", + if (eeCtl & SDLA_PLXE_MASK_BYTE_READ_START){ + DEBUG_EVENT("%s: ERROR: Timeout on PLX READ!\n", hw->devname); - return 0xFF; + return -EINVAL; } 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; + sdla_plx_8111Read(phw, SDLA_PLXE_CTL, &eeCtl); + *data = (eeCtl >> SDLA_PLXE_SHIFT_READ_DATA) & 0xFF; + return 0; } /////////////////////////////////////////////////////////////////// @@ -210,23 +210,23 @@ static int sdla_plx_EE_writebyte(void *phw, unsigned char val) int i, eeCtl = 0; /* make sure EEPROM is idle */ WAN_ASSERT(phw == NULL); - eeCtl = sdla_plx_EE_waitidle(phw); /* make sure EEPROM is idle */ + if (sdla_plx_EE_waitidle(phw) & SDLA_PLXE_MASK_BUSY){ + return -EINVAL; + } + /* 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); + eeCtl = (SDLA_PLXE_MASK_CS_ENABLE | SDLA_PLXE_MASK_BYTE_WRITE_START); + eeCtl |= ((val & 0xff) << SDLA_PLXE_SHIFT_WRITE_DATA); + sdla_plx_8111Write(phw, SDLA_PLXE_CTL, 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){ + sdla_plx_8111Read(phw, SDLA_PLXE_CTL, &eeCtl); + if ((eeCtl & SDLA_PLXE_MASK_BYTE_WRITE_START) == 0){ break; } } - if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_WRITE_START)) != 0){ - DEBUG_EVENT("%s: Timeout on PLX write!\n", + if (eeCtl & SDLA_PLXE_MASK_BYTE_WRITE_START){ + DEBUG_EVENT("%s: ERROR: Timeout on PLX write!\n", hw->devname); return -EINVAL; } @@ -239,57 +239,63 @@ static int sdla_plx_EE_writebyte(void *phw, unsigned char val) ***************************************************************************/ /////////////////////////////////////////////////////////////////// -unsigned char sdla_plxctrl_status(void *phw) +int sdla_plxctrl_status(void *phw, unsigned char *status) { - unsigned char status = 0; + WAN_ASSERT(phw == NULL); - 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_writebyte(phw, SDLA_PLXE_OPCODE_READ_STATUS); + if (sdla_plx_EE_readbyte(phw, status)){ + return -EINVAL; + } sdla_plx_EE_off(phw); /* turn off EEPROM */ - return status; + return 0; } -void sdla_plxctrl_write8(void *phw, short addr, unsigned char data) +int sdla_plxctrl_write8(void *phw, short addr, unsigned char data) { + WAN_ASSERT(phw == NULL); - 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 */ + /* must first write-enable */ + sdla_plx_EE_writebyte(phw, SDLA_PLXE_OPCODE_WREN); + /* turn off EEPROM */ + sdla_plx_EE_off(phw); + /* opcode to write bytes */ + sdla_plx_EE_writebyte(phw, SDLA_PLXE_OPCODE_WRITE); /* 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 */ + /* send data to be written */ + sdla_plx_EE_writebyte(phw, (data & 0xFF)); sdla_plx_EE_off(phw); /* turn off EEPROM */ - return; + WP_DELAY(10000); + return 0; } /////////////////////////////////////////////////////////////////// -unsigned char sdla_plxctrl_read8(void *phw, short addr) +int sdla_plxctrl_read8(void *phw, short addr, unsigned char *data) { - unsigned char ch; - - WAN_ASSERT_RC(phw == NULL, 0xFF); - sdla_plx_EE_writebyte(phw, SDLA_PLX_READ_EE_OPCODE); + WAN_ASSERT(phw == NULL); + + sdla_plx_EE_writebyte(phw, SDLA_PLXE_OPCODE_READ); sdla_plx_EE_writebyte(phw, (unsigned char)(addr & 0xFF)); - ch = sdla_plx_EE_readbyte(phw); + if (sdla_plx_EE_readbyte(phw, data)){ + return -EINVAL; + } sdla_plx_EE_off(phw); - return ch; + return 0; } -void sdla_plxctrl_erase(void *phw) +int sdla_plxctrl_erase(void *phw) { int t; - WAN_ASSERT_VOID(phw == NULL); - for(t = 0; t < SDLA_PLX_EEPROM_SIZE; t++){ + WAN_ASSERT(phw == NULL); + for(t = 0; t < SDLA_PLXE_SIZE; t++){ sdla_plxctrl_write8(phw, t, 0xFF); } - return; + return 0; } diff --git a/patches/kdrivers/src/net/wanpipe_abstr.c b/patches/kdrivers/src/net/wanpipe_abstr.c index 8b02292..7f538ff 100644 --- a/patches/kdrivers/src/net/wanpipe_abstr.c +++ b/patches/kdrivers/src/net/wanpipe_abstr.c @@ -34,7 +34,8 @@ # include #elif defined(__WINDOWS__) # include -# include +# include +# define printk DEBUG_EVENT #elif defined(__KERNEL__) # include # include @@ -610,7 +611,7 @@ void __wpabs_debug_event(const char * fmt, ...) char buf[1024]; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); - printk("%s", buf); + DEBUG_EVENT("%s", buf); va_end(args); #endif } diff --git a/patches/kdrivers/src/net/wanpipe_linux_iface.c b/patches/kdrivers/src/net/wanpipe_linux_iface.c index 97d8ff9..bb3096f 100644 --- a/patches/kdrivers/src/net/wanpipe_linux_iface.c +++ b/patches/kdrivers/src/net/wanpipe_linux_iface.c @@ -507,7 +507,8 @@ static int wan_iface_set_proto(netdevice_t* dev, struct ifreq* ifr) struct if_settings* ifsettings; ifsettings = (struct if_settings*)ifr->ifr_data; - + + switch (ifsettings->type) { case IF_PROTO_PPP: case IF_PROTO_CISCO: case IF_PROTO_FR: diff --git a/patches/kdrivers/src/net/wanpipe_multppp.c b/patches/kdrivers/src/net/wanpipe_multppp.c index f0fdf21..4fba1e9 100644 --- a/patches/kdrivers/src/net/wanpipe_multppp.c +++ b/patches/kdrivers/src/net/wanpipe_multppp.c @@ -118,11 +118,11 @@ typedef struct private_area wanpipe_common_t common; sdla_t *card; netdevice_t *dev; - unsigned long router_start_time; + wan_time_t router_start_time; /*unsigned long router_start_time;*/ unsigned char route_status; unsigned char route_removed; wan_ticks_t tick_counter; /* For 5s timeout counter */ - unsigned long router_up_time; + wan_time_t router_up_time; /*unsigned long router_up_time;*/ unsigned char mc; /* Mulitcast support on/off */ char update_comms_stats; /* updating comms stats */ @@ -2890,7 +2890,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, &wan_udp_pkt->wan_udp_data[0]); }else{ if (wan_udp_pkt->wan_udp_command == WAN_GET_MEDIA_TYPE){ - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + wan_udp_pkt->wan_udp_data_len = sizeof(wan_femedia_t); wan_udp_pkt->wan_udp_return_code = CMD_OK; }else{ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; diff --git a/patches/kdrivers/src/net/wanpipe_syncppp.c b/patches/kdrivers/src/net/wanpipe_syncppp.c index 6868cfc..b0c1350 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.33 2008-05-05 17:13:26 sangoma Exp $ + * $Id: wanpipe_syncppp.c,v 1.33 2008-05-05 17:13:26 sangoma Exp $ */ /* diff --git a/patches/kdrivers/src/net/wanpipe_utils.c b/patches/kdrivers/src/net/wanpipe_utils.c index ab5d887..521c9a5 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.101 2008/02/04 18:02:20 sangoma Exp $ + * $Id: wanpipe_utils.c,v 1.101 2008-02-04 18:02:20 sangoma Exp $ */ /* diff --git a/patches/kdrivers/src/sangoma_xmtp2km.tgz b/patches/kdrivers/src/sangoma_xmtp2km.tgz deleted file mode 100644 index 6c14428e38e89e8c6a9d9cae8673a53e69cc6632..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71235 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 ZGy9qS%zkD+v!4(8`5$Q;jh6r*0|11@q^|$~ diff --git a/patches/kdrivers/src/wan_aften/wan_aften.c b/patches/kdrivers/src/wan_aften/wan_aften.c index d39263f..7120162 100644 --- a/patches/kdrivers/src/wan_aften/wan_aften.c +++ b/patches/kdrivers/src/wan_aften/wan_aften.c @@ -72,6 +72,9 @@ static int wan_aften_init(void *arg) #if defined(__OpenBSD__) || defined(__NetBSD__) sdladrv_init(); #endif + + sdladrv_hw_mode(SDLADRV_MODE_LIMITED); + DEBUG_EVENT("%s v%d %s\n", wan_fullname, WAN_AFTEN_VER, diff --git a/patches/kdrivers/src/wan_aften/wan_aften_src.o b/patches/kdrivers/src/wan_aften/wan_aften_src.o index d0f8c4caa71434131e295ec9f85f6e30bcb3a64f..1f0ae7a53ab4cac95bada145d5d2d55c7337466b 100644 GIT binary patch delta 104452 zcmY(M2Ut|c+Q(0WS#W`c-NBW%EW1b%6%`c~l_r8>iwy-86%myn*!yCME%sw?U^G!< zFUd8=-1HlhnB3&X#PsTSQ*QcAG5!0$GY6BK=gB(1>GRGz@02s=aQ*$Tr#=kZlBi{y z=aPOf)HHK>klXAO6sxuqt|@S}hbzncG^n+CEht{?42s?se8h8qh@#ZgYWR5yKcD>i z#~**x1%lx;JZ;(Naf;$e zX^$A1Pf=`B;i$v^A>{BVp+yYQSZMzq^p9pNhHtAi_)+bYLfnj^+!N(~A z)6(GNlr(JRop44A=ekljTMOsFlW@94+_oM#+mKT;+M?~DlZT+L!C}Kk!asou2%A;{ zrzarXFAadZ?O=+Sa}li%3Olm|?qE^nacECy*bEA6ze(isHHr@nUrIh2%1~`#?;^8M z$7b>=u0)|hVZ-X-juaULhr=n`@X>fUU82kr!{BTkMTLe9p98o11xkMZCUZ~Z(7=x4 zaA*HcffHij?CnBFhV8;nXufcIPAN)j=ShmN2+e67ol6m3y$??JHfrB5b~xLh1C+3@ z=EE6thMY$xz#02EIR_nvGoCszEdLyw3Ez>kFZ7|cClE>*A4f*56FE6IqLW(t+mmw) zMNZBp=Nqfw%q}434Jb(Kyla%jyU4S3(YxfVtb%jsr{sKb51b?aAZPP(IBRE7vMlsj z>$;ufOohI+t`{x38CV8)!y)pX*9_-;;XN}S&f_9-{8>2f7tUv?J|{&4uNTe>LcBA# z!ucSHD)?a?x{3aDwF`@=u2b5DzYGs(IU7=_DD5Ih%{8CFCLQ~eB5iETs6WxprkeAe z{X1Vkr?&6$4w6Sk8_?eNJ=wpK;nh>-f!cO%B>V$0g6|1Zl zI5rfmN*y67kwrjQsUs!%S@2rWC`qZTzT7ljDUKPZ;W>s>N%M7M-J8wlTq$w6ec)Lk zJ@X@`%vMq>B^0uoW*CndUbh+%CQ82n5!Hw=NkS>>xf?+i4UU+Kpvf|5DBBi-AdBu$ zf*(N}!ip3nF}0c<9&aw<-l0n$P?YA>>1->4QfGJ}1`=fy)F!o7ieUshmH@g_QW-mw z2&$7*!R}}Snn}XZe3h)nSo1$TNy{5#MntdD(BK`>sT!L2X!P(v>3BsMS{TO8-mfTy z;Zi6H^Fk8~BP1E@Jds0^jZK1%7e-35v)|)DQIZ_&xqcw0Bo})y8RU}WW}72G!n9Ba zePM#4FT-e|iivD!Gf-F<&F5#ndqHlQFqN(5pf-{+SS2Nlk(9{{jGn?+Nmv!^ZB0>ZSJ_6-s1hFJhde_o^0@$`)+_<;)Y5&3-uo z>MhePVBZV_^_8@QJ#_+_kx?%SZUc^SYGGS|9qi^?LQfawDyZdIAK9#|@I zo60Uz+Cd~5-Dj#S52GmE&c2FKp%;A%Ct6*WGNKW4rb>~_I)f8 zVY5})Rc`(YIwyUOg>hV@oU8sJQYP{*E+TZEK;74@^5r$=<=8IT-5t!YV(a^e$SZCa za|**VeWgm3)O@wv_$%JYf5D`7JG72p9&R3pi>>I9`4`^?PJ=0Zl^PdDST@E`I7X9NTH3S#W*ah8ePIjJ+R03_ z*o#pAv<}xq)NCb+YPD)33~Es7b$;a>7Ih)|$Hk(ioa*lh)jt<#@cjdUt#leE819@* zyT`6umF15^CZ2Fz*3ZG`o>u~jhgUmb?Y!;_*<>QAw2_>Q*bONnuThwg%JhW=x3QmwTr?{OI1QLlupC8NY&!hrH* z>SQd)D)9j%)=olhx^KJ6ublY{?^gN1DsX2je80-Sz6YEos!aAH_W62nS5Zkr_2}jd zuPg91)wH`lAB!N}cT(jAcYu5Aqzbz4tjf2M$nu2vb>Bsm&m)oMTYN?3Co%JT3at1~ zsr4t<0HI(;k6pSR0$qp#owUuiKIU*yhY>tw}OZ2Wo;<^ z_Td`e2J_;%!%DDU<2NuSZ*#N82az6(unIh)@wZ_#Z}TyYpP&|x6lwzrYW$}8Qj*7e zV;y|Q=%9R{Ownn! zhk$i{;W&7@6@EnL8_;tW2Xx;to&Qd1UaSAqmJ*!Q`J7~MoxTX=Km~Od)}@|$eT8WA zV>TX59Xd}7J4@7Z;Ej6-&cY+ zSrtAK!r$Kp-lqSqV)8~0gzyy;;bFpq_+$uQwg9|Czv?DF8^U+q58iF@#Sq><1H51V zLlk%^gm=OE&T~-zwNGSjJ3Gj!O89Wxs^SgsTnyhaV5zdD4 zJ-y)Ze_}#~oeg!(nmkwW{9FG3x~2Orh4TLB8_%a!29JgE&&c+Fr5_aOuZHqP3&G#$ zM+9FB#cJ(fgrdYPUTUsS@wo3naW)%g-z>tv(FXdJHe>^v&Bs$(cb|dYG;9+z{_+}x zR%*j#u;L`gO01u3@Z=(CRZAdW+1-ptjR~w;2PG|zQX>P1YuIgUEtX^U5F(VIB;G)9 z*vFW6?4dRAi@Z-n3uoU$-u8%=Xkj*tQM+R^#UQ0KTDjOX=u|7d3Pc%&b-_=o#B&tm zGZDj2F#<}fWXe)Rc?5Q&Rpu)c#SR;0L`1UY4T=&WNYn-cR|(r`lHd1;7IryAQTFtw zMNHWF`HGU$lh#+kgTRMjIE@MQEE`5?LIbrz6fwpLoYff-f|ujxLf{mn)5gv&LLJ(K z{U5Xk(b!&eb{lImYAC_?Bc=vxV`~#7BRX3mb{UF@u8krYBEEu%52RDX)+|LwkT|HK z9N&ccwUK94K12+K8ulZR1v*Y)9gizYN1R#6vPX;sO`{03QTuf(Xu2dDbb?9H|ua>p43Pla8Cy(z62}VZ_?~orPlf zyO0u4yG7hA8P`z4?jDY$-Cm)>`(PG%sDq+7Vx24&3LKYx*^_Q+?*~cI^Wvp<5Z-li1&P zmLj&+B!uq{A$(9vDZTcC2G5PB`f7^pE;uMioHqw4!LNghpiH*yQ)M5PCxojs49+-@C1VPy4BP?Q&nDbIs4&!(0ABc$}39Z0r*HVb(dR!*;f3Ht778M9R#; zLhc7$kR!^aM3MLIo{BO;owc5;1&Y#;q5cL9MY;Ur9AJBO#6Ch7e|!S4gTUdMFN@Et z26wcAM~JOQL#8UrnZs{Fa1EW+BZDdN0{-DNU>9{61_mZXl|O;`p&?6s2RfqruBrT? zd1iUX4uKs>@Xk?Z9w2XQAHIZcHuO>D;tSh{kq~1;UyHGQD9;4vS&Z$&zhD>}3RDx4 z!`e*a5g0TL{nTFf5M#Cf<8g42Di;n|?T=j#E>%e!n76e8zG@^q2CMx=f-4#y)eC%w z72z>#4;sP4)fz}x_g&Ta>`?Fsbs&a6+M)68cbfw<+XNyY!VSAzY-y#U?Ba<~dkB=B zz}Vas?Nx{jR)V(fa!Z0CKta3O?1Ud3xv>tQ7^x->HW^lXSF9u#3q1vjljLS!Za~j7g8ZyU8Yodl#la>zXqR;ek-^?y1xlhdD>mZnG%CEy_l`)H z#o`x(l4V#nn+mPi)%KPM%VB>&9=lS)q4An8m%V)!lp5|6HfRVaYptLv z)*XgwSGOh~#wYgaEP@i|JS_ri*%%D9UA^BIRL@#FL4AJ^G>54JLAlb*EnrDAKzVjd zD4K5xdjN~sU4=f7IK|vJ2-t5f1SQTT_hS~=RU~n(s_3dXQn*mrd6yb^IvnTV%{|4W z*xajSQf!8OYR-|pU_{KAvQTO6y+Wh1Y!P#(RVmGVXx9lPh?q*$mv)ylaLWv&%avg+ z)&Vtd&XZwoHvc|Q{wNVME@JkS2Bo>64xNC6iH!Ci&4tn$_?4vppe3`X+^N_KV%dRM zMJX61>!Pru+d-qPnqj%|1Y!p7f@QgJ5K~@3oLGMrOd}uC=7G(KKK+0ogE_~5X2_E< zoPNb%#ZyrGi3qeu)T1Q@cgma{>@hREYii(g*t>#;2Qj}=C6iG1f>|<#pFL0onk^|6 zHTecL(F`g$n6kWb7%PW@1l9?2T)`q)h{DP)fEG(K*sXJ*B{B;eI|UUkSb9YiW=B?s zlOdhpWbhUg99+oxuBfcmm;Vl zjp_%HG(v?6##!}do+8kAxmwI%CQM(!1WB1}Z}wzhC3OaDDJ#ZoQ7})!YrFaLdevaPRj`uTrXc1jxd>8(q7~fLvUUo-3t_8eI;@>sSi_Fr zggK;O9hP)9%RFiqrL0#m?F_g%;h~#MM&VmC_pQh~HR;&{+*-h3H5Q7CL zfqGI@TJ(;A&1>pKbs;*6VwXQl%&#C| zWvE03!!o;?`pY!M|C6SqB~4TuN*&Om(9zJprh&BKrRib=3T`Turl%->w zG!2s@pSB0^wl$TpAk4i@V=gOILOc-@s;iWyu`**rN#2cEbDG-wg#`iiRJ7LxwrKylw@BagXziAM)+`l^n&XLq0e?)&c&GH_xf#=>c7wqbU(EjLCkvlK>$TDh@O-7yqvfD@Y`AqPPS(ZEQZW9b$9Eb{QRCQV^H8tYK=B&*)kryHvo^4S(bFX5ve!^x^mHlgV)kJ_ z(2NtJpi=f8Rj~Hs3d(CJ`yRRiNGq@Gm?CquH#0BX50mN1YgF_TEZrxe(p=y3@yx+C%(oI9bG_NZ9a-BgsQxR&0ogx!yd7wro1p}WJ-gLj)x=A;z0xf|m= zsz`KtRDapA3VS^i@rxxH>=l^ps1ivwp+`{zWX>>@yWzjj%hH~SeK6tz)`R$-@Sf;LGq*wo5D$;Or~`IGF-hanubD~plX9V{XY zbZ9k(qFDOSsZZ2>q!>UiqsB*_*eOC+dD(%ZSawC7Cb1yc$DZhp;B!`NAIrn=jyg{b z!Me%EhU5dqHU#T*ANv{xBH&$neXI=MPE&_*pTuDe4PZ@G3vMj*%GkrNp&<7H{hV{_l27M`)9u{kIADy$s&s z=jW*;)q1kH-Opbm31}AY_VcBcW?tWtKn>ce42(+T-AR5O)fbQ*CNbWL3d>aA0UEwW zJU$vp;_swV)eYZGc)X9IqPnO9QI6sJ1Rgr3^Qf-sXyNfWJl?`OH7ZvWY52aTJgAC! zmdAJSxX`a0KKYinZv#BG9WV#y z#j z59SejPzifH2qSs`o%>TYFlLpYffP(p8AP$Zi5E8CP=c0!S0$QV`B7SOuHt_ zOdTvP3RI=SsFI;i!A#|vB4fJQR15)EwTv0Z9zx|^Q`NyDY9iY`2UsHm{VXO6G)-oc z%HAIanl7`+5Rau@Gh}5lnRgk&YU#|HmZVRbkK`w6u^Hxj`E49;K~eg2lxE+?@Bq|S z&@t2rU9tD+#zyrr^9qvP2k%#uk#W0GiQp&jLucqlnU{TIE-P>cK8E47m$eu6tgO>f zQB#HaE-Fe{4_O<7ox|WO>qlv^%2I+;QSpCIKo^f1%66fSqlUE@SUMygb;s>a9fpWE zO3^RF)7hGniZa}KLawk@P_p3}_!&sDSAvfq<{!^A3cCnJDH?UyQe?8yMWb8vzibz%%n?JG+88||C>kTri|x!& z02(Wccd&n<`-;jxmIbona8QM$I95lwjH8liul6CL$z*tx;Gk?pA=A7dawI#l8c{~Ibgg;{G+HVd z&c+sk%Gx6d)!_=}oyaja1UXp4X;8VZ2Zgy5iDyU=uQ|bI@%~>l@4H?JXfk<6CMD~l$NZL-L(N!FWXziZj1vp zNUC8D46(>rl4{wiSkN3Pr+URn4gX+14z8k_R9E$cxr*~qZTu{1p~5{=6vg?N7RV6o zxABAbfgji8!qd(Roxmrw6j)>|9C*QI;FGtP)#pb5pVFk5-8?f1__SsnSMUK-f&b9x zmNR6@=OGX0Guj;ugsJ=yD(I?}Hkbc6?N#)4~OO6NZ@c6-~B(2@gjFoYytEVp*l~=p^&q;x?_{fqET_3}cx#2qIWW{J-@_GheKCA-PEYQLM*)fd0-C<9eimKu&0_P zLS3Ay?dc^J9GcI~TOS7INDScm-Azc})7uJ8kmMCtfC`UJ2*Wf%i=xhN6i#8aqBsTA{&#aK>yip0UM z<}2lQ`4K!={jE2}9>M=T9XQ0oGCpwvaF|uC3f}b)@D2+r`RGL82n(zDJFs-Ov4-D7 z1#V+4Urv&ikpr5qoi^8 zlD8RGmX<;DZZobdy@pxqHg7Rh&Q!ChG$F9D4g5!2`QU0&pc!0dakI*QBn4>UBgn`2 z3m;SY9n_00;kc$Wr7L)>+7^GS54mEO?D`x)}4Voq`WGQQf#&xi^ChdD}^s5rD{;uia}`bU(Ng>{y@KbvEcE{Rr#d02%Tq*I)%TD`NT8dx-x5UV>EDq z5GK|qJQH)KXQ4{B!(dSP%gE$5I(SJjaFG?+#m7NZx6!RcKb(& zQA-ZB^3GZd*7Gm7Ao4LQbPgYidE_=O;NRT`JfX@%#3lU6Q^1n~g-MuG20mpmOu~~* zU^8u4Y(QMidq`v}?kkF`c`b~M-_!RXW((uKVmGpZEexY@sSQsKy2YyK{6pUwi;sEbemCo~Y-|GR5|JDx?Ub8&j*7#;W_ziWp zFjKHe;e)_$i#Y;MC-HEQD)5e4Au?#xmFN!0xIu{OK^q#E&j zvE+ihj9<&B>q{(LDMjr$|L8~xKG#dLY5%{FUD;m4D4fxa-n2mJb9alA0z61O; z8AIK7OJnr(x#S-bf7RGln4^+s$lzim>FgRTXURWhE!XPa3KITHw*|IA_qH{+jPM11 zA~{?B5DENCJ%9Q@B=EUT1-&fOLL?h>_C+py=vqC>+N85~u;3-HkOjxk)LC;4@Vac| zcAe#{1ingF4`}9Ne_sQ9jW!3Ew*oqww;6mx#=fGn(q6#VB|fIJ-&O(Nkoc6&Mu!65 zyi17ls?I(%fp5vstBg&>BwF&etj9IR&W#7YBSr8MW9zyD-zB|8S1>k-^smQzl5a9L zXf^o#&F3iiJH|#&0Dd5|zQx#Q<-iZ+>ibv5iYAz!jm)c}o9cNBT2|dJq0{pgHatoL z!(iW{*?EiPX4=MXWP%oNevHCgcm{f>lD9-I?%a&_jCo7@m1dDmf5s7x;<~d+=&&l>t{fR4~kq$ zSstu<-l_9~MqoA_0TqrL1&QMHc@&I>^I`nFIt-^So}+WDF0T9cwzgCTe=iK7 zfx#NxsiwK`4-5)V3p%(TO90Ohjjl}4Tv(6ldxlz=$VX)ZhiP>8ly+wVx)p8jNatv5-Z7ID=-4O#LE(@&Q~sq}8>;w`EIUED<#>QH(d-I;}Z5!|SF7x-MN5k4CzGM|?$-KYFMXVw6 z@&4Wp-9*d3e_~qjs%l#iwU~eC1ZwKVt?a)+?hax}j1n@DM@eIWWB5 zAd3T7uylqHy*AYtMG>%I$*%&3h?N<=V8K82f>hFkHm zi+KY(1aE{DAM2H~rQj$lKGrKQy1-5uKR}nB{<#buE-L{REU}T`Xe$90EG1AuZ)>Z7 zr&NA;BiL=l#{%Y2YGJGu{~F#X848ZG;=iQwj<7G@cq{&OysbgyC5mutVP02xI~X~y zS1k}Nd|Tz;q5r&o743#Z-dFhybdop4x=wXd<=>12r(669mVE2M?X4Bs=PIAt`7iu6 zm?WBMg@32=2V1ppF$%b)^8WY3ql=Z{uh?Ir^Ss^EpNCTg8Z~}l8n}m8I}830Q?571 zV%+yyyW9M|A|Y@RQ=M0C&JoSW_fxVGu_A}9@NpHI>n&BYM7uWlcnOA`cbGa}w0nz> zzl)*gl^b+=-o&q*0uNW^l)2l-4|>3()GDbdK0X73$2-=lcC%08-ch%MKDaxkrpQMOc+P!C<{}Q z`9Cluo#Rxwxy^(jdlvNzCee^s3}0(Dd$`%F(i@<*mnHRJzr>?u3pwOMmP^QBk(7ZU zo>e3*ma?<4IIK^SmdNuV2czqaNlWGJMi)ET9<(f0wY&P zjO`9o?P5sBp47ldV_E`5bg1ETNASxSh?bGP_Jl9XSInNXVzFigbcas+dq< zow~9ysCz=8lyWLN+zHfAQYK45BR$z}JLXD1~E5;5*=d%4JSZ#0xZ zROq|8in6!0jHyM`Ppne*x@B0f64r1~QO3xx8+>bn)3p=r4_gnDJEpa`$Nvayf+H3G zk2%QJrNO&t7<{Oq33q{-dkHewgw9HLWy~QNXk!g$5NKWIwX+%M<}ub~-Y~W$6Lh3V zBn(%={%NkAoYaS2GDxvmFG?z5JtKi3uOm)}moXxgw!y(PA6>V1~4P)J#DaN|DQ_EPV0pjg^1&L{LzJ{Ue&H6x)gT?Fub-g9X#rA9mbqmLk zqf?$endX?PeIXuHq0rll-86rzN(`*UtlsE-Q|#KjZ+#`2fV=7LUM^~;Q7lxb#sOJ-f#neSJ7+CEZ^3PyX` zhnsM1Bb4E)>&QKpb_@P7vlims;Trg&10#-zD$BB(}> z;`DBd)2_+KrV4K|fnnD31{?2ARx#W{2jAfbMp)?P%cFn}YeApL%V9{IEf18Lde}kj+nFj5u3c&tGzQ zHs(^N+u98j@)U4_Z1 z;)UaZ37WJ4wfvz%pvT&l)N^wkFj14o9&`BQ$w040TR3rc{W#`eXOdQlUd5b^1HKMj z;NcU`oUrXx`A;N3zeab4#PaTOl5et>2}P94yEJfH?cZ1%;J{bq!(m38Dca|PvApX7 zBkoMox{3H$o19$%ZYMef70^g{o=%A5_(D zLJFvv#*24?yKAK)=lzrgjmj%c~KrQR0H6K7v5{Uw}*-w)2U_=?8A zN>}MYl0&H8Hsz=&l)pY%G2@X!UYIcIHO6Mz1jiIau*3(AxV2 zxiAOP>&{Ws8TshQ1!{CHZ?^!om@8g_!?5Ck-xh)A=~54I_?rcsFWz&c)qnC#-~#cY zDm_yC&qm-v3nTgL<-kSO+ukm|>ptLOy(6@dKHBgpTI5`!FPlf0$bWPIm+Gqo`uS!W zhs*T9dcmpui4<@^za=n(SLFd4t$Jkg^9FFag;{(IW+>+hU9OC>`N!0zmAX7=$lbdtYaDyexIsE83;6@9V@c&ZUP1gH{tFREy0dLkrVUWb$=_6RLfOCr# zVT;ONfo?jt>63+yV=ygdVABfUukx+b&h7g57|>$yOrY|1imKDW8lON0XqPTe)-K{b zZ>$-ddvuy$gob8M0q?WkDScn#4I7nY#d%0b3a{yEyba9!%_z)_&YFQmRIaqnPYU{m`sIPA$W zic+2-K5+DG5S;DlnSAhe*rX1%csjn^$Oc|0W?FBjcL;Zz*>n8Hgp!~ zPDyT-MOoKLN@V>Y#PXSvQrRg;qP$*GCR?}*)F3IF{SE~vpG9^9Ybho84b){g#=5(F z85;?mEf2_u3cFr}{wi;jXk&$W2wX1HIanU#QNBWwO9_s_)P4;Mr}~P{toW#+RCK8n z1t^T}c~)deQduoDsG=(^yXcPlr^vFRo6N*uPeaQqy0;W}&nu=bMQrQEIpd3k=>_;lFH+}L64?areL(#;DjoH_#UmL=F&530)st0R=K zz#-s9>VRN*{=nXqlv9(3+vqyur$uNVh+W|7Ecskx`kF{*Y zc1dw85Csccu|pP?$v$ia+9?~C#o9~-?P`&&pNiPsBHOXBq!oKwWIKq8*lWpF>EJo2 zD9ShyW zR?r$hds;L~n+_%2`@0;Na`^1C@L?!uM zlx{CS<)7+9?x#uS{^*f#o@oWA65M+dR$_%zxudKLOknx3)$pNi?2!*T-g53F#?$>+ zSs)CLUufu^kS%nGp;vwqWPaZe9T>F;JCgEy`TxOWlyh+~L37#8uE1#ZE0{;x;TFQ| zl($yp37CzS+yiv0vTS<&gz6PMWU`{1iB^;)<*%|Q??a5&tc4Em$pj)pCGT5Zqpr39D!s|$wmdk%mKsxH*92mFq zUwQ~~u(Xq)UuBq!y-H!fjSyjOHrxaHU6vll9#=tse3c?9in}OXfQl+Z{rnD?+H%#x zRK9q&Ic?6PfllbWjPhVis4$x4OwAA)g1rEBs!g@T!w+Ckm4{ep<26`{mWQf$h{$&S zWHYdpg$}-86wt0N6`?LZyBjdfLO1^hRuSdl>Om2j6vxZak>wHU-vuY~M-BiT>Zbzz zysV4)?A)J6?L}v8C{Mr#Ut9?G+&;N^%mgN?Qojt|V-C=3p^M*J0!*^5(D=ox7v(3rJ|xiK?Yjdvsm}|v@w+h% zI=8ByO%q+l=Rql)+f@ZdgcgIBPXKqR$pUc`U@q{0IzXVChu#Z3XyK4J{wO-i*{n_x z!HImyaNr?zi9kPp8vW+HN8Kebm3M=AbRJQE5SYPJGJyA~(NHe>LeT^J%pMEU)UV9R z3q}V%ZVT(;T&r?=+r@cWl`lyseEL}68TBk=O2%LfRraj7SVDDQ&;&eZN!Z1gdx7WG zpV6oEcxA{!;05b?Kq5a>3%qFEN=oI+djlV^(grek>v-^k;=Gk=cL#*${F{YYJYgR2 zlA0sxo-Ml8`H&TwBfjF{ysXlb2P{5#F8b2>uvJna|M4R5idBzdzUdI~5ta5%unDkW zFV`sMrG+25SD=D6X9B*eR-h=Iqvctq!tOQCFPa=UGaIWA=hG^0#x&{thj>ety58Ic ze8!TO!S|8)u3EO##>-(^ozGfIX6JJU1D{jrivhH>|C#W4t74h_LD)FwHE}Xaw=25Q z#^(hqt3VF#N7DVL6+4%AvjJaLX_bo$m;5f$s()GHEafN4fv>1DMd(oOqHcWE3LU{m zpn=ZUtgOp;HKrBk4Rx`IT)~fa0KRS&RLRe51-5^~l5P$EV<`B2OZK&pUw?E;Tz-&P zolZj@ag)s4C9Xif&Xi80?}E6;(T=BsMwNBvwuZZ-7I~+Ff9W@F8O|@^BMu@m-doqNA|UM*3osmcl!digS!HU7(Hkr9n2Pv;C{y1-KYK!X{#%pIWbvCi>y*En^Bv%4Yt zLgC{`*RqZJ1(dbH>9F6~!`LU##v>YlJ&nf%+BqHmJ9`=bC(yw=z*swTj8NDHx}CJS z9N61P7wG16IPdIZ(4%?H2kA}2(#F}>xNAOfBLAf;FxR+Opq~#}1jhEHWMup*eipZeXCl@w(t#PWLpN z#l|gxh2kN!v&3*?0Yzi)ha!XyFnS9t;;11%iN_eBCrjj1AZ1Yb1J1c_$v7aWYLEj=S1u({`qm>FstAi{yQnx9mZQCw3ati0*4zx zLig%1GTYbVNR=+jIqBr+wTX&SiBly0FuK_pp_3mChO0e+4r{+{@R;?$NT66G+j%XG zl_8q@_#46xx{9fOxo#eAlKzXi&VY=i$iC$b<&Z+chg8}ZDD)< zr4#7ZU2AXH2C8-z&PvhqL6RGGQ*jmZxW%!d=|CIqi+{j z%Ku~jr!hI^S}$Rgibx|biCoQz|;}?LZH0z~y z2k%FG+6s2@o-_u|Sm@^T1l@Vo!Z^P51n``NiTw3x!1EURl}zd-oAZk1zLbc7N5r|D zdwL|?f7isRZp=Pv^eqh^EyKCnYl!|GRLq|xcfV*KijG$Jrexr+78?A_IpA;F zPa@RD?=#J9D|!VUhgpepsye@ylwQ;Co-K8%+63yl%*#q_=zk_gXpj|Z=MPd>23zRh zxw$}QW#!@}DL|WkQsj(vGZi7GE_-H!S-LVSFb8_=7#k*@#*Yn`*Ei(!F*f2WkxD-Q z8f(40VN>GfL2Nin`4pkS4yepoSSMqwOUyZAd9+X>H0;6sA{xcW?1LYNGf{V+B$0dd z^GNHy^E_Vub|&fH190AjC||dtXt6q{8*|PP)`6J9k5>RkT4?YbCvcRd+cw@Q(=1%& z53K2=D2X`x!wYl>?jB@473FT|t}{ERJqjU%yQ&P>GpKDNp^eYG3)m~@v@qUwX{>XC zq_K90uVp!V2g&0^7w>fek^2N$doJFWjAY-S32w?NkjUpmfpaZRgbCS;HaY3=aneAV zN|)%IHXzQW#(q(p!uQZbv&@>LU_GeWjTYLtqcd=Yg?9dF9B`!}_c;!ph1uV^$_jPy zKoMHxyvt%Yzkwp1t1XP<&))}JW5{+U@`pwP*IMZ3|EBqGogsH2sr)AzbL*|p4E{B( zqwlsblhb!#oEwZ+MH{mC2FiJ(G2(l{+5F5w@FuI^9Nuj&aI;}wMncNv(J{cS#wCG; z{7G7xZnF@EC=)f`}A&~kwWKTN9S z528=mQpZlC&PWdWn?O5X>H)S5`j8Q5y@4%38V#kz!^n!ogTtge|H}`F<3|v4zWIJaX5pvOhF0gh&! zFvR~{Z+MTG2J+KmwGN}EkAl47=t?>a2E__aU9KpP$D%_!OlGvm=wnqm<{G`r8o>p-_Nt%rBZz+5j)Fdp~>LVq&FN{cPSfqbNB)r{))SzWPI6Wpg zpTXD-YkM6|C9(=Jjj*2Vt77=|k{zkAJU1xEOx_V0pqr*)xiV*kNlnM3#93US1goQmZ=&OrjgskwFlVtKKhTBwI09cWPeS>QE9DJ{wVkd9Oa@ zeTv@|@on{K?5#$4rMJZ2&=1s3QZ^EV_`w-;v>AK|KXVpAzBA{spYK$Zne$uBoEH{g z<^o9uJ6&mJ?M@w1hvm`CC3J}#GlG)*15z6^SNTgF@Lo;ipFIZ7HNV2ywtAK_bFH=x zo)Ze;xz0w;f26~?KAfBh_nIem7X;>dalSrtxwu?Cb45#?Y2`k1r6hyBGXb=jDoe_d zJOjxcGY|Mx*rk~VNf1i14!JsJ9`a9^4!?WeL=XB`B*J-EIEOPhj|k^XXy(j&g)<+5 z2+X`sxOaDg_fa~7_S?q7d5p}Re-L)qGmi@=I|k?dxzxyB*>Ikqa{X7aQkZ#CI6YXc z%sfT5&mU9{=jlXL6L+*wv8y3iK+fFDK7-H9rqTE%QvMEPEQ@0Ds zVvj?g2G>Z+W)(}#kM}MQq~zoF(BO@%XEFk}97fMj6aPH|wDq_kgPrLJ+9qcQ8|wzy z4mKs(8NK2)czec1Aq(+o`@uV8_q*6*!w|MhlAB!_3fe6xj!oVN+H(Uvi2@VZC#QgW zWuRZIO9tvOEtcf3%=Nv7j7MAfFu- zv*u#cb+B#T0mf=BD#`&{ON+n605}kW8lzeUyLTlhREF7DO%uqP17O)7Mz7avR? z_aiKmYfU)r6QhZ1BGk;yq6@_zDOlsMPDKszUg4TZ>lHoxRRYYoYob)^D-4{L;%l5% zWEzk+&@EwqZ#1>0_JN17=u$GylwkFi@lqmk&-h|6)^-_tQ4);mcS(v;-E|zmY2Sh& z+Z$^EM@LoceyeL&$?AwnvieS|ZQ}5>x~}h5s;Z4upxxCo<*|yL(OdG>_42^R5ixs) zdAg}pfWA3fJxe}ra|?@EJzG9D^DDuW&tiXly!vNO*#&}tX<5U@zBZ(q>bj)GjwT@wJVA0p7r_Vxj7oFgbsT;HwU zyj@Ttqw~S)trrFP8J!1Ko03vl3?_@}?f(>E8Nzf`?~s(qIxa)luAf9$7F%5f+T(); z)5CoC14=)odY=r;VQDo8JRk#e*=2M^b<xv-j|9cswILux9sr*Ehi9s_-yS zFF%_x4<66TIWd{N(GB#R9IkEIPnZ(IpO@W`%8IcH3%_=WiVEQV^YKo=7wF4B*u65x zV$h3p21S3br)DPTpI1I4DrS8Kf?krJ>>A1j>;k;!8V-6zQUyB( z+Y)}g=Sj+?k_{ULdR0=Op4nr8uMy&YyUK>+peWpWgA0G(=3E5OdV_1b%EnQ%-k<|B zx(CM`7z^R_m3!cRm3;@T3Af(hYQ|fD5P$gFGW3Yb4$T3+Bk>s0wgm>>r7<90A>39B zeorD^A@o!5C%e#cydtf#!Fj+>Wi78DFHFMWpKTSPcu((bbbI)JcnbHHDIIZb#{W8Fsr zf0dQSyN91sdR;(uX^KNt3~f`jMzMuK3MH6~a|j zM4&5v9ZA@l#aA_cHXdxK+g_o#X7kb9iB1el|GG$V>33b!cnkxW)rcu|RmwW2B)K41=aQ{) z2t&V)lUCE47Ieh1E_%7Bj+@b6NNJ%sMon2~<{fhd?wqeEH}!RKY;CQgtgn}6feP!` z7StfghU1&r%KBN`KBbHuY#h2^{cK4tw(&S=N{B{XA=>!R`(MEw~{nl*q0_ zVb?E|X3Ed#>&)vH1thj*+hC{GFP43S&u zhULu~)G9b13+VnXte&D~bC$CXU+#^T3ucAgG(WsQH}E>v5{a{2tldzAd7BWO))X)J zKuJ<74K@QUp6!!w1Ys?Y*fBJJ8>oFoWNs{Dutr z(k5M1W=Ely4eeW_&gngn2CwQs zLy?|~^ggw#Kw8JrH_(Hr#RgQv)zCqfKJR}@pa1h;OJ5MvM0p{xnQ$t()v9TVa>RQ> zrB@RMpNa{rfuc23$R4(d3jz(}3*q++bRDXr2pSoKn@HHyiPws3B2m(}osp zqG#g`8(Y@A^bS_TW~o~^W5yP+VT;t=dZ}7lB`sj*514(<#05^)Aj%GBGgTC2m7D?Y z94Zhi9HAt83J*~zRyg#~x?$fafmq?t1NeshbpkOp2U9NhJEK)L#cwr=;%_8{Rf1nZ z@V0y$BGnDRt9M8>(0X@?c_)Gf)gc8gb{g#OTY!TJ=@cor@i5Y1)qAyW0_)KmL6slC zhiu#Ko}h{MA0aYW^m5Q7sxdvB2vT#Z;Rp!brnBKZd_E7=Cc0DL6q_Ec( zfvf`%gYAGU>h|0a6|#vFk2>qb!_MBDg0THk9~>}~=79_Dz@r=SUGch!Y>kOP@po>i z%_8bW8P#A*P*mLmlI*fwf0Nc7-x)*tx=V8GyT!>z-DPSd9U{0%a##Kfk3v2+C$pQQ*@n1?4bIQA*v_(}Hr@m(&5z%4`Z@%|3=? zG=sDvtm}-!D=w<7qoC>dgm%Q-*;5oYR&IY3_O-d^f%L#{|IgKV2S!zNfB(+iyE_Y{ zEMzAnn*f0X2oNCj&;tTOLhn@|2~B#*LPEmQi6In?fFQj~69g3n1r-$^5fM-<6bmX= zcUCrOwnrRqJ^p4wu{ zGZb)BbqUR@CxtzyDHN;a>BgShsEs3m-FZ=2x>^al?CHVSNmW7p^Yj+QI;gJd9n=F) z9}&8vxw|^_GMDg5v>^~w_9RK^*KrprCkIX`Bpj|hXJA&Q)C4QbI1I9rEILt8~Nd7jW5{j@7_ zgHVU|z#(5OK~7Lppf+cL=jsg9d%k9%E8;0&#-6W-9|RXNW6xK!aPUIj*nL2#Gt3;)e&{M>GMyUKw;1znE zpx)q4i?=+hMNc+{eX9ygST-6aX(<= zLE!CW?{leOCbQ?nB#aEbjx>eyC@O80K2e8+z3ig3-hy?BbfLjTA{u2)H zuvS+Rv?iY61t#Zh3+t@G-J*8Q8WvYrg4L>(+wZw#mX*;Mdl@yHHzD#(M(+oNK7-Y#irc8q>XPOZa zPDdwC!2-)VAg7u@zWM(G`IZC0gsmmNKlmtx@0F1#Zh2cgX_YQJ8D+YUrbR zaP+ec%Te>{0u|$U^*HiZM&Gk=c^F^G%7P|(urn{ty9F2{=wmC6&cap9ai5ffODwx! z=5khC5CbV0FfKNxE@#D^PJ>Gv`w6+o={k&&j5kg=eh@AGb$TD}hsofkVl9%V&*jOZ(3>+C<19$>-%3!IOm8)OXaTq_KaZV;Ghsqy zN1b`7ZbH$ys`5UruCVd6#-yt3Bvzr7)i#|b{$*$8tvE9zzjXJDbt)g5Mcs<6@<)3A zw!d}eTk?a_FJ7!0dNc^PU%p2@ODe%1`RgC_b1RkNZx+H$dUh;+{{9et)|xSTwk7|d zx8brIcuRxGFMpDCnqw1u3?);Ks3j=Ykgadn86PkOjt}^AAd55PtzHsg`K<9(v{xq# z{m|-LmX>ZgwJy}W0le{ky9m8ZWPEcIpikZ?gsg?3O6Wh$!;r@FDPmIvRU3M)V>6+$ z@qqC?Vl#o`X6yaw6F6=-{{z}MAz*x>jyjtVN__h+R(V>BbBo}W(o?5ZC>wS;S^i#~ zw0GizT3gE&zQAFkanNahwksTFeDgWwgpku=-6qa5;XAVXWKb@7rkn02qK7##Xh`bC zAQR`9)f`^E_GMz8Asj$d+V7=mVY(Rpp<;-6y>#A7@f~}i7I>v4WV?EnHJPS!bPP83 z0xdOU%kr=ulb4xEeMb&C1}ZY-mUT<7zSN-Ex@cT;A-zIdf$U^6ac{{tVE3}?m|iCC zOoLu!^YtS*-lJz}`uJO6hV^xvVx$jg&2BbDQ@lRP zJG;4|1bMa!WN9Y8NwRr7sHLG=a>s+9)(fst%93SzV^A9t!NGD>)@UFf6gpf^NADxM zy$N)b6!SqHqK?ypIg#VXTiG3HH4NQ!)#3q&?pu3>Xp)TW2kK1C4a|{j3=PWeVrZ5; zkzU&Bl|U^z#y-0TEpDYcF6rv{>|R5zn<@>ZY4a5HWOix(D=k8gqwyH-nJj-Rf=W&? zk%75GL3ySca^$3RG+e+vTXEnhJ$Y^*p6@({q$u$iTE636IB?YjWh{s1ly1NvWggGgeL%@EN0d z$@0h24zDJU7znRjJtt%v)L+j@qY0MWLs{`cnTpdW+4G{&Jg@9cnf9^?1z*KscRjBd zz3|CTsYO0RA8Tkz{P)t=UcE2&m&cI@Deu`doX;5mNlF58!IiSAw8m>~(uTs6Bw#qA z=%)K}JzZ>@)NnVjkL%knC@6Gjp+4pMxtf1T=v5Vs35WO*9ZPS#R?{BesMPcNC*?@(=X*Be9)UZr$B8?oVQ1q)@dqp`hYJo@8bVof z=9@hB%dBaj1%_gDoy}QjEK zmYLj1iX30M`)q6qbu)8{jgRiSmgOurx!GI(1y#x^F<lh< z2j3XpBxViOsx5j3J*SfyJ6c*LaytKjeijXUsh5@0<BORh$+VTvZ@CDHfD0lO6%}F_a>Qt_Jlrlq!E}1L|j} zsqBVw$?0z>O+FLa1LO;>XRNJGcZKeb zvpEyhi#>qjZIk zp%O@|8tH0Vu7#SF;iI-}RvlQ)+yIZyjo-@uA*Rmhg7`A&R$Cuj*-D?`hbb&fcMpQJ zdi@;zVtjsl1z88yh|iC7HCwA139uph=+kKwk3@s`{J0T?-l`T_3`p_$@#IWkZG$Im zx%hryGF2iBFz{7$OzHJ=4~3q{u&mxYddPMNb4SmzOYfc=2zDQ_pa zxj%5wY?vjQEB#L=Q0YH!RSmU4BNns0lN_Fn8Qsoidd!l~m4doFkCaenKY2EYFJ3YS z_HXaH_eGNVbnb5N##PITzlE9ui?kh551lyLj_SgTru4b^EKh^gY8+knGN()-KP$eQiL4Gp)#@2p}M2HvNhueUNa6J0?TuTFG08ZTypzUfWp%KjEdNlPwUW)jOXm>vN|T z;Va8gL$+KG>%a4uX)PRi10A)UPaAT}o>0J@&lsN`EBfM_mbGLf_E+0kAqQ;%wuQ`h zzJw#1eO2i(;3B8eIYLL#R>M%%GG?#Jg}!DjcbaH%nEK~YV2RUHqfa#{0IqOml0AZH z`)UYqr88AaW7J9XgR)jRk7|t98_=^>JLd471XXQ6qz{`-bBRgn=uzM!&Ix!XMOJO; z#ihj_)msN1FNvHZqJ3)ydkx*h!@lKF-)xU0IDDSJoz{mJX}C`lLC;n|TjPZzw~4HGWNRv!&C+)i*FLS+DDT zwrD_vYPAe})+y8p!Zhe@v>91%aEi|gwQe)`O=l0uLv$bXc$oLBx16{10~c^iJ+eCM zymL$QWufY#-OhTOBlNyddnn57h}P45T4ulDHEtu;m z8^32hV24yq3h=h`iuQnWobIBr$-3iQ*Nk(VJXE#+%P+um@~RHtADFRB=|_t2kItXk zKb9%c!sD!;oQm&I0P}VTAC}*;)$+Yy z+kH^WL*Lpe&>apgx5=_Qwi-*O&T*g79)3cAWK=xv&o%#MtBSM1UbnbNDZFc|NmRMZ zxuY~=g8j`F;0o@BnlZutP5>O{?w}bH?8`{g!rjA(LpbVPy+9@|!Z_e?ceNl7>~k0B z2XL{8-5%_B@79b7_diLsqunoS#)Nxys!NsKmo;O;J)VqWjQh4`Tx_xhz3r@6=DjZU zBl_D}aqh@VF!fl8;!;mraH!(02?tt>qcT^4tGZig#!V=nP6StT_tktHH>->WCorFM zscPfFHQckc{Ip9=SOQLRo26)HTW8VVs|A~?ndsY%jExK z)1^wN2%5VyG~aTmzN5e`+zr>jXrQvYl$W%!rF*LOaL1*-M^`PYwR^qhpIqt-GGA@o zv=A4^7`xOXVc_=6cU|i9E#P!Ft(1kqchs~5>%U6OBf)FWx&Oy;fl z$U+h5&Jo(_C|`YW4=$3uj*2P|?&%J-(g7TB)NxXhUhbiq4?C(w4RCLFzUE{2$kGGc z$8DA$9(U9V1@7xUq~#|al|+W7pZitKr*Xf^li>dDtD4U^>d02`K=(86QH0MrDx)uW zP{{qhb~xv#*L%ZZu=}>=3yvxzLo>wfxk3+IcGP?8!4J4;={?r^IBIq|@JM%0%~u_D zs5*F*dz9vn9kuQlc(gmH`6ixU2hMTR;xH`Ea@5o#;LsTNG41fJqf()5S!3P*(R{~I zRiPYNI&d@yHtu|4Drn#w?3LS8( z1B1ac-4AMck=yd23wU(PM~%vtA5jrAu~{Qzx75-PKM#Z^9>qeWhGuP^N3N;@N;M?q z>Zd@B{}$BG@XE8rpeBaG6b4+Uq(0Y_&HGweg7EU!hHXT z$M!FX(#&I+>6l$Q^NV@*TZ>D7{9>kkq<87~FW)QgOh$)zTpYH#m3F<=q9!e<^^U8n z=Nrb=GxH7Rl+!Jvvt#_A4@hQ7`d-$t$`nnGp7ZEf zb)_b+e6#eoTL(k;&%#H0k<-;oi0ps-Bl93FoXf+1^9x&!$SUr($9IZ)d6jq&I);WDfkp+GM(UVW};5hOq46}s*rCCf%GL4^v6QR zHwM1^W+RefT{JDo&3R=i(gu~sLTHkn$<_F+kSWlfoL8y9@C{BN=Yg-$R}AXk$cl^l zgI_mdESsJ@vb5_rwL?uhLsxS~%QdigIax-%FmJUUlx@h773PEZ=wGjlK}E}<^E8l; zVX`%1XV&c;YI) z+mv81m$OpuuE=@RD1s%C*H+G&w;?C3961`a)(|!W!iwjtGjn!f@Sfvj=R_X|eR4;Ov2hY`GBm zlRb#*M&!6`D|<+F?a`}0*JKYZyl%3GMz-0*R%!CdgQy1CBlc_Z%W4^*2VT+?BX1&w z*(0wUMVZpMc-3JTvPZqIg$a_XM)qiv2T59mva?M+O@@w?`o7;9S+o=D!+Vu2CcVG( z)c4hzZ_LF!S40m*TfigM@|2mmFC^kI+XUy;=XOM_XAD!nl=^SC3SI1lM>g3}izqq? zYF{hhX8Rn<7dI8E?@){pTWmL6F@uAVx9F`eXeO66xe4w%kPcZ0DwqnxZ{75m9ynjY$fdZmfvPTB^tFwCg4!j>Rd8w%tTjvHNM?sfza9 zL{ztzX>6*G)QL#6k7!I&w9_b}Ca0;5x`pZ%k!({J4y(S^rz?T=Y-;^ce(Gyj$%quj zu4+#ebmSuH+vjvx-PK$wvQ)dNF2UX^sx7dQT?9i$>ynB`0vj_9R0{|Zf}$QqcMBT{lIj6N-{p4s|Qej zB0BPm=cwq-z)rSl6AM%wgc8x&o{uI{kJ)L7YQ+7vSq+OZd*LW>H`^R&TO<_Sj?IKxZqHl`9oD7eZ7wO!ptsP5}&H`ei-U2A;;caV=T4m=x0B?AVyNvjgNq7rDkok zo*^cMr$mgdX42qDO2g;`#0@F(%6>aQi6?b49wzIx2i3f!$tQn=1sGk+eAV~Mo)b#{ z`KfZP(cxHn8S%T2F?p6XrjiNOk|!pCqSzjxt#0#klK850^v{olW}%c)c16iAW@8S| z|M3^}UQ6!4sIH70IRUn7mohSZn~o*=Li-Gp&+h_78>{WpJ%n8`rqDYu=`R`h|W+zv(;4k`K4vi6{c`^z1|cosj(J!zXr zT8cLJmpjaeZumCf5k_xF{rU*_DdsTsWoO_~MqI*l03q9P6vq>`y099;lPrYwtAKW6 zc^KuCr`9b@FGHW=msixAKbBYG_v^*3WrUs9P=@7v)`C|?gc|-2!{p8RAU=A*Cmp1t zjQsi{v*k)hCo#qf|ImZI23<(0!snF7&;Fzd4Tm8XIS9ll9+>h8EVW4Kh$6C6&dx-Y zu)>!;4xgjRELWl}EiJ2|(j|%F8G2oF@h4_h)zV9mi$67+Ud&?d;?ImMOfTjxzG=uW zFJ>aZ&*@4NYQXdckT2$cO_ZQFUlxCLLQ}fgI`g%eneQY6$hhKfuyuwieOEcECGb1b zBy^YQ3qju->LK%yVa2x%^)&l&?ilK&XQqpPIB}F-*jq|i$KszTbyWN1kcq&bDMwt1 z3x)gyYFYft>I6dc{%HA9@vrmaw-TfKcOM#_;@`~94t%wFp$)LK&+jVK2Q~ZS;)U8+ z6c5r%&`_PUEh!!>=vxeGwK@|8|3k!|-w=kW{gJ?-BJNv4pQ3g5#lytUTIyG{(7t%M zXs)F(igqy+j}YB8#;f)B0Ur>PG$u6B?Md-SemF_hE`WHnn4!hVYE2DbmdHi2ap#M= zjuA?6Y0Mv8;=h2}dyBu)r_>dPi_djASo&DH;?n#-CWOYrqWOxe34N+taRMJ3Y3ZIr zadl3p6Sti5zlL7xgMB;5De5@VRIU_6Z146SZi3o=W)-c1VKY=Ql4@l?aYucCx99;WkO z!oTW)pO4V0nAoex2a%B|)XV6jW+d?nRtRc*hlpj=!s4Wz5Y*)Y_(_| zq;**8Qp*YJii$4EPPY|`U4md_MvCxH8*63MFALs32|eYE2K<=tPtTcbWi(`|OZ9_t zWu!7 zdQ|8efks;KK^&v_Ftc>o0Vr|8aK-iHPRfH<0 z{HkhR8bVFKMHyD@UgT+6VMfBe$j?0htX>v*H5jA1j2?oLK>8E=C_;5*^x{x^mnB8T zp(V-ab1%?O(eP*VWwfo-m+_b{BVL4JW>89d3QBp*?E(1RPf$!_3j5-Be{r@S#r-4g zJq{-nQ*jLt^i~)tEAYo8aK516nh(2!Q*E3KECJyX*K^qJ7*LMwUNqgo}eU=o!uD+EEWYie4iEQKNvnS_R8N;}%X!%2QJ=kbMD<#$=P;n%|8^&w{z)-!o^nDEl3gwfkRw z#?HFuu3xc0zru=s6ycZegD!+OV~(xr=Hrn(oAQYAM3-K^jnbo*-KVCV%;`cgN2(>A&BOSjVbJ60Dz;x1@^)8xP3H(|Yzc;w( zFp0p_x%j=?Mc2Ltsy>O|`&={*4urvQXB==%q2WaI?w>8|YX_4ZA_Ln~ub^?t+(>Uj zL?s=*o4M&p)DN0eppio6W*R7903#nl6PvlkeDEHnI~kc<4duv6^xQTR%6NHs0cg9S zNwR89&<;b>YZ}CYzRC+ml4zFJvnhd@W^?M$ArFdIPV}PrR%V^H+3~ZRQJ~YCI=omrlSJ zf7f_H$V*#+rz+@>FXKRgBf!(Rc@IHhvTHQmGL-p}Va#^X$rYKebkSnWb~Tv+Jd>>v zvt18$1-@#+!fe;|1mJ51G22Cxj+w6;#B7&<0m(dT5VKw36@hOU#E8s;?oH-@@&|?} zB6soP2f=R|@qAmp+!J`t;9^^jdIb1ZzK#dh|1<~y&p)gY>wng-0A5(95$k{G(3Q-K zn>1qmPXbI-<|UJPSpT!LJ@DO^wG=(cP;KZ~roIV)jvv60p1)v8@Knr`WIW}P8@E_i zkFe&*OH#^_4}-!DIr6z0pa?@=IjJ=$(omQz2cz7>S5H5Om4C3AJt}t4RMCoRiZ?un zsvMIs&rzY{eNZJr4ypvbLw!C9xKy9K0?oGqm&$=l9Ew%cUi^9IFh-9V&pH17qsLhp zC+Dot3pbm{Z_$x2i~H8Hxc><) zSjgtbF)3m5#KIkAFv~!9D3yBhtOGW~BnP6~}EL<1vHdzoO?{5p*V<=wF z*DqY>^NQ$DHCWt*`zZkx&me-H#iL{o*!#t!%}cO8e;O#ukdUX>g0c;N;cc#I)Ore=f28gg6VG_|~V+&H`#`R{m^ZqHU?Pvn;BTnkY8}sL~=P(rwP0Bah$Vej_z_#WWved7>-Upn=sFX+r zq6cGM9Bl=%&=Tj*7jGkqvBUnrykh<$q3FP>{KbMxO1$d0t5}+%hM*skznZ0~%0bJQ|1e9Ns$7yj!qQNh73e??rD7V2C3Z6s-amgW zCwv|I!Y$W1@bj3Ud?C}&7M;5M^}<|cnr;OapsmT@AjUx)8}TP9X#SrRXX{3IP`tbpDT%&zRrJ-i~I3dR9u+1Gm;$gPC8Uo|_2Pv(S)Z;x4d>3N6&m4nSWk zZh#K?=5~7XWgc~AZZ`^0%{a%B<)c9T3^}sRCQyGK1Iczs^V|W3Fws{D z@1Hx+AP&0ys2`+*!Vzl4XYj{6ccQ$2dNy~GiHar9!Z^>JY%HcD_o9WLJH?P&-pm9| zHRO?~iPqd{h9qVsTLGt!L!h2R|DYcbgD+SG56KhRNPofdvfwYG2n$M#QE_AyG@k`4 zjVwk!k`G#CC|-VmZg>H=?+J1iRHfiyBTJI)(Z&{(npY>w)1yIajVwi0MenO%ouO1Y zcp=hX@R;%1R8DUU;d(>O$*tmyq&$A0Xw8kYJ~vo=B+zWwKJXhuYB$uJAw&tk@smA*=w?JBz#G zq1J*Js$+R=OX#t*J`uTs6-c`e@-~73jP;_AoL!67>-sh{IGT7q|2k2wL0D%Lztk^rqhqQu0oDYNf8B2x3L>3HT#J1yX;85|L&RVYuIV2t? zD2FK@x+epN^BZuFHR;O;##l9yqz^C#)condQ5Gy zCaWCM*&GpK%~a2YgU7HqRsFRWIF_*~PSk>VDHt#ONMveNn@T)iG#Wc+s#P#okOtuQ zOsk+kP%c=p)8V6c!GqWcPf9$IgR#`n+Q3PSjyl|x^nWt9&|d${3FEASIV=wI=UOx^eZf?gi`5B|g#ED(zNss)SmG%+>t)IBZu-#ilaPYafm1+S=oTCnt9 zZ%t=NXc@oGXEdXT(XTrI1rPC*6)xI6hKGyGvfc{(Mpa%f7kp(Mo zc))l_R&qF&fAZ8EmrrFIc1NjVrM@ zQf*%Y`Q!XRNu>H4eXW9x!n8B1BXv7fuvxzj?O3FucB)_t^J9^^ohsO>BaSs-k(T!? zVnPL^D|4u_6=;sGUcq)z0q)_YFy%{XlCh7y&k>eba!16Sf?h58uec1k-l=TGoq|zW z@&mhIr?M5-qXJxhWEX5Xw&Dts;PMl@&{64ekHB6p`PsNQ$PCP-tOy}BOMVeI5O(Tx z{lZ^GBkFrC`Bi&tlr>=%{ievE$%NGa^a8~GsC~DyFKKW8D|+3~0xd~r7ahHH zRMaIMj0DL;5ir8=$SYfv5sY?&HSEjAGZ9XEjFZ6r zY%8wuT)6CI7ahIsZn!+bE;@QM^5C+MT}>p(I#=FJUy7oN=ZDVp~c|)Kw?0W(_!A<4|>?)^~wR=sG*;R3&@ibc0=V zs>bz(%g5}ZQ}qfA!IDqdMW<>h<;AD$qEppS!R0e{(TS=`>UNV|Orjdkfm7&nXA9z) zI!?#)3r^J++M`L;7Y?Pt3Va2_vE&PmUpj4G} z&qOp+TkB|+cN+yPul<=sm3LDTtiZKU1iY7bqZeVt=4$Uv+;RJc!m%j_tIO&iw317j z85f*-N2X(5EjTrI-;akqRZx6si??jx?`@djTN!w)Xv&jC(!`?az|) z@?Y6EY$yD^ZCuUys_JGqn@=1h~TBRHn#YJh-cv1T^X}l=uMOL8S zF!;VG{{(oZ!1sT*T39`_O;S5i7~-iFEVe*V7V^xlBdIG|xYKk+z4B@3Q{nDf2#uzs z!dpWr3-{DPSS?>EFRWX3;YZj|H^(ZxYPyS7&;S6c67h z>wCT$4Xk`0ddhJSl$1NKYeoqy`m3YxD z(+F>qD!CFbxuqYCNZ}nSaIE)r%f%_cAE^*riSN4QPdUJ!DK(fGcFU6k{)boHvfN_e zuSWW@TPDHugbIJ7^kE&O+wxvU{3!?ZC!>034PEFg7XF?`8GWOIu)Lnae{`3l(7M;< zpdL=4i(7l$rLoX9Owl=LdNhTSrD4in2cF9_`qV4Y(7(b8%zj0;6c>hZ2PH-gqzsSH zEkBA~e~c~k35p1^TrC<0X(c_Yf`yqCR67qiiutDsYC{XKpZT{6>gT7yl?64jn5?d# z)-D3agakEWuEf78`0=H(Fpdw{nIEPu9E7||Sw|(z^4`XaDTj2w0pr&*Fv^A1#0@w_ zBi7bcbYw2CF05mEK!tTVS*8b6i0|6)Q`Q42Y#~+voy5?YZMNs} z^EzZ*^FBz5?u7O)??ajpOqz&UlDv=f*trwBnt4}gpjazw#sn+x8dY1X;>>VijmkSO z!%<9mZ<_(JB`?8(B#0`*I#cC>tEchCy83R}_%WK0FmBD;W5yPF zd$~t$>C=Vtp5V$ORAV$~dHYxg9ra8G5IfX#NM3yy8{X3_0-tVhasrl`QWR{5UXbRE zgrcv`J8k0os-XG3n0U0Sd9MkYqee2CSb47tnxlx(x^h-fr@E0=mNx`xo)udip*VS$ zuqmzpPhKiZlhynYpRj&kNS~8<0S*ITA@bg5hs$uV1913&9o~mS(YP&e`H)?%!leURpuCU7IUUHyaA-*- zcU63;9d5#*BRXk$*Ti?);T9Y$(!J~ANA2(}9G)wI!wq)0v%|K02iA2+5CIQmz3<$* z(e(Q%`u*j)1qnihF5ce-2}qdX*})o6)C!O$2%v{UOz74A^V`tb>kGsZ^)Su{d6} zS^_N3n4sJnfEBO{km8Y~=2C4BV@y_m)0@KCbBb!-6BxlEr>gHd0VC~H{cKbJgqbs} zJYR^#Y3j&!h%4H?wYZH+r1Gj{Pt=HOBKrWN?4=qzsdW@fKR?@5O^E|W+uO9XyZT`T zFvfmOV{i3dHDJKLsqxbSN|OetZr9Ul*Cc$n*+c^yS~O8 zRq-KUO}nMW@oGF(u-f(zjg!=7w8(jN>^zOr)Hmp6<<(=HrRZRRy!xDmIcgyKS$Uy` z_Gaz7Kuw30&1+=82-MTe!^6N$?CY8_&D?_YwV6({o@Typ8n}i1x0Yj?IUlWXUQ3o^ znz=n?Svxy6n!rGs+5@JQ&rwEnvU44xza2E~`)5>eA zfV3<*`{Am_TRPQ-yoUt zuiKv}VncrtkbeBnqh5Xr-*IsDk#77;MD{;y)e-9NIL%2;%A$K6Vf2nLM2AEJNkoeC zuSZ!lokXNHT2#e6MhzhzDlkwM zEn&0y7A~)>zW_e#g^VyvUlTSv#gI>56E?fPA;0_!oxRx&48`cnzh*b2x1uL6f9?ud zDis-Rtd+Dra&{ww2VJr*YW(cR^dxPwl^@Op(tbwZF_-0iyE4*GsQYEvR(MaecC%Z! z5w`bh{Go8PD9ZAjih~U(3=PGp zh@e_;qN%0xS>+LWqb>oxawvK?unvWzR}Q^}u1%;Ry;7g5>~B( zQQ|!nV}&&^2%qyS%49U+^P^03EcxgpklzrlC^-yLhHzWlyd}WOA0k{&&494p!gu|^ zyqdBx##r-eaR`yY>zoP5U(YGA0m+`JIf&`^a)IwE&oBlCtZIUm_DuL)$d>@7k@q8l`? zsS*0*2Wa)@H8T%ZlHbrPnj4v4PQm2Kyfh<=metVHo7d7%W%(mfD?>O2>lmoDp;#;Y zB8JcN+QuVGeVvgjrgHtK^1A0ci}ImVxOisaPnGrPBF^#a?3ts?OD&x{bD~X9$lzUL zEo)BYOn9$UAzoN<%`NMUm=h;g41s$Uo zFgfG{)-^)hVA&f~&ro@pgU-dA`i8>f6ne0Mp$Hj<$~LE=A)l;?F3g-%LzQI5LJ;S- zU*HVU+v5yr~^YSSFf{i-r=IH-k@VdHEI5Fhzh zLzY9^Fo%!)OOlIW0q3+bK5NOHm_wP<#^g-0EFB7JYh-oh$YoH1IqfJXu_9kqfTGW7 zPhL@dTv~1Bq?2D);)^a>o3gm0k)C!*S2*x~BYhe6Bo2X4F_xK=u28`_-9m7QIsj2S z^i;!wmQbXALBS&mONB`Pg7&>d%A|ln7mFQ58W?m~>QSVEK@Us4igYk28OteB!l0M2 zydo_OmSe=%#uIJ9&ZuMJ%TUEd@;yA@2h&Y@HO`v><7wR)) zC0vX}#EN)E#tMgJ$ytKJNQxHL`;BSs3G=)z}I) zV2bz8YH9@=G9~z@K$gmsq>52zgN+!I)ilb^#*8T;Rs8_C33IBdM{#J%*i_xj0XAby z!&}p=U~|Sc>Yq|bTQH`p4|f667(1yoRe>!TyQ+gI?_ev&?rJ(TGT1uA+*|cV0~u_? z#oS*Fpm?-p9H7$CYY4Vu9H`zH159Teq}HMu2RpFF3|7!XE7*~7s9IPXcprNnuBe?3 zc47>Tz}G9-gkWc}kP7o<6z1QkB5i_Qg(}wyf^Hl`OSO*%W-vM`F$$Q;Z^0t6hk)G~ z%d3thz#e+lJ$(>9R1?^fF<$je0rmpwMkvJ!?CSxC-XasPkE)#@taH#mU$CE0A1r~O zKL?9RxEZ-tZ~&w2pOH1w3J$y%rM}DHc@U#lQCk@t%!t)aPZohkiSzUlr@F9yr-cjg z!E9mjB!~0FQWLkrW7&D}to>tI>NRl~R~D>30X{gM(WeSYCnm6GzZ%~KSay26QYGlE z1g}I}4g0}|8T$jrSiwga2djNE5K<}QaP?&~;G>MARPG+&8b+L}y%e~X zalATK85ml}JV_m)I`J6eG_{#@c|GGSE0DPwyg~S&w^9E|6xO%~I0YcMgLQWotAV9{ zqI}xT&tdg3ncO{$UNyNP@Cn8+^;-zddT<}JPhET(xS!FlUMACdkTFKRLpJFUW4xN* z2lymof*Sk;@GxVNibj(Ve2Oty-5n1+%9x@e(H##S6IW3G(e|e*Ixaf+42!W)V>QL| zxcC}s9CbNKSfe*!7C3l9sEKX}$|eXc)sKquMShM`d+MG|8b{66>3cRwMgm`A3{&5Y zBK>=rIYQN-uE8seK2_iV&oEX}57z^}%IH^9=K)`1j8^B!w7kw3qwb?Bc9t=quEhW` zqpA}dul^)O_>V^DUsY9a75GgSC#c7#0?%=Q*1(bxs$=KHdnoj%?KOpUQeyLL@Eu_i ze~}Y!sYj>AjOV25K%PmH)%IpmMiZM*BZVUXH(Wlx{ZTW`Lug3HTe#;o6 zejsi8j*tc+@hY|!_U zV5mkFS`K$ zX2d-ewSi@;d>vIM4ruZERj+Ek4=5PJ6b(FsHX|0LQB8C)hWx5C)e48#!p0bT?`APJ z4t!5xd+ZHJU{v2^Vcpn@73jfmTldEz*q@~uZh^N*Mn`wgd`w$LXFp3FQVa%}tFOe2kwTGYxqra;wtk!re%@wR+tFNHG z!6aT{ZK=MbrZpLDH6sI9i_uZ?NnmY8k7^sDW-OW6s~)HetixDdm8V`)UB)ogh@x1J zF+$zf2$;g?Q(dWJTc5F#x;Y5gfYGluQV}#{j8;GG2d3JaUlZV ze|D=}O56bEH6F|RH)2|dp|k$zk5#aNn-qmX_5-N0Q7h^ROQO(XfD6xdIwkA zw<*~92=@FGTof5xW9!olf@^JZqpxSvDVNtVHc<+U^~^V84y|M7_N=_>N5tP$SyL8oX%J2qETth-$?p zo4QzfA9(PxOX=&56;m<0hjQ?{g1c=+yGet4?xpPO8o<4bPDr`Q676I5s=r9l_v;M~G;Um(4m`k8 zpPw$U4<58p+mJ1Of6nC5=#VnTsK7LMe$sCLB1z-bHR`k+=4TVsd*gsdY|~IDsSn9c zKNVtevOjAYhLT4aQ%vJ=j4@U9CT)J2v8jL7tV!suvKFTK$I{%yvy3g(MY3AQ`Aw}< zdMfZa#@4D*OW^a2p*AX>Ix;7i+o~`20#7owGcElKjP3E_JoI-N)72x?OE|^R>ZE7} zEqI!-tNOD5_!47x)sTj6FY~j#)fH0t&@1*WH1PTgwV~iMj5+G7Ea2<>@GQM|I(XKm z&mTAg7>k;NAKD*k?JQ7-DZSUUSIl(d6o-A_>&!R~kyZc%KelNFfIbfKZ?b-$+GGWA zCMWKUTHuDmXExPed>wGBHzHNl)-s9Dx##O3eX(&Ai%!DGw_A-|boTL#T+|psr`Kk*?qXmzqMa9_XT= zsD4j`fesF0L=9{Rs}&sLs)9$NX5i0x=)DLIcd4aRkw%m~hi!0sz$0A);3qAt5&pP> z@48G?y5geAc~fme@4Luy$J}fT?;p6RgViW!ChG8qE;8D>4u9m*b(prC2d}zl+RjwN zYc86^Fjeomi>jWf{x@9oWx>?>&stYAey(@a5> zr-`ZAjI;cc5%3(BspoUl2`c+Mj&Yt|eiqEvA-NLQi;%uADma%NHsJIUd$! z%~m%%f;Tc>x7GB=z?+$GAV(erZ!sK7#3{z_qVff|vWHJ>^&)kKwlRNds~>29u$}oc zED@pd-obp+R>#Ox?PUHOw*syM@8SsK6y&8;xpp(-5ae1^H}`0U{lO{7dOW+A1HdWB zkH^Eq6Z`;9LG~^O?_<7en@RWm%s2(Pq7U)|%s2&kh66sxj8l;HaP1I>k3*2t*Fb*6 zg&l=-=D-RZ8cgbbj2yrRUFs`Rl4qIUa;cnR@bk>yxzw`(@JSAE1rD4o1i!#9#EH7v z0KUllsH6HtLVn6cV;$@Q#PP2?z^Cy%%o{8)&hVuyf0+Y(0w?0O2EW1&>~qZE=?u%C zcT9)&RhFM{l%IyZue->Ux)R@n*&rP_>mn2BN_-33R9AuDa2X4Z18*CS1i$4f9IZ_@ zPPiSq1P*WW3qEkDf%(EUPd|RuvAnOr!rbdfRl%oqYUysd$g+Arg^aA1?qo$;;k}WT zUiH6&t1r5_DD8bW5Tlnb=yiNn_$oZwt6}x#5T~z;?INm%{zP%~N?r6VY?_k}ciW*L zZ3jIOz6^CTvP4=k73f2_@|#ae_`sx@jjZ`Q~W& z>tOmTj{GJZ)X|VvUdRPuTO`T=T^;!jw6cWvMf#+Ip)KKkk$%0?yrkO*{W@GH=1`<; zhu#|gHgd2egB(0n(}Y!Htz~sD=^?Mh!ntP}TqwFPxIn#zXu^@D^FY1LiZ5^Ej1cyz zl=OK>3&Z4Xs9H(iotk_y08K9GcUqHQ(p|76{a@1*Bk8z=k^v@|csX)1XyBJxmLP{h zA4&#=wWQZ4$zER2kVcx4Wdf>a$uRR=ifld==`R^>UXd!3w}D1<*It{-pU`zGd0?`p zG`XH=r19BC(vq-}Q6`vl`5Ky@lF=))&rb4k2`J0Rx>`QUhO*DT76~6S6GoTuz&~j}mdKEQ%D?~fMu=9C==pmh`UTgv zcXes*1KCcC`53=^a?cCtQ5Yda2Y#Tx=Kwy+SQGs7>u%#q&A9K#l`@!Jfo92#UOGfE z#iNxV_fgjV%M-nTUQ42J_eA=&gb-2Hvz@-=Va2+M-9#WX6TidjZbTO6$QI}b-2#8P z4e`#cfVHo9C^t+{oT&pfcr-Aa(NO~nfMtupy=qzoU?i^%$FNI~*e5n4z}Wa!sCc=R z&1zcw?+T_6BSH({sj}#)8Ov!&@F~z!pNAgCSO45Nv%D4m`6X8DdI-I_L-_4OM2~cS`vTNgxcAfSSkWZ-=5foq>f~0% zYF-R>a;x#=pgH?4H^D5v!k3njFuS?cd1b6uceQfOfpIj}p^;E-5?>!g9+BiW;aSP1y2a0J%GgYg zNOGGoHrKX3w>e`AJwC~8!I-AMjpd@!nEq8uJzmLe$>LV3-h+5?E5_F99aPfX){Jdb zT?s7v$k|rU-{p2>X*;!SC8YN;wpVnZb8aW`*->aAj%B6uvvNC&i%>`G0K~l^w7fpI zi{7L_$3yGW`Eu{qi+^2-9}5*&2YENqq60l}Q|RLXb2FH43H33lW~S(&<+ucc4&2G@ zAtr0aB^XaZr*iv<6`FAgMm%atZeOuia|pL!{5KyCLj>s&9h{@ytpOe?`fFZ{o>o=x zFpf}>t=3@Vmpfb+FkP0V24UEfJ5r26vT<}a77f!2MlnBXtLh8E+2X8z;bZ7%(fe`? zhY~Squy+g`#)|XW!&X~8+y*?3d8e&%(B9{c7lUA5(8}BD(jo8!<^$;Wpef3o$S*i- zs~#)Blf=;G6rp1{bPEX;yJ+Har!%8(T6qI_h9JXCJ8aaC6yQwpy-oo7reiUl&7H;JUAEO{_kjz=5FG(@ zJ!znqtLMzAv?fk;?K4oisqU#*IbFeAjTsg$5|q14Y7v@J-hYbB4+gD zhQo5_J|t-V0}EwcYR)6zVnK5tIQ{^aF{Fc+vyPm`Z4hI@C8Bcx14pFLrKb^cS7?KZ zu`Mn~SOgEN`2uL%_V5md2e}W6sE*_xw>@MG2A7HknsM91hk4*fMK{g3?crInfNR7U z&A9F1F#5i^y96DM2BmhXM(8Ky?h(5}(G(!AclZl^&)mJ@cg?u4c?cE3KHdPc)2&XR zUCuqgwFG1B{!f7qGUI;cS4ry+@kZRkZgqJY_^_bm;d(5daXM*SMc~5#`WxVz&+t zQ=z}3vz_}qC*VRkRj?U+f^+zCIc1^6$~_qp@978LF9&l@#@cqs633pypZMHd+|1hv z-hx_psnwv}BDu4*>e4dzo2YBKb3`;0k2WP#AY+=x7^a3`e3_fi=u>yeF3n~1tMj#i zp#tU@s{+*zp?jC6&85i$#D}6%f$9p&roa`>x5(Lt7qc_{g!8gr>F+-f`WlfCRnrQi zB!v+|M6+sWzW_d%tkA!Fz_~3sljZu?b5|$?erZ3FlO_9?oO&%`+{n))Ia#*NM+|4B&&uthXp< zp;$uYA5g=z^gzc^$3atal9g4o4h$oTPLrqbjKlc(QZ*Yt zch|+wm+7G6sF=>e>axYM(u=Ujjk@wh5!wt;ef$oS07a3Ej;fDJU*zMCAkLHMfErj- zv8-dLe#S7QC`ve;sJi;plZik-Oa01$jVw}(G5(nov#g?M?sCSfW0fGS%+dt41qQSz zmN7{^v>g~=OxDLG6vc^(V}YnaGDyG0!(1U zxf)NS^(#sh0mM4CJMzL?)Y9}P@qZ7P@_`1Dz=Immoh0|ZT`(jXZx`X9+qwx5H`BF< ze8;287By$YMLOtr7PSyZ^}}9O*bA5@UeP#7cTW&>5)e%XeMF#0*bcqIOPLNbGw+%Z{ zsZCM9`&n8?bw`U-RCY{mUG+MYwWu3Q>#5t10LzxKr6@YKuPBpWl&U-7McvDmKQ&c1 z4nf?5#c66X>RwSV5vdiijoMNZIEXP_9YF0XDqC>YNlidQQ8a{~?W+E}5;#%& z*@mJyEcNSeG(~x$7W5ANuGcx&2%mo6Kfd32Jl^v>*XykJxz9QGxtDX_HJq&& zd9tQ*gsJ14K(oy9F)2K!f%!mI-eYZzoW&Rov!@T%wYScPdCJmvBKd&Qi|E zShmz$4{vprG6^GRmT$Rv8dF^uFvZ;ogJ<^aq5{}@U#~QGVc*FF5c^ejqva?2C_r+N z3Q*k|*UcnZnMv^Y7VsK$XQV`3Lfkew(*_e|(4);}>>P|g4~CnUAMDvi%~6sqJe$Qk zt#PEy%6nL>kkjcI$gQmY5T~vj5?(bgA_M8MC!|8RGbt<$dq@v-ax~(5wUI+b~M1KfZ>5Zx>F4Z{+B~Svg=7k9 zqRD6d*R-P~u&3YzDM5(=ebsp@0*{hxRK6EktfW1O15*>$`+qw+)mERlJW;;XfN5~ZqDc+ z$Pdj(kvGniutpOkCm3y zWaocl7U?Yo+-y3#q}IPR8!C;JmeWLErN+|ole?gO*J#*!(`>Xkh(zxz(O6C^7QRBMLaQP~4)?M?S3UJ4CdNoCW-_0U@WDD=&#p^Qc z+%sD!jq5%u20{N}#wb0_a*DNp{?o)`>j;nQKw&eW?^EMC&|A_v|DwiqpaScl|7QBQ z4%Dh2#@{T%TA>oag`m08+f7Rs02hMR^oF*qx0FAw13fzn+O{q!jq5;V;-LL3`)Mfv zt^;B6XJqBGN-K@)K*u{m>vh{$x`&13GDN9iRG&hH1>w{T1EvgTAz$_M-ik9zS3fS| z{)2$xDskq9Oq;`+)3ij@urGBsB!a0KuU|=s5b5ITBu_U(b*VvZwfsZSa0w*+{-IRloKRnO zVW3zEB!j_2fxN6lvrzsS;`4^LDiH-*54Yu~-U1>6fqLPF%C$Mn$0gt$G0Q()7^W`g zw3go&Fc*~W$ZI$f3}yqC5E&L8%37r$4X2R$$7IqCXw9uLX@t;JtPkjMOyOM-aG z*zlN_$^ia&wWCo`#)b!l^KyoorR%R2yNnSJ?5sJ&IVOHGUi{;?wAYnlzOP{qk#R%K zs`7eZAPi;xkO^J^>o4^EpbrA^TJ`+We}nGh@X$R#xsgeJaMW6z;vivurA4eAu)ln{~Ou&>Qx}f&VZ-mI}wsFV zjN>CVK+-Pwws;kK*t`>#kguNh-Wq0>Zhu_D$lLfChU3jOG0XeywHb;1EwL(!MfQeD z5Y{3vgmmyKB$*XrtHWI|_CcIN;zSVnJ^?z8c*+~{nGbhqikKJwW3GlM2t5rJ%TI1s zTYl=U^xKj}spcG8UsT@4Z3!w{hIhQclK<;|cm^2>cZy0<-)o2(F1biuPKoz!B%y`N zClaDYXlo($-GZnL*(Q0%xqP-DDpR%@b942=|EQ5#mGV!(Iak!E+ejZ%N&g}!WRzQ~ zzo=04eS@g6EtRUGzEBV~zJp4ohWbE3)CBoJfh^|i@eJBQ)TCGyw1N8MK-6TNeIx&& z1>rYis`3l>FFP1&rp`V>ePAMLw*J6Gq`!RFA!@GPh;~>Uk5ZYRVhqdMCsGX|rM#bq zV~qM;+%3gj%&VD<{$3s#gv5F+k}*iOg}dNXFD4n^nMi~?zd67(rsF_eu5)d5d%bfV zu}B5hd)+WP*A0~&iq;o{6UEN;Hc!Y(YbzJrMAbJUgri{h4}YMfC|&9xT?6$ z4YexepR^u+jr>&(zH-=!vrvYB63{a4mPa~xr|)dYSJ9mNcW&z6Y9u0r%U3(3NUuji zHG8V8s0Qk@sGXb3S3K~2LVx)PU*{IO@SX4xKBx$-x~V(nom*-Z<)4N*bLXe{vf4gI zz;b4<`lrumk`ZGX&lPd;!qdgmal!8yQw+%7nTjUirYeaWUH;CU`p{|WQY|J#g`LUR zBW^nNpM{-IvG3gsbs-Fs;t;11<|l5ZIu*x+$QR8Wr)*j8uSFdZFF^rv-nBqiS*A2akgSk?@nTR zz6~MHa8$30_q_fpC)t}roFO=5xl@?Ig-~a5C1@WLycnvMW4hC*FNLc0nC^7y&qJM( zGZ20TH{f!pb95;5O!ML`brK)yY}f=n%Tyn}^;KS0(diim!yHo{+Qk&CqEoRLibYQ;?JhALKiLyYdDX;lhINNrM(O92 z#mMX~rwnk;)P!6?i5u9s9^-nZBqmpB<=qkPN)`$8_IM0P?(=4X5B}Q=CZ5ppW(y`1+B*bNo+Ud~bXhq2QtI*B-~bJwXW4yq2-PF>HPx}&1rsV_49%VAF0 z0SLdr^vS#emsY}@%hHTq;;p7@Vb1gn=#A9Z!<<>+(3@DGn_*6ip3s}wjP8Uv&y9oL z!kc|}!yI`dhPzc=cSAo3bB^Pn<-W@Je}y?GMQ``fFs-3eSNhow>KP54hN5>;&uZv2 z75y6ZoQ95nQ|Q-Oz^sPOi3!lVnBj8`jerEytsE&;m&Rq?QP8s2)n(nEY@r#ua3dp*eg+^^^?(zp*$7I#YFcM$=&R-R{d zKVTZgolFd|?uRT+DP1k6Da+|<`G_)9SIftgRdhX^p{$|n;jEHa^H)drq;vFcpzGm0 zWh19z6f(ZR`wZdEIccY#P)4Z73EfXw%1E_h%gtMU*TyL&gLU5WyLQex>A`u+?>ab7 zFO&WMxoT2a`>LK6b-$qOqMpcbFY_W^H}yn@`z3RVawe8RT3=E2QY(esuNgO5J%;IC zp>H4c6sG$Pefz41Fx_uO%9^|W>LE<`D!m7)M=;%Ml!Me0nC^F!gVh6=?)Q}O>iJ9e z2g)Jp@k{qQM4Htx`R<>m9(sURuTq+(iuZcBf<^9b0<>nKtAhl=+;+& z($6U!58r~6xW2z0vJhnQasq3LQdO&e=R1vIu3U z^Mi~#MJcN|g`|3mQPyy}J`b62dH0D{mZBqeFSFFX8Br_Yo0}4xwDC!qK4;B}a$KlpG!O zH$~9@IXqOQH;0F6lpGzZQ*w03`@{%GhnlPijt;dbBlK{Pw@NTl_vkum?Sp*H8qZjv z|JUVOl}@@#*Q4yLyL8?%!7jQFW0{~KQ_XI=59h5C?4i4G-YUT;-G%d32}V0kENZwh zx1o>omK+G0Sh%gB`~T}}p_^Lgv!!ifcF-Sp1l(|HT$Kw+gKow(9k{60wLWxnOZJsr zdAjAiPz72q4YVu29qdG=Ku1{mNuMLZPQH!MdT}5g%n5enRX6TaQV;Uz(1~DY*D4rV zSsPO%!BfG`8^fR@Ej`0J6YO-uY};*3eI;0Twsxv6@aR#n6C+Kkz1luZf`gsp9nc-9 z{|qiJFF19vM(_zqe_CNDUOK0&2}D8g5O!hblnX;wZsA_M(!TJpht}}5%8$?Tp=|pw ze$P6Lf~wmaZaFT+FpA^l$nF!i%w^=r6}cOUmA5bA9=+UdSyl`(ln;R440Qg&3A$U+ zR?|ga@KfE6e8qQMf+?oflq&uEIqD(+W8GG8e2#{cHgz1?6;WDUC(l>28E3Xkh#S!VBG%mF8k`$O|BJPp%Uz%w ziuMMMHG_N$MoUIlYB@b*-q74$tMs*6PB&=>E$layzFx~IDwBX#_NPkUtcAx5&`j)Y z%cLB4YB?{;oUk3E->s!?Ww{+~-K_qsr9KkucA}nE+qo*`>SlZ2jx|e1%YrSp2lv8r zwVhApv5%hAi)uSBi+_|YXP<^{U3WK=8T=WmZnL{1sizHgcxb*FgVJ)8+?5yt!J=VtrP7QVrpu*j8c3ssj&J1?Gklj4qzNu>S z!eD3P80ZOhepd>7aj?^0+Ra4j%Y&WEtDz@RUm2`>;bgX}YlGFIHg^j1`+l%K+WV%m zMArv9`<5U9AN9?_@_uM{x-D;v#O@pH6m0in;66*kT^M}zr422xE8sekU*$hx36?X1g?4L| z$ky4mQ(_tniy3DJ4Dx{tcPS0KV31XE?s8imLiek@7lzAnIP~nL&BSm7hQ*06thD9v zalguo=GbZ-o%D^zw9mh?f z9Hick* zJB~Y&am$yEgZ7y$pxTA-Id2E9CI$>}$a(LECM}sc?8~z2j3-A=PY=1Tz zgyG1`{M?1s6#WniKKz-B(aT+AeJGKhO2=YR7x(1Ux#4oQF`hDelz#f$a3y7cJ~w=x zvXDMETtyk8&kg@WSzMnQuC~(Ai_ncq>FM|y7O$M1j=w+|>Zp0tT1!S~nO9bj<8Y3e zwaAML>P~=MM~U_-$BXrpgPcR5kS|iE>i)Wcl{MM%t$7XJFIjr9pN2>HWD2%X<&5hs zruw|HyNMe6GjcNgH&f%zal_KkFRO*)@?~A4%rH56Y_aS#RAjXb(-`V*x124K>JDy? z;mBoccc)01C;I8Fe~sRFPAml8uTvJ%XCJ#LL-g6lZpz~N>|+mQDSh^lOIc2zeC(wR z)#nrYRO^(Ae0?qI-`&rOt)VOS0P8AJSL_>0Zn@x)AH*}zkbfPGy+#`@FLxT5slTIi3c-!PrTw$LB5Egix=^#;&qm>#D4 z^>6@o&vI%#yjtANbejn* zvYi#fq3^H_Ewi09>>id3f5G7Wi z6_80*u)PF{`NF4QmWs>bF?QH^!;Q7&5_;GW%q;A!I6|q#{BE2rM})AH#1a;YT@F_LVVT9x{sJ2D+^9~QTKecnyB zad7hKb^dOOEh9*&FEijV!j{d%qx>kD+3;E12$K^H%-N)<1?3#Z%(E<&!pm8VzKJQ} z{<*D=7%z#xoYiQ5X=a7wtOj21h}TWu13%_*S=XlAI}mDzQ)!pp3O7)Ex3 zj}cVv$UTt?751zOSxDWI%zpB=@(b~=gri?}qqJN}rMUl$c&H{b_K7NGgh&DpZ8}#Q zNC`qDzW%7ATH0Btj#P9G`WZIo6Zi$ipk-%=_lC3Cvt#iYK{LC#|2XuH?09+hL5eI- zG-fAAqH+^aK8cY%M4zh%_?N*XBs)>BYr{uUo`f1E*DdgDn!h}PlAWZKuX3vY^4*Zb zwP$8woO))b$Ud?vyZ*~CzGOe6?+}jn-;V)2J8cSL%Tr$dav?iAUCWnEwQx5(L(45@ z;n8CgjqFSUk4quP>(j?mrvC}4w+VVefv?uT(G7Cad6n`qt8i*c zrjb2GY6&N|_#V8h3D2IYz43kcr^`St!+{OnIhKFT4v@=#$3Bo}oQ$BR7_G8b_>Dm` zGRC19Z5rZ#zN2AmN^+oNm&o$rP06}7`1vOnJtNa4|Kf_dK(};#j74k2Qk#^HF zzV1qf`0vO5+LW5C6xL#+RGZRtL^LBwUEL9SPUO4{z)BF&vH_Sm9xN5a2eK{Ik(c$AwDi>#yN70ds#Es%9} z+-vym`2a}ua(TP*b<1BKmtVjaq~EmsN5x^lThKtZQkMD|0ps9$@F}FiMvGO@^7y3H z$+RQVM;TT}so$3JiV~}%c%sg7fKX|xPyHYUg!U`19%Zpxp7dVLG8?58m|z+o<49<~ z9H{TBwU!obZw^!gLS!_&mqo&RX`qg$y_YEOHm%^>w%rLN-R_+HyDXU)?aSggWiJcN zSzsFZY;;V+=#YkxanWASd8U(p4cyiMZ^S&ad`%NmV!t<4!+7ck*xzUaeL|Nc!p$)J z-k1K+vQoIWbDkMCwCY6DxIWY{^3ByjTFN5``R06x-O*BJ&iUr_#w?&y!RO#y-nLbW zk#C+#+lU;6n1xaQelMEb&e4Y7dgbig2Qvw{rJg#Mt>blg)~uZW0K(@F^D>?_LoL`A zKWkR>m6?Qt48qz&ES*MY$=;4vCu3bQ-BE^}s1E;aen;%KU5m>9c4hD%e{BjPcH4FX zq1p{ornYU{Z4k9x2k6im0Y-O6f=2^QTi5eDs-8Q`!fE>*U!c^5(PAjV$#b+;RqpsI z|LpiGYR7kb4MEzJHw-h=RGmx;fFVl#b(hiD%rGSk`iar~tEx)xg_bJlUOroCNp!u$ zu>3k=l(GDLt$xPK75+r9Fq{dS=XBDNY)Ne4Z=g>4tV$YBt261drX-Ey8)A2vY#OgW zh1f4ys$dec1%A&-*|5ddlb(dvfK+HyNeG*0uH_U_57WSaAKYa^L#(Yy& z?w=8<(m5n`conkMuu-E7^DWtzeXAkSrAR3RiFA}EWge4!`mIM<)bM~n=CSDeQpA3@ zVU)1}{nIdy_b&&h?;a8y@DjXnBr$9+F#0Xoq&@gI5ZCvN7#Rpkp})t-V9;6|G9dI( zBY-g|1bNADastU;#m{`de>~)H@s1UbK$J_$W_}PY9@vwu5Jl$OWnpb1+i#wZRv&** z;akJnNy2~3@Rr{M93uvshcR-Rc%Te_{`g^!bsIF@G-l6$`Dwj7vk-4Na-N8vZYX_J zL%A?_XjwJNcCE7 z2(~eCGE$a7HXcG!oeKBB@ena{;rdIWErz2=ewd8JcUg`_3@v3)dlqLLkL}q*u&6y- z#fP{m@1}4tZ;ZJ{Vu5LR>H;ZTfRMZo!yUa>{=JHS18=Gn;Oe3hfFo8Mm*L2S0}1p) z0#Ypj(k$Y2m8jy#Q)myW!>3wWI83TMGgWG+fpu`OIMP}Z79cgLipFTJ@D0U{=TTvKl5q zWpie#tZ>ACZ-!}H#^l;;t;P^DLX8{h)jYcQw~^l8Q4Jq$W%%f*hK_bJbhL8QG7VEZ zRpah}5yWTUfNF}%=#(FixtM#~>_r|O<=&e)P_k>KdP*W?mj*>e5Pr{G>6|!UF|JZt^Opn8lkG^C#fF22Y!}4poi#N zQmw;U#vo$2*(L&sbje6cGR#scmA2Rr)&C!!XQ3=@`XZqCp&LBnm9#CwF#dxHn3>O( zvDt{sLCBXYAo*@Q;tW>>>#mMC!@K6dN4wj0QN?^(&FZlb_mjCu<=q0<{}@xHl=620 zEqeu8TE7CbaFoOTy)3P=adaA-1MkA!ZaiEuGx0At2r66D^Z3^kDrN&5W8oOG9S&=8 zpRRjB!$`S<#2Uz0cLaKi#QPAALCs;t0m5gbAW$ZLX1X5n2knKA%+$oVOgv(vPeR7$ zY1RG`Cn1zfF5{83JYU-Ax>{735i zvH!I}=YNvQ9 z*}{B?CF1R}-eTw>#uvn63_b9isfw{3#y#ROpB@=#*{9IqYhe?!KOO0tHW3T zjwcTeW9leY0~U1@YligHK{XAIhYqUo8JIsvp@x(}X4c}N0}A+%bSF77RWqNF1Gcre zze+v+e^MWxm-^Pc)Gz;&dWhc5SkJ3!-jeix8cKjsxZoseI5?JJ~TdyqBSUePQO6bX#OuSkmL~jJwlP^b2 zz77}3n{1U-bL%gmQ`JPZl!cMfhr1(~#zrEwV@Tl)3a!V;>T2d?s4;Ja9`pK3#vRfS zbW0;l@UtIG@E34`-|YnaR5Q7u3#AH#LOqE*^aTI93Myai=p|baDf6G6_?bUi(Qz>J zk`uPhH0EDwMfaCx+Cy3?#@n*U_gg%@%!(ZAC>TNaNcK)iWa?7cW9*2)SG!E0P z&coi(LvG~YdD#AhZiwZl%WHO4>Dj90bb7X$vg-8mDZ3umwcChXjv_tr9Fl1BND{4e zP<1$H`%pCPHX^Se+QD)%{?B?O-pq%xp7~JLvmZ)BySu14#5}#5BAM6JZk_jB7HoERv4?tEGpQ#M-c`{x55T zuvkkCEk;5H%yQAYF7yiGeIjuy*uLmyFhtkIzkwGda(lR9df{KFj+2Bq z=qJW?gbxisoa%OTri8vJp(jh|Ec_dxLvKWAIe<&Z`VzXX{rC|)&r2PtcKHxb9V(CM z1iobg@+o6^#iQBye-g;^QVD#M7r(Sz#xWAhpwUT}48dS#HnpQ)hdX)`{tcAxqPKe! zu9)}nuML8?J1_koyQ?oENryaz3`5XD&CYhTg$@w?t3>QC5rZLP%HZE~h!|51j&mx* zUefW(BhDa+*VB&f1s&ZU{|07CyjZwmQtQ0aPHwyRgIyQ8zEGQqbihCLBMYh2dHigH8T*PM=GhOGvW_uyK~Dr|+!fY*b|eDStp#U5 z{KKKj7(=h)GQQb(qzY9?LPbfaIS+>_XbioDYwl)aPldwy4}#&tNk+gX{F5@J8R>gt zacQE#Y8Xs2-EWj(EDY!e9|+&ehEZ#X>?epB10imvE1!(43Wia$zZQMcW4GWt<1zhl zJs#oWv1=BclC&Xi%z-$&UyGR$$bZo}suGD1pHW;KivAUygYJn)`EgKPGMXvGtb-Us z;kJSpOK}k++mdk6h|*cXABb~!(k74fSt!q|YkunQKV!dEpe2LsA?6?2A) zeXn;>@u#8cO6-#7zY$|F0+c{ISFO3Qkv?~jVbpu8hl&<37C6>GlFR(85A2_t&*=2# z<={N3`rYYB!e^#0s0P(%quPYbaVU4a;#OB|g=uE)Mq%njTGx|RX73<2E?i0RQkNOV z>Z1E~K3@T==Ccq#8tK*B;4JRtk91y((I(dfZ_Snz(yR9}jCq5Lu2dp^2!tsOWNdZBBynQC;~%S#<(nDCOV#uyr&pZ^QT^L*mCwFcA)3&qHpIr~exE5m z0r*f!_PDEn(>B zRIl%5GxkXdk>IBNZ;;XWyu<%mlZU1z=DxJqtYVozdGBp8JNSN?*u~GZ*X2vH&rFIq zv~9SbZGT%Nps1gpeJ3>u;<;k|l{*5VHk(P`!gR(C=s(;JJPyl-$uquz98 z?c2uI0|V{nd@sO!&fW^^e_$=*+8If9siZ#Z2VAv(wO(+0*6bND6A7E|c#B>!OZpD_ z&4BuOvJ_^ay-2xT`=hA=E)0kKqzs29Mc6s!4CoyDO8sxX2}rKfAO-ddD$-{A1?{$j z_uHeA>|iO-YCB*ntmjmSEw-d`ZnA927JE_sZ?@rYZNC8l#p^Wis%q^}*@LM$H1*j9=m91v43ME7Bl>ThzWb(ZUAuN|4h$!X$~Npvdm$j*PQD_g zL;|M$)g_zcR@UnDbQ2=Hq${iTq~m;`6iMm0dIm;f|+ErhAJ>T_5*?UNtL) zE}1IgM^kDj&)r421NMuD*Yj2LiRgP%B-9*BcF(;j0kU0ltR#E74|~bBr~65Zm_FGJ z=z4qYCuvqog&}(} z4jBFV_MUk?^xB_)|NVFF&7I~d%k=Zo_n4);&vuzX-i}>nQLo`{v$V(xW`6C}bvL|1 zcbi4cfCq*OW`PIpAa9X)77_!#=eyfXHA`ssQ+v$%W?6AJHJ=bv_1@oupcTB&VezCl&Bv#)Xl<4G>}=6n7yZ4rk()nTkGQ6($P)b0r3 zR_&InaK=vU4j1NXcZ5(5tWqSQ+{2N~gbCUmE*zrW5klV>{8MEW$8_z}NQf&4DkY(u zZpy|9ds;eGVIS=d7Y@|!2w@EE!Zht}BuuAWI9j=VZiF~ykDrPlj<>Zqq8wKtWUGbOwL4sRL%Sn{xA0T3Z~5T5r_~YVsDRO3q6@2Ncet>s zc1H+n;isaDqoEc@l%pSn#1;qOc1H+@;HP4X!#6^!BZfE@;wRCC%d|UOxLms< zgsbpV(Z#V|izCW$3_@ZHPiS|z@T7J}2tUG4#TLh>cwv{QBjPfOV2UBpg+;YHTv$xI zBZS5AQ_;myT8ksfQC^GVhB)eIaY8w|LP)y8DD4gx_7XSRe}p*t;-?Z8$6zgvD8~{A zi7xcCJ6yO@yCa11dPfyo94~2cL^r^T z$Jbh%P>$UgUnODTe(eqyzOCI6!gpvF%6Kf{F(RqIWf(-B#}7C0cgm@uy0U3R-9aAe za-O=kuR<0;#|*{~Aq7>GGg>Zs*3-@^NV*YzI2#mnP|hgkV_?2*;7JvUz7Kd)J6}T} zbsf-%!V9E)#>bCF`UoYvt4oLQ>JQUe1G8DAgZaAtTLI+YhihrtpmUN@8lfccM(x}K z{HC3<-7WuH@byC>jB~0C4^l@Eqp%A3AazMcZ$LjuPM$tMI&#I1N&ZVRq44eb zXfjej*&M``0=_AyhHy)Ak`|njoDAV`#sgntV1QGu=RQ_Q+(*;5G>oW^;5@HVjlv1A zzPN2fJ+z05~->qMn62N97r{1$a|Ck)ZmMGXI31Y4rU8rRjyD zz$wY;-Pl(){Vaa4>KM9Uk8G#fiePl@-YR;(yy&kN?^1^Am=xh!uQw|{I0J5)yYVM;su`R<%pI38>Y2FoF=<1FjmoY3v)QL$^YKZe(&92RQd1Hq z;5>NPu(;8~632{6!H4Zq(%oUB(i2kSG82Xm8*RwhE}Wy%M$7XiV-nrmrGJ{0?V<_e zQ_{vDiG;*whPiR0Qzj0}-SxNmLYe9vdpsT5HndT_uzC$c8#ZXrG%T!PqtF`B!-j@- zN^rHkZli`Zb9}U=JMX=!*3JT`iPRx+ ziSDS>+=&uYb@e`~ng>qk;ZLKhKhs?FUwF6R9(ubuC zO&yloalSRu%6)Hvwc0NGe<*$K^u<;`(>uGwYGGAb>lIyUtvAi-b7)*c5l6~(rey(!YZA;TVTGLui+^c z?}_C|q)uns2=&^-Y5DE*Ml46DZr!{kpgGOkx7@03-t@i{T=W800Lfk$V6E=%4P1dR z8@=fw-x%R-5qZx$ErE`BzXSPdoj37L+o~S2xq=C6yw_cvuYG13HN7!#nxA>kdx#yl z#CzLA#^Cp0z6&cY1kggADMRmf`A#Cv9qHMii(3>}txV~thZ3Jk|-DYn;Y z<`u}XJhQpCKF4Zhw#fY|$0{(q^s2uw#@95A&15cl)XNuOkMk}0TYKk_+sXfu$H))5zxYspv1gX9VFGxB@#cQVk_>69ny zk`bhw%}YTCk|~NlOcrREORgYaB6pFvYpD|Wi2RcLnXF-H|E6RIauhk2TtVV_Ph3Go ziFVO&nEZ&mNgB3JID{-ihLfGh{$w&ap3EXwlAFnQL7!B~SsK10{~&|>bjB6PFtQyv zikwS6PrgDPBtIm-B=3-w^2rr+6rgE7ol$2phD;-UC`8xTIkB;-?cjO;raDdJz zg6u^ml4HpY{oBD218U=Ku!en`}E*U{~ zB?pozB?N+|dK|0-jq)W~vmyjFDx5$g+?_{fBolXyO z2>A>-k(@`a)btsfXt+S$B#UBVEA77y*@Ems4j_}sapW9wIk|z{O&%rBD`JqnM#Jx9 zfe@W>S+Wk2yg6t}kL3SVwDdc!^F1dnyiQGjVCO;x? zl7ExIMRft5AnTAV$S$B7WCzfYOpYVxkju#pSAhamF5+82V=nm)`7!w= z`4f4cELc`2UYe{d*)*&nw~+_QqvTog3VEBfp3ns-LWYtJ$Vjp?*`FLPltE}54Rgsw?u zB0nU*Ab%q7lKz!dK0c#_b{JL3Mr2zunoJ-wNgtU_t|7OQ2gvuy&&Vs}ZAElKtBT&@ zB4j98pL~k!P7WfUAt#da$d%+Kau4|qd6xV}D4p;}8t#*Ys_FujC2Nt*$WCNGGKs{e zSk+-`7P*vsk$jzegM1%Uo$yl{z9a9F{?&AXCCI8|BeE?SO(u|;qOGAkoI-{y&BeE^o zn@l9r$jRhgs$#$vQ&m z|KT(YB9qAp_1XW|(Xf+zi#$z!N&ZZl4Rppu$x38xvN_p>97raTqses* z*#D2vaFM)28eux4B4k;z7TJvKMD`<-NPO>F4P4vF|B@%ki#|GjCj%O?O384t6WO0k zCdZRmNOd?%!F1cDL{eKG$dZ8S*RgK3S-#&Y(D1iEKc2BL|Ynuq*98e7mo?M+MRF^7fP9bqg#50V*+F%Wzi0?*t`n$8)*=UxL&!yj-&M`omnG>jsrdnYT~)qR)R=y*5CUr4*Hwih8QkafuxWM{G;IgA`lPA3QS1`YSgpq?xMS(j`{ zb|+)WG;#{LfLud{KCRQMLpCM*3T5mWOhYO;k<22$=&KXBO8!C?>8I@#$hu?;vNPF_ z97c{Nr-SNfyO4%8=qZ^+wZ*#VqwS011f3?o~S z-N_g-g&arbklV>O$q&gd$e+l+$-)C!a|3U>`x|>6Uc0G4Y}1@Q{Nt5I&+AQK8IXRZt$LH zVCVY&O4Q!LLp95j^~k5l9^_y$ot#Q$lP{33lK&+?Cx0Z14^#R1jPlxHv>>~X1IZEO zMDkg36}g4nPrgTfN`6n?BMT(y4K1UHF|-y9&B-q0Kyo7aEV+u@N4`sbLViaE4%Zo# zCTo(-$j(9;LkG|>j+{$+eJyl4NzVDcON7nX&8rvDo{-O*{ zXZ?`%$W~+@GLanR?QU$xRji(&qqQWvkul^5uVoXvq;DhT9`YRdE%_^%KT{`Hf~-b1 zAv=(L$s}?tIfq<9Zq)P{duTXHo+G~{e z93{_@-;%$Q`A4w;WHqu0*@5g!CXr*wx#Vi{6`}Ox{WQEwenNI1tuq`zjwCy|+CGRJ zL5?Tqkju#Rxo^ zZD!Z=O&+h~EhM*)x#Uf<@B|$$lI$+TQ{DZjN0Cd&_2fSCCV8I>n5fe88O5~2s71CR zdywPE=gC9l2V{jwx?qjT4&(qbg&ZTq{8PSpAqg8( zH46%nfJ0rHtWQ2kwj(={u|jP5P+>8=LydH4pC&{;v&bwV@>$?xfR!|?q25frmpo2h zATJ4#;FsjjwEsnIal?v{>LDeBuSs2(^feI&O45q#Cq$JFCDUjhOU|Z!1-Y5rN&o%i zN3?%O-lF{v(r=o|7yVxx$gm38glwe)7@f#?A+}&BIg%VhP8DK9=8`LDUqx;rUm@QR zO8(;hNihpQ+=MzzSsw6`I<(%y$m5Tb2NAZL*ag>ux~N5ebh zz8N~gJ3W=EtMKk`NiqBA3(tJoys&GI>BK zHA;Psyg~l#qvM_s3EOitiwjY(Qe;E23E7qGNe(5G$tmP?am<%QBkB5~?xNukd4l|o{Ef7qWr4`DWOXu}#QW6M21S#D$r0ova_+Oz|51hW#Q-i8q6*iN z+sQY{BSO^Fhty}NFOz@J9xxx_&?w83jf6-)oa{pOm@h{oc=QtkGL9!x$ngv~nOs0F zCSN2skvoJ)XCL`C`4Rokk=KMM;IBRg_?rxVP8X;sSw)C|4TVU!HSO)mX!^&~KZEws zk zJVky-{z}@5bU{MM8f0U#4H*Zj{y&a}+2j&(ExC<6N`6h=B=3_27VC^ll2yqk$w;z0 zIdHLAU+uebG|VQKkShYw(9o!E76dV^{=1-8euQ1ZOYLL_`0y$!!+KH{Lc$XbqcmAw z7>pJv{#aIxwq;m&ivr#-rW#0l`s0mZ${%lFRt+tl_F=S-6x|pL{6#mxE4@V5#i3JJ z0ZaR~i31tECIOJq$HIDe6NcCk@v3Mqz;n^sf2T|_i8d|EU% zB!k+eo+`v^cy@>#U2>1mhX@B4K)wGK9zTi)?6+wT#cq)Z)r7Fu1|@_3v=62|k#_YC zOoU%S`+sOZE*ka^X#W`WNkU(U0bAtYr#in78C3wqznf@8jHbOG?MrEYp7s}Lf1mc# zw4bBh&ZpA}6e9g#c>{@L(1ISV>Cpic`()Z@&_0*;4Wg0gN91|>U!?yp!g_}BhuE>p zLa_2x7%D`(TI7KI*eVG)oQBcl9wAD2Aa{0GyH!Q+OsX9k7$ExvldnSFja0j-*C@>n z2@Iz#!fTmkR}WNe073eAX=!%JKw0%KF;cw+BBxQ#^0rCf&6HccOCk?Z9`SccE>Jc!clDHdTQi{xekZ4}J#sR}}T~ent7?gn2zWCG@omp}v-E zTZN+dTD3(C&95l7$#BfV{}JTyDUm*gXe@GLCjFxscfq>KuSXN}@O(nx`oH(#Y+& zFkMkRO;Caox#1|XV~&=~;bSKs$4{N%bUa3Zk@q66P?%$Y6JAjw=}Wb6#$KaPS)k+f z`S5Xxz*#{!IVE+xFaypw;e2iYoK1x@;Ut_M5qEzgoXyCo87vl}u?9bpxx)D)8r#%$k|In+bDGBGP=tlY;Pli}`#!eA*$f?^ zI9e`*GyXwx{u32w+WZ-E-Z%nh0(GLJ$yqoPe=MPZ@kaMv6rZ_gn(7Ygr899UjnfHX~0_+C-C@Ykq?n$Nx()Hulo6|Dv5m zmY5w4vn)NW$IyjVc zRP%dTFSIIHDk+JjLs-FKk^-z1x+6GTQjnb(Wt#3*&K{@XIg(UK^LJtI9yDKaxANBY zfMQHqbDP1f($BQ(<2aM z(GVs43ACYSA4N$DR_rb~HVH@bSF*Vy&2M;$c2|)Z9apQN!8_uD8k+c2+|baP(TY-%?_g6- zC`x{m6pF&apo#g>k_@(!$SKLjGN2XtF_P?Tz84fL$;tl62e~A<*&hLrTat&(jRpzR zLLJn>1jRjuo1mtC7yuxSU2;Khxa=I%aq!Y2ASqpS)Y!ePLeeCVG1ZilFn|x5~g-0 zGfBhXml2>YlER?(w>-^5pCa?rZm1Vx*w|}5Kv}~hiR{ca9Mru^P>?;j1(dx&P$t_C zVWswv=@zjzgF(F{EoDnF@>6rD9NoV{Ws53-y(O+x*}jRuT#2hfDhn?L=Sg0zvYoJg zsri(Z?yptZvE9Hvq+z;$oyuIXz3n8s`Tvwy9NW^Cr}IFCTASjrVIC0_Gp_D|#J` zLD*bXc9n-aMgr$q=;b2ieDyDpGKpWtJd?UWpzc4U^5-U-k2UY4z1G&e(Y(5+h`j1{ zF+c7@Q3Flas;kSp}>J<2R<8 zI}_W7@=qyBX6xpxc7>v}_FimCwN=*!}Vh*smeobHo--m^YFM+BRLU1NeS`1FqX%VIQv-zjc z#@m?BcS8MrJ}b0{-v9K9 zf9B6UG;@n1nK^hDqjWz?CYVED(L<*Dt~bixVI3$?!Tb&TO`t4i!Z7C!#?0VEB^B; z|9U65uU;kEa9QQ+fCJ z8Sp@>5i2y_0^`e9tbd4c3cIfHmy_<`bsGPDEO?L=f1}2;NPil6tHwXs3NF#hpt%s@ zP>o;R438mJf_)mli7|Pb4{5xX^q|x#@TkU<)9>Kp8oxm;9wyWV64ZDP^R*OT^38Sd z9jTuda(zwX?^Cgj{FcU(OsC%$Dm(_?QTn4I)+ZWoLZhsaKiBwc9q-`l8n1!1@|EjL zg|NQW_@gvdD)d&OF+XVhBnhLDf7bX5><+%EHGdw;>>GVs148~=8h2uz^o`L^r;vA^SsPpvo;E9&jZPoc1B=k+vX|{)ebw2EV z@H8v@sLpltoW&vCe_ZG9lA6!Ze``qzPU`&80C<+Z1m!>lbvM?fzG{7yX!FxHej^OQ zbM(!EpSSU6un6@sw%}!!!rZd)^P~{V^;bnFu881k&VWPu zB~f5)1pm4iyh107jA0(Zo5LjgR_f0d!YW~$NAQv$JZh~7TO;_jao{>VLyY_F5&WSG z;B{8`Zp6pj?pv?FA_~|S!8!Hd27O;AD&SBAXEf$E>F&+1b`{i%SrBKX6Z@OWOIC-|KRej00L z-xd8I@f7|+1pi<%_!XVDYM9j{_>Sy5_<96yLSwcu{D%mhb|>GA;Qb#$_-j`B6_GrQ zy7+ZHBr{wW$*0VK#~b<&qJXWD{1rd=U44b9(Dq0^uNwTGo+~P}JCc7!6?nhV)JF0z z#)Chw_)sK2KqCK0Un9~V1wR1(%rb+=Bl+4c;QyPT*NX^eBKb!&fqWq*RM^=__nZmy z72iMgPdiYHFGlh%=o{ZxRt8T;@=Ij>}`w`cc7GBC%RKfH}u|bg8+a zmCy4finG}`3ogOGaR&O8Rv+ITG@ohJwCfr4rePba@qevBXr(q(1}iRd{GLE5D>W{X zPHYV1m%EtJ!T8X;I%3|z(W9<)C?<`+bBm=TJyy&o-N9A7O^lmOFtKay@5P9G@OHr>16x;xS_FfsR5k0-Z<+sNEuNhKy_AOm7I1c6pNu z?}=IDPxPm=xrLn=vQx!%)zFF&quOQ9ID(oO(g5wRxV*% zE9^n2S?6}7A|$#0K(RZwza{Ie#JquYX&DZ-w#qDQ6U^+2ZBItb142Gt)-VbbD|;Zo zrlx^hvh6{|k%gYma8tRCQ7PvAZQ6$Fpj&BMQkb?|QMUMRB7~ayDYRfqi~Uyd&qFh| zw4}YP<_~9KV?eDWG4>@yz9l$S6mDZ3CV^T%=%tuWRs=C_NtIRcviN&IZDgKF>>U`v zEosyZh?>Gi<^kI_)_NNBW{WvHEpglu*bVoV?(Dv<@X40@NrkpdfMH9HxZ71HQWlWiwf3Gest}Dm%3?8&TP5k~DT4rf|#jkVKt* zi=NzK9YbMc^-F|W^`krw$UF}==9$n35f3%yxn@7;aATfhFg&*$Y0PpoChjfwNHW+X z7|>geN(y7a9iV&n!*Ef@D&gZ%UOt49WCqy_FmYyUI!=Qq6vs_;shLI<3SWnxmoZX} zIU8C3Wr{LqlT=g0I?xxmc_ziO`4r_BOtIcM53s&N;eC?QA+O|#Q06(OXmDcP5A9Co zAt>pb2c=IU>3jPY@HitA*w`ra!<@5HhwbeBIiPb}lPEJMd*FW1c{!roN-TMQ*iBJN z)j1n@Vy>dpq^bXD5asf;Y+zfp6#a;OD%ZyX+X)=1`7`)gsBTSrE4Wl_J!;ZbSZd4xFc&kQ~-#8vhz=ubMt;_anqu?e9VB zYx=5k;egftUF*R`Dv1O0wwA}AEQLq0+D|07r18C3;2~Cor!^k70z6cm0txH>%Nj4j zK&UBI2WZ4sG+wsB9FX2DG!%n;W4)U_1)0_JBvlBMZNb>Ak3$n75`!IqquwJ42b1;nLT<@ndM07MOT>@$$!!p@Ps%XobA}pIF zK_2z3qM-4bKZo6mwR3$i$}h%8K1;{Is&6d=3s{rGpwxhfTEqsg0;LTQRKhMpN9)_l zB1+lxcA$1LT^U;q^HbkmhE*_UIw-wLq^o3WpjX_?i)Vtm9Q2Fxf+=h;CCq+7 z1kPX^Fx2XMd?Kit{Q1Us;scoS^1NdGnKzYu$l8B*5YeaY7i6%3WuWQuWX#68Vw!4}H{-epv`1H?C3!Pt z&Q3PojOrW=P4FQ>&BK^qsgg0Md)^!wBf$PW0W?=q5H^aT~b4L!y5OA zk4J#x4BAl|a~GQL2*;=`jU57C&B&&(RMfoG4MV6n&OxfBe3l3+!*4hpVZ7QKOO8Hw zvBfY`eU|p4K*-`PXj7kMa!eVl;X%;y2_nqKzRUrILbQp8qGRa{M_mQwvMPG+IHk|( zc`_5l|0^6d=oO=Z1=?&@lm;6~H{fUjX9VfA;+WYU?nufarX?(#t)T<^1WMA-kxs>^ zCKoaHG<1?9$53MCBa*YBD;p4k`ZQ$jwqo6Y$!@TofEa9SGAN6p(xUeOY+gfmstZvf zifyn)uwAj$A`&g`5+|cJO3Wibdqa+_L+}5oL#|Z^nO|PW%20_3hb?wD^pj}{{wGag zW196Cs}237Zefat{xuAs4KGa>)Nc(%lAKCR07$q|{loq=YYhFX!fRI2tqJZ-#5@e`oSfJ7gXAhEd%dvCjDGmA5 z`am}mtdiZx3=ss?tm!E+S`#c&Qt-)mR@hgDMEDUguIVvkS zn#yzLG-H40ijosAmstv?VQr$5Wr(nmUAA*E96WbVWyK@Bd2-+gk3gO?|6op4N zilnm0{5UH<)B~f8H=z|EJv^Ab4rISukcUmja=nqfj2HZul9X^tGObim)^UT?V1X1j zw6Rnz3{-jzN<^i;I2bfcS`i!bP}uPNQ50rp!!Dpl;woB+3ObnwqKF$U>*8TEP_wu( z9Y#=8FAFyhcW)k=x(0qzq#QEYP*{?P=ROC{2r88)jq%!s^wuo`nKZ%$X?9xDxHIG!Xm=INW?r$P+BJ3GS-uo|T znyMLfkVp7q`03CLeb%Kb>$y=;x<*McC}IoQHCk>Vv3cFwQ&Ga~FCe;CbJHD>pW%ET z+1q2Av%BgQCDz;6+uP8R*aXq82tT^pfgW69K9}99Z`KBk^Vq(k(_{O|j#b#%NW?FY zWU!xMwqpw=*@Pa&_Ln)sQ0|6*4>P?7cfN*RiY<9d%uqr0={a*)j}D=4mtvg7#@@|p z&_S`Aq-YiP101oNB^m5~%w~;bV-LZ0G?JZ7X$9Jq!AR^*_LCiScn$2USo+YZPwX*L z3}7;&#>YOeQ-szgvtIXM*%f=5#DZWyV_gw^){52QPAVqha~Ryv-$bJhb8XwvpH*lk4QY^XRX@-FB0NF_^6*1Oa?zn z0>qNv&xREPFOjO_aMaJe9`Zw>H&!#`HFo-A$;@SjKm zn#H>V{Hd{K?_PzWI!AkQ5RMB+xL!jYbfyYM;B>oO6Ro(D^ z4v!QR728Q2fQW|wIy|zl=!xyDju0N-!Xp;z)Yu$Rq~ZSo9{)Z7kKUHY&+z!J55`|? zuH|zRK5vD?Bi}0K7Cip!1&=-|4GdIdhsq1jz@x89OFzTE5gu3fnZ-HrO@3$~WlvD~ zoGs?uoPz9)t*}u>1;t@gyMK~kXm-AaIicNkX^IRsrX2K@BwMSmS5h21-);UoClIR2 z661C-+7rGVKR0G$+{U*Tqba_FOrtP5K#K1u&6hktiti-H4~F8)NVXHk#2!}28p1H5 z`_s8URRcCf2^&D+WCL%6Kt+=1h36(!tPFy&;UxjzNz{5-mOD? z5zM^1oYlfWxJN%`HPAT%G=}<#avq8Xy2nbgiNWq3FJs!-=)nk^ATxC`B^ESM?L_I^ zY&vEt_aqt9!`5L4xT|DLFZ&t>$30ms7EzPft8;-6uQ z+C5!XCY|LjL)Z*Dv!*4f&3qy^NvmvQew^FPxeU78v%NI?HiieFw!HR{14luSJ-e{I zS!VCN7M`3FiZaZ*8^wh`iyt~eH_DP(&|IG938lgC+RNGsdsf!rK7^Cp{yeWJW!+?L zAe!T#K9m-#EG0acf$h^+bn);K_5tKSd~lx@F84q=oTpsLb^3+%yMBsQM%csPU2=5a_JUz2C-?kyW6t}32zD2axTQY(QQ0L zr6_$n(>X3Rp9<~Ug_2V-RA}F>*@#X39fTV9&3s>w2h$TAVi4NNrI>%^$Aq?T#I~$& zE4CYo(s%ehmLijt?mMDU|M%?#l{w=nQyZg41bs)!^I|(|n+qBxi+8dO=)S(?U&;bm zS`?^4l9!#MTt-vLv{&;E2aUOE6ZM7}G#0N=Tcjd&N_E>vq8mXlfM3l7}O%EvORRMYv0!Dd~;mixDY+?j2TbK zTF#q0U5S}MhDQkx%fwMQ`fpLpF!n+nq6}~B+BYe|2&rT?b^~KHrcA25o&8z{8hH&F z(0rG78dUD@M&xFbV4!0vz82(Rqo#pI$7I1U(CTK^DBze@=uVQz!FHgr-2?^LQA|KF z6Ymwx46?5$fU2HVDP|hmjw;4X9vDxQ!5)Q{#EAR7n!i9CyT?qE0x4lN0}wVtZb(bn z;{KqSFjjOGqKxG`fwSbfQU%L;2sB$-vPyRBZcz1OqD>Q7%xF-Jq$%ti=C_zRl4h_! zP>q;*Qcl&1iyH2MqHc^msJg4h&R1MdX=CP4O%*xo1MHXs^r);xkkO5qn8zfg zvsc`pC#2*uS@L|)Q@ygNyzJ<` zz|`RzrFKTY(KV&!hxUOh#4SBTOT--kjjK>r-)M21s)zizOtY8Ds8s1up6nlx?A_})A>9Ye%};TUR^q*^AS@7Z%d>6aIxj1Snza} z_TG3Dp!27xi)W}boUyOCsACoQI_ebvs2%=EqTFyA5AzS>NUZGy7M+KcYc|~mqp5v5 zMrykrjpJ|cI8aYXHuh;>P_7(Hc1A~R?egieIZZ(YYeC|kD@{RdDQ3SnLl8d(2U~+- z*KWi9JGRZb6Vebv^uQuwo^R5j{4 zF$fLb#mpTP2z?1n^7`hh{Js_lU0{tmg(uDdF0`)98ocLl;36SRtWWs-&cMYg-4266 z<#X@71D$+HKj0E8vYRi5sBWW2iF+K@%Dz!iYE@rt$f{-C?OKMxtoqhiXz(o3xOHL| zLj_+S47^+HVIX&2S_#~&(w!kPO7rFcw^?ln^6?jdyR67*oEHLjTcPRvBkX53Ed_;bEpi#2Q9mj%@3|HHJu0#l_Z45J z0oBOZ_)R9$+{n1ExM=Df45J{f?mcD=NEiiib+3_O6n>%s+sH5q-;t4MvtVW}Jk?eqB~lnY+AKW%%W%A~g>4|M*$W?(VKx@Z zhmk2f!$we`on66rEj&BA10^hFV_`Q6&utJ1C$iBngN-yrJYOt4FE8WIVAS=67bsI4 zb*PNGy6_>1XXLiK&^krApo(2{;UhBiqRO5Np}4|}%ZK41mj9BP?8VGd_$WR2R#m3^ zpI4KI&Hb-WxbXSQ{I5@#@Y%oMzdnZWSp*>$J|^?gWvZnA`e@|Cb}ocZ=y8gq`(IF5 z2%1%R>6&QAWtFAFQTQaumL3(eS;fGo)?rNQ{@2v#@$;*c!l&~_QoY|&S=I!EK4Zy1 zV|%F&o~2b7CK^1+p|YQocu8ZKqO~$^Yvu&8g3g40Vw9XQ1f$vIuUT5i%!1vAxabDJ0OX}kHW$0zb z4qy^3{6N;@3S-}l27V|-@ET*UbOC-udW)`LY~KiAw~r-%&e*Iv@F!c&Qt;1=?ZKj{ z@Kc%fO~wM{z|Z9B`xayC#+Y9Z>phWfs`p;hxawx;^xlhWo}z(aFxP6(61kbSF)!4l z_g!0_rZ6|2fzDKVFO`cs52HO}?`3;MSWr9=?Y&%1d1>tbCYoD@2SX*fh_Y&_$U2*O zmVj21_-X$9sR~ppDOVg{_1;1=@RVz3(|7aw%eSU>JIzIwzwqYn+Y*eA!}WL#uaj-M@#mr84+)4upn^HM&zx zb73AT=xanLpV|XBNTVwgG#6f=&=L!i_};F-!5ZB?rQKSeO~9cRrYWv{s0Q77-srok z@$J13cuhmI5Lb~eA-rR45>pKRtgyBkC828cn}pc!iP++LeZD!otXqh#^&7sww6vCX zWRo@!DyF9GeF#a?N_Rl96!{*N@$V>zS{)=r{V(L`qHFmt55)!-SM+E(9u(cd$$NBwGF3{`Ad5&xe{WAPhLL_7b$J(Mj$v3ABlX2-eS@Iup5o?HilK*T|D%!)tVQi9B zwWWw!!2jj~YU-arm`Ih6TnpCKhY?$>S2iyM8!FX8ykD^r%hcpBi$hqj%$o@hn`#WF z2w1SxP5?((?*?JPk_!L(N=t{SH2zq zjnCI}5IbbxqE;827!d>@xqXNDS45 z!CP+55zWs(qGW|)MGjlx=XucFcEe?!>}R>z2TZ}szG7<$QagHF$z_~ujK zp{krRcl$Z_frqOTrKb4#^Q0N0tZEF*{_8dd?{Tf2=a&n*p#kve0dqY9+Z-KpqOF? z*cEK8xWkDEpTATh@xQ|qy9NoxBTGLs5?G>QX-PHYyD+X@gH?I4!NzAmimoB5 zyvtvkO;BX6rEw~Ls(luI@o7;34vKLXm za1srP#qc*}r-qo_E0aUi_Og_2Y)%4NwwMp0nkiBSOQZ}8@vI`{E-5=38;-G%vQ(ZA zIT>AVOj#yxH@ex6kVVS!<{}rG=r^OlaLVSN=rDUq7AxC;2%~xm;VNvwKI)_Le1Qf_ zFt1mpx10v)*i&lQ`qc=Vv(t(y`gZPFD`v$&v*);_o+9j=rlc&E9e9EYqsl+B!+c|0 zTh&!R-tVLfVTnDZ!0qhf1hdol;IMnqg2Y_9sz@i;q>71o)~PEqQ9@$AlyZ<=PY3mp zgx8!=`NY1GGTG0tYKi^ie3ZlT%`@XuLgO*+Z9BNga|gW)Dk{`wzM|}CDr0KV)i^@l z;gMnC_?!e>Bjwi(UbeyM7H|5$3X?msskq1g1Z={vRyckbd4RnVg!jS0@S%qG!isg| zq3(hVcC>@iRT+6$2HIHOg9x-P^V-=Nbn{5-GOvTZ-5zw5F4t=QD8&(DuA7k3lU_1t zWwTzCR2+#hz=(Gcr``7$5lYMOaGH-cLWOO~epYb-mLMS8q+sBi*C!;G4C;)ro}4bm zdUA)xu}%Xdx#J}yrpeg}O-Ro8RFIR6*$L`=Q;?f|Xo9*#VPd0Go{!p_BPZ^S7zu64 zPwviIoBx@Z6#6R;Pxh1F6T7zL_iuuCOw?(|0?11V ze;UD0xGA6OY#7|hUv(EnQq4hM|12~%iBV4_e`EEj68;sU_70~8--w<(r&>w=!Q3~= zmgFcytRE>5YY)YC6Amh0-h1-CHOYK_QoytN0Hy208mjSRY+|FJ9_>?Kl^OaM<|li4 z6npC+7N*fZ!@5#;R*VEWB^km*rN>CZLqKwL?|~I^dbCW&|0h}8|0HW_C1XE866qdU zxScKC4Qe(^F(0Xl@odXS{nEXRGEGlt%xqDr`ALih7;`}4rE1)8p5TEsvTO3OslxxS z9_X;1H`urnD&>l@(8<5|1EVeU@JX>ir?sF@;s>EVuEvW>0sdJi101W#5gz2N?*h84 zC4Cw{1I=~0HEChf`D+k>i)+%tX7G)bz&K4Bf=vD|w8Yiadj68lmtZb+d92+)K3@)f zay7HCh*up3#%pErNV1eqn+I-g6<;u=wXWooAx~F=)>)XGiG2BJV4{YR54q0Z zSMz{AYg**M^v+Yugq@yrR^UX>4l z&btB{-5CSd+BsPTCxz&RGLeyfucnJ;#@leJR@B&@xAr5~#0T+t*9O>|PGCJC|NW7>@j}+T)0xq^N zhHqa1Tw=ZL?dIK%0q@e=&!;wcdE2ePrTX#(gh~8;CvcfwD=@&{q;a@h4{Z<}B|DqXIOGI`=6;A&kSG-PwSu;{AQr4ASImmyhK zop`U1UNhgE1YBcbWr**_EYf6%zxqDR6YiM>-0V?N~CYDL(J4>~|MUG@3| zq2m}#r3`FZ;rmp6nfh+K{!5iLc!E^kPEmC_SmQgXFL&wkWbJ~+4a};pJvvP=LPM8K z1n;%pDg8v_hc_xM6xU%PDZHku@kbzi*S*$DtUqf|ptDdQZJ>KgJZQQk8_S;>0?v@=Wc83&`AkV3HjA>J zB`Jxm#UiwPwxl3?Wdo>MQaXELC#XhJCi79)9I_iYW>Ui6MO}Wu4#`u#oOOfFmWO0S zd=jTG`m20}L>n6i6)j&W(>YmP189{bw-O#-i6^;1MX9dn$iBw7sOVHF3Q(AaW>;iL zQd!hJpw6`HqC4*4y+K`MCio0kH&EBc;&?JB)2fVgR`iin#(wGr>MM(=WPeA0R`ipZPGkom`ig>Dk!KY< zK~yMT%A2Bu4~7VTXo^)w#d`KK)nx;+q?;ECd$t|$ZdrnjooNQzXmy0*NIneQL>&;W zk5iNn20*VWwy>+PT@_m!dtn}oRK>PNxt|&is+VB~`v>&3!ldHqc;~OvpzV^pEYxW= zaEB}`oju+Jv{N=NgOy`oR_tn&Z8;UOyHU3LU`Z?XG|F}x713bH77q#cLx7`scrNOD zr4R#bjGNWs-!Z&#fJKIb;;y0nsFcCzowqSfWgr%4Pa)mwQ2#*rE;)X7%L-cKXHTO> zf^mLFdOAL_>8y+QXko;!`p0iA%D5N4M{ z?*Z9Drx<$WCqd>fHF2R$i?Jgqzn7;{Zd@Ep&|LO@1~5*&fnJ~;?m83LRFx-SHvY|F zphuNu)9WWxukb+=u)Bc8Sz7)!n{*5@u38I4mPOUM*0}NX)`Q-W6ml}hIpDhzJ?tQv ztoP)6lf-&$1-&m%%hOqtOwb4N21*7y>jHf!Z&c^7U3Sn%vW@wyC%UElW4RYBV7(TA zK9SNWVVkI>pURhCN<-}aPQcGdTW}9a34aoe=nob4mVd)O!@uRPSZmPliCB$N|E?st{LxL2lYROC=#~s~vv}B= z^8b{IFb{hPx?cXLEZxh_sGz@Yv=S9f;tzKODyj?(@Smv*RSSdsi8;>RoZc{Dsa5ohcVWEwmN&`l!LquddpL7V=#6l-OhdHj?t}YXy zZho;d&|#s6Z^0^}JW4$vLQ}ka|4eYS`lMid>JQ_++^K#gFu?bBG+&(m`|!8WSsTj} zal}Yk;=6rvV~`>zsZzfTUOg9>Y@wT9EdZuiS7-v_)r)e!IuizyF4(LYZ8lptB=kL} zi+y*id?pS(TpQH`SZ~vi88Q~QNqtnH!RK@VZdP9wXya{90Jo`M!)nlCa2J%qwOv)v z$FvxngFbWZQdD1`_=veJ^bWR-~kH`W+#6HipPUQoFh;&+& zFG(o;=t$s$>KS3{4Bm?>dq!L=p}NN(1fI1d?B+LsOW z*LA_Vl@#QE%LYDVr46O=&0g@s;=Gk=w;hsqJz`-7ABI`Lby3Y0bw44*%@$wr za6P8dlLst5cufH!KW>$j&)>KJykym*fTzQPxt>sI?}Ya;V8LFWqL>#Kf981}ncG~6 zD!Z18uhYfJvrOD&TcM@A1`TvwwX!bbtMh=@)VoCF z3jS?d;5$}9mHa0dVprRDE$L3--AcfpShAl1`SpX`ydAI}!y}ie$iv&+%vtIVZRkMh zH2N-xXVXTw+i6r;&m(bgx7T7YmT?S#-yX|wehD9O5Lpy14U89UTfp)(BZeY1_uRtd+M|E8l#tQ=7d;x5NYqS;F z!~cf$hHH%RwFnJ)`7F}5N+WtH6`aJUl4%%cv=YP1)a z&pXm?ZkjPjU;*Dc0yy26Ca{SAyV~?F_kT1ZoQ227vwM?TLE(0=<{0-14DjmJz}^-H#l=onuCYoaPU9tK5SnLHipc3amkevZ zv0sE{;N^B;A1gGIw@U@~HJ%Wm+5GA*V5pz*j^G?l_cUAu20g35gL3f@+Er-KlXV(< zt@nBTVRCHAZGzbVXabEa#$= zBhNTRsl+J~{~S8viq^@G27@CD=(P6R2JgNe7z0Ev(|mP|#!9Td0tS$JY#%AO%lf{Y zhwCIbx7aL`N&BfQkn8fHMUcOOB3*ITNkA^I|!>yUM{Xcr&1avip=R6F^HB!?r`BYrmqH3XnTCPCM6 zjsHLv<9_RKP~r3d!gazzLrzZ*SZL$9WPDCqXy>)(fu}UEp=tMg-$-Y7m!(5;Tw%unz(HG zNs%+w%~XV#y6ovSX3^@5(8HBzz$k}!8b2yZUf+<@$EfHVB9(mpHOhKp%>PWJuXH%tC`Fxq!nh-L~-s?aln!KOm zxNDg8RFsdxICf=*wM8LhaGx9j%nEC{g3!iy)dIVRofgL1E{%0|m^9W-@wF^hk1%;0guCO4Z^&IpkYA@Ux4{Zc1q-~-^zR>63Tum`xsurDVeR`ilLQm(@yq0pM~Cw$_+>Z+I@t~u3;Uj1?f3|iJI z&0LE}O??J`hNPHe$jA5!?n9er*LoA?QHxs|QsL}M{DBg1E8`!?HU8B3uh+I$n@rh` zA>+c1>GNaf1MBA-+I@a=@21MoF!V#FYqk+hml<=NNvde6c$}IWBa1QExckrLM69p_PdlUU0guO^}KX`$>yc1 z_Efrgb4y-`ZsfGP{i+?^7-%;{F6(XV>JHFQ>*l)B;&BWnXS+dx=pOJcoeB!jW3_g} zr$Io9m#(B^c}uavgDcU(=IGFN6BsQr+P#zoA9N>+7!P_`lELy)bAVSyi9j10G#d1e z`GV~1k^y?3#D|J^`o-6lb_QIlM4)2x z!$C2{C#d{N_^aT1p~miMLt9V9Hw32*qpw1%hJkt|Z(eBH>l3sENs^q3<9+m# zlkQC5xNx5O6d6Yy`4Do65p2FAf@K3AVO<{K!K*V&D2tAkPK00F=E7xzPdQMc5x_k1Ikrc6Q_*P*0i8$zGlY>LtV6?DN%TFSDtdWsWfWdlsOh zW~BUvOafn`^cnsLjKIK)hs{ULo{`_eb~$JG*vVn0x}9fHlN{nXK2?^Q>u}4nJA;*@ zeGV?k7CmqFT)Y=4#bjr5R+uH*c^i?ud28fI(($?*9ArU{Nqkczx zza&k@4>T4&X9WsxVfB&HfzsL6*ij6=`BfBV%|aOI7hxr-KVjlB6Z)!ioS&E zJNn5a279>%R3IsgRc-?nlI-aVV=WwOFlHRx0u!LojvmyAfZYiT<;bOK28zsQcEqb| z%@20?vs`8HZpGnET|ajzsEf=sUEEo9bd}VB?H-S?fmBm^3GtT8?6$L2Xi*<**2As| zT~XN9wV-fG2Fun!j1(1FqwT0&wQV!17UMuXXLTeKshj*yYWx4Bc37#ItveD&$uN9C z@C4MnI{L~QSmc-<$jqpYVR0Ma7b_Fs3}G-USLTX43lnxo8Kr=hulrFrmNZzE@uR5&+8 zk@M-J<^#L)LfV9g%6;}~Ne1(c1#O|ql5(_|j^xhS`vWPkOS2D< zAe0vR2J$-`I6M`8N8Ur12Y&Oxd5>_WF*uJ3=UHgx?0bcCF9Z>qeN4DN#E6@HADux5 za!0~>oXlMy2-7qBe&M|TJ~&V0P$O4#h4TR_H{i&I^Q3S-b1$5y$o2(#je_%Z5~_(i zTBz9J2rM9HH?St~nSGG1IFc!v*#T7fAhiakc32ls8ywHBR+N=4Dl$A3?YkAkeZ1lk z;xt`Y=~#jkkIX_iRDkV_1C1&YWMfYkfyyP>S%F#9&^+;l6!?vmejfH+M^L3C zFMDp7S=SKEYCa8~lO~8v(%4TBL~+$(LFtSg1x?;AD1-eA`cyncQYNcgYJSh)Frbr)x3jo%MOl^q`es>sI;mb|y(wpiuP?6ZD-+^gG*og` zKiMC4_T5ZSfou!j-(LbMlx=ZGPn}bvtm;o4iqqHViBsn&s|HLGC3w;24?;HKeTm~R ztCtq{VxypygF4A3D2%@9FepQsCV6{#P-j`HO?;DWP#5`03k>ia%1Y%4wa78sfdeRWa5pdNxkqom~~HT3=z{v=m?EvLe%fyoPRZd>k^hgKa}f z25OY{NdZ=GY5kIrds?evoIIp`gg7v&12Mv?I*&%NF8fw|Y7BNE=xncw-EY;5T3H=2 zNmey}OjI16R?X^#>6oU|Wf=HXv*odhop~05s^x)=GkWfH^Yp5~z- zUk2u|p9g{t7K^C)Y?}!>vPe(?E;fUX?iN(Uo-8wO9rA{javW}}j!~=v9U67%xsRz3 zC3y>49Q8NxmXsEb3(U!1%z?+>r3cpRf#fUI@VG2I3?vD#BlF?$qMQ?3u*5E)m*jA5 z$@U%ty)3&S$Trk~u3V&|Lb(6@J!YJ!f6$kIuzO|wU^Aj#xgSG|UiqO1#Zj+b`i!W6 zt?mzcjb0n3FI85Q*^$;dA}KA4|k5gi|T_`YyB_uSlzG zdJga_S<6c*%R3JIdYcHvdwOxjz;ERH)UT=R%yJ+-CP7-fr)S;;{7&LKDtj1R9`!wS zjqVS9fWP-c^|~SXBbAkm0scTsdwNfSy@N$S)Q{_+y0|-}vO{};|9VU${y}B*P$TLm zi9f5X2Z{aXE23IARW@ZP@E0$QuI{m}BM^M^ zIgCKuA=Fr967V;f_^8G_Fy~Rf59mOl$2Iot8Q>p(oF+V}v6@ogEm>*2d)SU5|3|j? zg2r~Y0{$tpx~Q>t>wtf4d>d(p`Ekc@;&`y4{-3BeuJ}Dd{idoS0$uTY9V?zF&Em@% zZ}xz5Rl4+N$dFC%+8 z{O*Xg%O1ZG4jtC=@rd))`@sRjPVD!(Cr(oKv@qmkmc)OILtsm*pa8!~*vi7768|!m zaeK`2`*OlWuI8cpa>jjs4vV_l7;)*hHg*h#0gOfTq*)V{T9+ibAgFcA);NWsujQoG z^ri(Jan#1G6xH!C`U@$IMfqH>^|F_yV*;s`XMqZvhY?X%Bguy2 zo4HEeocgaQV;sYv3+m=dai3<^o=fDf|H zQtDPn>L^}Ku3I(gYl@k{=$pxPtL6KCnXE?}(E664>lB#7Ucs2F+tfi&zIcdOx0$|N zO_s0#^{CqxV5EWjbmoAgu3q9%oz0_GZI|kQQWp!aI1`c3(14} z0S{11=uh4FKMxNjKX)8n2c;K25%GC=^75weIV^n=gwKon;B!R!c!f_d47$2|q)&6< z^Kd8l9F;!t!snh{@VQs|G!s5msAiq`7>c2Kgiq)!R%dnh$w*Cw*I!fNb6onwkq?_e zoqFPrFQ^gM!x??mz3u^d=khpX{o4Ug4jM$ECmBnkJ{NC?Lja5|gYBq0T`dK`u)J9d zg$&PyWorYCbjQx+Z1g%@Rg9AhW`&iTpPk4F#lkQq&Be!xknP;$gNRO>mzI7|iquMj zok5G|`sEuzSj%I!m>ZzaUdVk76`>jQ&F@(H3`c$e4t&%azgR=p1muuW#CtL|Ex*N3 zp>^L`%w09D@Zt&GiJQUxgQnC3={*$jI(ILOkeb$%BlJLH&tw8qCBh7L?E*}@hN9@I zGAld+Y}*v7LpPP#&Go=`r2?;L>;&|nCcVP}3Vlsu6&Q{+9m@s2rQv(pSoG9%suBE- z#?qDnGbDbXiRDX8XL=z4lZM7Rq$9M;0fC=uY;hv6tBiad?@CaORzbqykkrDd0ra1{rY)yezG{4`m7LRiAT`OV6Ah(DgCf0O z?JSVivGfh}aB6YSVoKjmmcHPBN?-WXwbYxCpdW>Tb1Et!B_c{S>u?vsKKWW? zHcz(yGipD5+gu3ea}o}H+x+vE=gu}!L+f+IL49wiWcxYz`Jx5v?yOd6O=c)q9Xzmx zc2$4CkZNg9j)&Y7$0gW-S)J$@qWwO^Ka4ronAIb#q$|bmGmPT5CxunQ-$d|(y>W;% zt3O`7L#hGRyGv|BC1~I*q`<{a{Kes|z+yr=MG9YWkD^?K1-v|KEL)z9pvq6-L$;0P z!&&1_93?VX*A<}gRB75T^~JcDHHqdJ>ayCFpsE#zh@7(YDP#qOTCDaVa4JRB&4}}^ z&^6*2)H`Bn`&%7wro>AsJB(R()~quqlq{SQPL)x1!Sv3mWJ(^wc0DXAq%g-4kaYlJ zuva0AS$nRD3gN5hGeOpghn*!)0_~If;MDLpUH6~&g!E1LuK28R?B#j{o|g#~8TEpU zYOq8UHR~ZscG<2+q;+?TZ`jVdD91j|lBmGPsF8GtFq$NH=_gT9{QZ;-peMrarLc5X zq=TMHEf$!;CQ%1JTPi4%ou|MTRtw5z?;^Wdmro1IVbLo=FUoB4Va>jTWHf`c!m)7L zJ*zILO-HoGxhESLJ%8>bg^iNiADq&fdmc&+#pmFKQ8reFRW^oQ&sP*SE(5zC>f#r} zLE|OigSh=c6D8Tju@9?~VseVp4mSCTFiMBNZ9$RFm;OIn=N%ta(f$8>@7~?Jz$PqY zPe?Wa0tpZxNPqyLNCzRI_o}4OtB`C$0&XxwET~{W5Cj6!6i}Lq3W|#D0hOj$P*4%^ z5d~2c`|opRPLSvO`u&sad(PasQ_jqsnL7oswVmPW>#!%n)DyD?b;v@aTfMO#Yr`prVocSEb zB8_UHd-bG<=XAOo(ed;V&mHOW+kt&$QCSx{@ffh5U=O+j9jRxadA|y(H$~qH9At*C zDDF%5JqsRY{;6;v4PFKuVMaX9FCI$cmjLyiWnME=gi7ccYsM<+Shd>1GeH)&ji>tP zGCUJ`Z7812rM)A8lLRMHfgd%#fg`6Mrr7 z%#?>`)A>cfS%Pzjr^`KeN`B-~LI+^TY>pyFYen-p#RV#49@-M?vnO1ro^~a!Hfi8i zI24&>$O-NW=o}YovC2TT=WE|o@O)wH`8o-k&9guld%j{Lz<0~W?j0t1SPe>rci|}8 zp5R5o*wP=1t~Tr`6NmjK9f7)g?h!sKClY7I%3YB9#V5Kjs zfL94)@7NTy+n#lDW>JZY7RQ3un_bikaX+9H39b;v{eWHDfHz14aX;Yn;oyyx?{m>g zUdZOzZ0b=i&RKh?7I>Sy0Ozbd$VKp^1X$ssS37~9sf>V4aihU|B}I#DGC2qLNe z(?hIH&zWOX1ee$}1x>GKzeHfEO@D{cHhEr@0G8Vnfo{d~lBtLAt8C&s5j?M|X+&hP zo04L{hb2Xe-1Hom@tdmVBa7V>kJiTXp4kS~2s!Gesr>wLbB2n*DmN`fnR`wOKklY5 zf4}zN(pmLDg_~w^icbq~a?`8J!JnIts{ppSsm@d2vu1+wzr#%@VXt_;kN|hN={r`^ z^XBu)|2{YUyb1h`d0O#)H+|>@|JS^(_<%c1v!8^+_h#k`9OFZ7%JzY;n3EJAcGKZI zz*o(?6~FDKQH9`Z^1`ETssi)fbKTsm!=B zt>kBhxTzgR6duEB_Yz0ooSPCBgDtD4;`46$bOqRL=`6hHrtzEuRjffue#uSTGka=S zB^CVq6*rZX|L{^UJo0ILC30q{>1}5gD;W3p->*l5KUUaOy}v zcq%`xUmRQ#Bp?ee#Oo8BhNfP;5K{W=B%7!A>Na)_h96E7^IJ4LFbV0CyMW>5=4TM| z+#{v!ghLCJI<*hCZZbH{XIZ*Q_mrnVYBRRX?Mp2tqZXJNcM z-BjkGx|zi1syf}Jx}uHeH70eO9;QAg3T--1{5w5`D@^J%uYAkPjca{3m(7X_r&(W! zH~g(KA6Zd;;pHabBl&Rq9+~^`P+T?*>Fx)f#Lkl zZ^LCb@Kyv-!1>vk*&2r|#BefM3%59+SWT9?VP|qs7r5;lDu66blegaNNW*VTuC2V< zKG>o44waR!e`RI3xEZ|3e!EDuOk{E!9U#vBfWA#`tEndJr@Od`_!6=Cr5dO5nu^Vo zTH1q-%@m27rS_*!k+|6^;3+}v6Lr*Hi%{Zc_cW^VTAYgv?aN;|MB!~{my?~}>aq4t zo2s<6a^VXcrfCP2_KUZ{Va|77b55Afv#2-I@^tvN^U!oqK6~by?sl~Ug)}*8G03z+ zy_&dBUou-D)*Hb_p7JkOBO?Jv!fI8|3j&zP^j|XeE_eW1NO?QT%L(J*P-3^)}CmNkY zPA^S)&PScg+rJ)c$j8{{^y9^?T*n>0IzDH>sLyqkhSGH013l?dUi5m~@CkGtV?8sR z*n6RpGj(KeXafq$GfR{0__%|atqI?_mw@in7iRArD?|SUvyq*DEq=mhmziNTXH1&0kMS||p zG|*|_0^O%+sPjI$3eWwTuw9M~)oM`KRL>rzo1VSw!VOILc6i+PfFj$;MV0V8%Ss)^ zpRsyJ0iV;Fm+WjW@A^jaxEAo*+w+pM5cSt{Kx=~Ge9KvJuu{eQvL*4d);!Dvai+bd zL&4~nt%}#RUih6xjX;O>SFC{3q5RD^y2rL(gFHxi1IE6YvTi7%nQ{^(>q_yI*MGBP zdLo*V1Pn)rZ@RD2-z9AmWx9cbT$e6zx-4ol4>-it<{L&YZFs2s(KnmaH3lJ2bbQZa zt^F@h)cE&M_Hc0E5MR`_{Op?ztevUlp0~cJ!fIdQS%-7?ue=p!MwI*BjtigKZWy^z za5(4;nU!0j^Elvangv>@3F{G%bGdix7AfBOA`(=pskZt=o4ZI;9jDVa$jUU;b*}qC z_vm~~Py_ee#X5JAs!uN8@^)+ro0+-yYae}8Ez5mC=jK4C?GVV8=&yN0`7rzM-VRzv zi_4vNvdvEAQ{NfeYAjmOv7Ys620gcj9y=OJC31USeS!1JcG$|w?e)sXD(A5N?YDR0 z!b?lxmZ9f;Fxuxh_pNM^RE+xR7{xnW#dG^}73akT*#sI`sX>#Mfd*+xan?Ny8muYR zX@}XC+##CMoT(_6+@YG%osr?Kz~LG@Iz48CMri8dM6U*o)YQY7vN$>JA|(=-w-(Pzkv_;c%(c65FTx)r}^T6wJ_>EZ1)p`C8e zM2mhz|KyouNhZ?uzQDkKmk&2OzDZrAsX*9Yt1&%PnU|0nETM;S(C1WgL%0jrja{4u#&n;c4X= zpCA9818k)60N&IKn9P+30}RV~D7XCcqxXgRO7em0`Z>)I=DPlsm)`v}3^YJ?uT;lP zf9pigQk)Oa^R44+7@>oy&YzP(gEisGyEdR9dM9_f^XUDcp_)26#Z1FAb#WTj01Yp& zVmX)|4xi1mZbSi^CI0C24T^VN`9JU035U>$#jNe&tjjixwLSIpnBn~O2&mVKDhfEj zBm|O+m-K=CYkO~dnM3lc++Ev8s+JMo3^fNW(nd%MDx0Kn5K?S=Ru(1 znz}giFfv#x>BYLzr$HktQ~$=TpwTL=!!cFdYXfkMPWn*iGi1%$v6{wW>Efd})hRCC zg_*hIqw%v&BmPZYA>ho7$R*LYPG%@ijKW#08vqQU^K^#YyNg!S!c=(>K=UdiHNJA%F% ztti3yrwQo$4eAw1>LB5+S9FH(wUQSR+xTzCsF<&SpNQ7w(~rFtK7q!-yMDK_tJm+T zw7CZ@HjMRqHCfK5sCDc2>E6P2{HQMLpVj1cmO=s7Kc{_qjOY_bu)_si=@KhDY*RV( zF}uY629D_VY4}QDsa^9ZqfNYvF`T_v*h@R0uh|dSt(4eD-O+1gFR}Y8^b_yB%zn_G z%k2@Gw!~4uhwNEO8bfAt;KTNEh4E?wdiGLVAKsHdr=Nm!ncg&)m_!fl1wLZG1kbF< zl*cbFw~wobQ|PZoz!mm43RCIrG~lE5Zwk|B51QrdmA3y~jz>CmhiYf95@|=;)fV`e zJlln;LUpoN3-+L`(ZDr=y(w-fEUxUec0(0bUuxI};&rkIWgulj&9W=(UP?NYzVQGz z*jWlk(tv8fjgrK%GzyJ)_9puQB^^)3c;IGxi^5#mUkcn}zp8LDwd@DnYM*=;@8{!o zUPOsyZ(|0|ruHb)?5FI@3iD{$Qs8zQ*#K!F{WBc6)Aqc_IG@5WajBje`kA`m z-FCWSoW@hF1iaVgvkKG@x+D?2Pi>t+mw}_LCi4T&+1cs=jG22BfcLBIvuezIeLeU^ zwf9!di+&aXeo5`8Rnwq#XMhi?-M4BQv|3Z}%kn&?L8qf(%6>)sV;XeOZt$yW11^@| zU>@{Z5gcAuJ8;o?m}If09acHZpGWAE+Tb^AJ~IkuOylU(Rp2+(Hd{VDoIXL*lKqz2 zXNwNRq%rq^-?kU11YsJqF=yC2lH#{<5a~Mb5qm4k!+am~2n!DH+V83dj$smjHSRt8 zqT*8~MWWx%eqSQ=5zZ&#EI%glGdR{BH8T6S{j>6a&ZN{l@Cm!l`yAo(CKW}3Pujf| zUo`2vIPfWZGI*jZ@e)q2?+%9#?Na68ib+e*pJ$&|bq%LiBgIdGKeAUS`E`@FKM4NB zepd0HI6&!E@MrcXiZRi9>2~lr`*+2QaOPL}k`L;JA8!WN^AakicZYMqU9dYG<7na} zvFKUgZ$ysSU7qC3{?;C(i&1$5@Gg~P8B;4zCPbBeFqEmZ)g zEJ_*-{@os__#<2cf@V1T5AlBnDS}~}{ipCbi~O7;f7_+X|9Oj2Bf$TN{Gvt8V1H#> z?wv{=zGTtROgOmQI?JwL;S@J@w)?R1@Uum=xKZ)AzgB!5mjHyoUblIIQ~0MvUvXWn z;*L^`33fj>ch%g@6=Ql7Hl)H5j5~rwX5O(XVsCE!fo+;0W-dFvk zFF)LGQxt&*yPsC_12(Ox1s>vlL-8S--hKu=)O|+rVVj0jfQP%E`;a62woQu$fk%Yh zA1Q~U_zW}<4kO){6(6%{H8(V)+@90?z$u%8kAZJ@^U`}9Wo^?yPQe}S{)*3F`}lV7 zc=ve4=Ww3PK5&*hr1(6ZUkT22^Wrcp&ax?eH#j`Oy-zt@vS}*p-t39)|0uqKV_UdK zndJVj;-76=G66irUG*al;JQs)xRy+HH&Og2zEf=m&vIudE^*W80pQtgwo;)3Zn`i6 zJl8!{$?tU=ewcuJ*MHigYSpeaFcX_S&UvVL`6pio!@c$zMpkpZHqYaD(9>q6YI2-W zdq6GqWVhG(_C8Q6O}NevN|lwS$*(3Pvt)WQ;M@Uy$!gQ>Yqn2f`1?mzTmAhb9^1bl zO4pAiI4K3?b1&Rw{ZLx|(}lU#cLT~NfAeA0UejR^Pm04+cw|@wcbfh)aB!o zn(FxmeM;)26yz3Ofdk~qH(jjP>gxc$=ya>1mS%Q~AMr8E42Qp$b*nv7k*(%Dy486| zkr(GkU%$9Bd>1OTZRYmY6C&H!e5xPhh4Z;Pn#n7;Hs;FpDqiPK=uhs`TIN#+xaL07 z^)r6X@63Z$ox4jV=f2#2hiaPMHl5>T;8!@4`2=@86LpAZqFjk*a52j$NMF@KpEI4T z7Qokz;4d3FPEQN?`YfakDsMWyS$a5M;U&}Q2kpsyg9{Ab;7q4_Iq*&Xioy1cQ-jZ6 z&V5UZv26O8+sk`@*C;%&2Xr+z%V~=iFE^WC%q80TF;I>s+u=I`bLHq?+;+7K#OGd$r-)ibDcdrvdtOuup+;69@QXc+;&9)XJ8-D?XN0|aT+6q zId`1i+mau|6|lR3<3Ccu1c$3ePL|GtB&9+*Il7)ELr2Q}KU7q2f?hvzK;>f6`sJ_u zP`Ay=Jj`=N_9NZ`9{H$Dnd$pNB3H?w9$s~BN91FIKAK-1xZFPMgHlJXwfIUFKC zJK#F&D9RT%6;g8)W8`|v-JX$G3Hi@rwEg8Ba2@kG;_T^v4j=sxL{j7|r{G>V&#uhK zYg0gXvYbEt;J`H_a*qDkgBy6NgXVHF)e^Gn{egLvm(;eL16K|p2<&V6bc#C?ZY4!PveHg_1a3XDMib5QU_AK5X z>9!Ur_R?sWLy?ZPNuf_2#}irAI;_yImIp;vvp!K6ATIDopI{8}s>;X+i&y>g$uI*K z0R5JIUPX;~&rM{Mb&EpWAiWP*OG(w3op;?t#)&wEe(ndXZ4FVrQ;GN8MAowwD@;>I z>O>}5yA`Gr?=*^RAZhAI_oKQ+CR=R6VbwP^dds>kVbX{wy^HKhaVnFM{ftV6dXxEBljZPS)o2G9ZSp2x zBRdG@()1``N5RQt>;&G*nyAO@X|2GWEpGpK%-*LLu#2UOIgcL3DbcD|c&IYK9ovgqJu4yPe2fmNL6$gXV!B_2Q=xhFAm&=z{X;bH;84MeA1EuPlU$7+vcE&N7sIMXdf#9^(wRLGqnC z-dTSSDDKf@)IBS)PW3sMMy`n04<5{ohH;O&aoW@H zqG6OmpW^SSp*DZqQ&Zlr7Q0rG?L^*&N93#p>}3z%@-O<-65@O0=mo#i3kj;EfV#-+ z9^&Z0{4*l#oT4*H3ghn=pxI$ z{uRM;2c|ZFTqyZ3Q-a!jS@!Kqin{2nGyl~y^F5rOILhBmct}Ie=(48%dOyw;O#{@-blKIH_VNn{I+^A0`7@`EYrnH*D)1WTh%51K(>VsU zEc<0?0wb(HUcOZJYe{?sGt9pQ=y=Mm>zy6=YGa|nD=Q!L8-*W0%|2Ilw`wfPMyMrd zs7|UaDI00>w;28=x-AO+N11HsdZa`ia-wmyI#6DQSRsp?%p{vyGC* z5bt6r8)x=a7*Ef21Kw^|1q8U0He!@PT4dn%Y9Pu1SAIY;cZQKsU!*Qt1?9>}6vRMz z5im*6P1oGO27(?V_6T0#&S-==Wpv;f$s#alUVT)LjK;zyHQWht6M3gad{#t8Q<2(6 zY`-52qiRMolcJG*8MoXBrYZW&jOLY5rFWpQ8L2lCoVp3vLOi>vE&7a%mVzD%`_W}) zv=VmcAUcYSG(j)Lw+6NrtYXBLBMR<}wkBOb+mn$l0z;QgJ3*7?bD-^SBqXLUu!BgE zkR1rc%(&I0=T@O9%ji@YjFIZS%t<6OW*)RYBgT9kh2H|lU}V%WSr1wiwrp)=G&H&B zV+L=4mlTuBuSNFU93!KR$r&Bv?FaXcCg)a*i4%;B&L+p&h#iNpt7rI4dZ{-&)X*;t zqo$wc46At~^1Q4tBkD%v`|SV*DkD$t*8+AiISH&kvC9#vE2Eo)+PyL>tH~*kX*>+Sdzl>5nCA!K_ig6eLpbiAD(~2we-Pbs zMsJhfibl!^cAO5LVRCS7#$3S>2zJI?Q>Q5JMqE^i@^2`JN>NBl+a$WEVk^SX3%L37 z7VnJ8D3ph>(smSZp2>k@^_W`dmr=AL&TJW;W5%2r4PmkQ4M&(iI%do_*TbXX-G#s0 zh_{^ty6hNjK32{dv#~Ug%k55+lf><8TpVzLIbVhEH-e9Hinf^?Ky>FHu};*7BRrgp zepVo7My`?3Ura?K5augiG6u*^C3YY?3wkop(p`s#p5=HCvUElF>Ua;fICiRu+kx?Z z#t`dkaO_gN#-B0HqL*{vc)RsVsg7C;uGV)*h~5Cqos989RcLCMUyxp4 zz}Z$N0*gJ2KUM~oJsjieHc1{b=q&odjLCwg5xk0_QpObPad>a@8~$8%GG^hk1BX1@ zQh^|cRL0&ZQMZirkyn++@JuVF+OzOE$2x{bV-~UA>fbH0^3Yt#@40i^R{oB$x7_4s zV%`mR^@=?83L|lBb2^N04UCp2Z!AH-7ik@yf`^tk9I}wBqMB=ujp**GfPeHBEPN zl0Z*rnr%7vt?c76gJUJ$<+xjbwsAa_$-*n0GN0rC)cz*k zY?b+x#%-o^rvuy$qY2U-rqiW4a0g#T%%At1#O=V{e<<8%svCzh_n0G0o}b@usyl}> z_kw}g4D}b9{mgxAj`6oWb(~w~iyz@CBDMRI2g{i+T~>(sD?Z9L^I&xq^ik8v=?;9k zp~7RPlV1URC0*eu)2X!^c&NWZOm=+~MzLhRsu{Cg_jComK39n`+m(MO@bFTFnC*J; zHsBjNEX;NdO8~y95wl&hvVd=C#B3Mprjhx!M$C5o$gzA!BSvHyD}evmIviI{s6zs_ zPXQm%;u6dGvmfxN#zmI1X&La{ttuW^|Fbz3_}`HS2>SHF=%g=u-Pt*W`1yqo(%rk5td$91*mc{c6lqRKti$!yA0?5R);@ zrtsB)s1nm{ypi8Qjm87#s*_is`9^R@74STpV->Xxe^&3p=rLo99T=K52`%l7=lqYt z-;?$+)LiZc?qloYsT-#W^z{L^3;O6u7=jr)?8ESkX$?PRJ_FwK?->ApGVis!;C<0o z@Q2SqPW5Ksqe40KBjX)==OrCmeMhI=1^@GSln zmtagsQ@!9pwJdPKLmn5rp$k{%_$+vs+XkM1np6#)&r)4YZRaYqdBHN>EqI;a63`=> zsyO3eIxQ&IRMlyN>bPKqrfSYCv{DOJYVtX+r+`*ziohXri-D{EM6_yzpGUmB3!Ze^ zqBC6Z=46`t*8sh3)bn#uUC<;jC)08+`DwZW77QKI7v>4G(TQv z4~l%j6O}P)_ylOvOrtfw&+ohi%V5D~9ZbO4fHri&7M%q#&JqlE7HriNujcC)tn_=$ z=x}ah2)1(qY8*xcJ>l`rB9v4(OTWZ$(r1IRHJOh6C@4ph<$P5L%GKm@_Q!xGXtJF- zXkfw!zR7KK`u3=r08)kaM_LMG@J{3M5JCSL&INKE>a&go&{Vk zQa@c-16(1}0C~~N6h0ajaSZL=0bVKMcshrSE?gzj1o{h2L*Zj0O`@gz;?*Kerr%NX z3)hG=h1S6iDSTX{sdRQ9aIHww=tY*U6KOcz2;RdE>&@9Hme_Sj_|U?QlJFN4@eBL?g?WxbKcW%jXc`KW1mox|>Stj?2`Ziz-4AReh;xaXb6F+}C(+jFz$Wr=GVNw; zD%hA_VoVWiLZLapTf`tvp#d#{sS;Ewt=R)?Vd-s}X;jn&*ivvPy@MKA7)}%4d31ug zwO}EA%BXM0dp0(IA9I~?M?9-44y>q1aZO*lraHq?1uuTco5hV?gk{&~Hf=v+AU;gC5jV>Kv4 z`}aGSpp5e}o56&IFi?GB&Rk>OjTPe2!y)Xay~aDSGeG@yLz;l=P@e`4*vu~)ix&mv z4RX@hX|NvW7|sthK|?gzPRZk-p)v+?N|EMy!!-FEZ%w>^-f)dL=$3{+IwAt0)>w@{ z-g(oU?@`a@P1jMu&154%GjvmJJ9om2m^V`sTKJ>wfU_pyLC+)qpsPc5?_G4C^H(-D zYdugILM>FBq9wZBu$@jNNPp2oS{UQJGY|Bzrg*0gnx!J?!xNkrpbkaLv@FS4h<>!F zT)#Tmv9dsqYFUbty%e-kQ>rr$#Z0v}HuMOO=87Xgi5Gfyg7iMRRnwlxuP#7cS zn_GF3_7gWs+KBxSa$iwS}(D$GBDI%}YhyMCzpnx&wO%`luCZR#C4Ty<<{G;B8^y z0I3Y_Er`oLhCI4k^kMOrnoDF_rt{lZlOuqRRd8DfH3=V1MzP zO7l7a2MLDLsQ6j%U}1dXLZekQR3;xf8o?CkT+uM|D(Ax~(=^hHMo2!4lxGYYFb94{ z31Vw8tK4XFt;$+2^w0;{fJW)8!2#!ZbP&C=Rj>1m0 zEH3dPv&F>1Sw>N@$r^y)bB&_;Cg*|?I}APs7ELwP&i$fk5{yCD8zPkHf;N4@MKi7`g!zX}cmEjZHphfrGu*g(~ESA^#wPI8nXaVly@&5Z{S}I0$@WhjhRK&5)tGeOcftYXssmff-2o}MbE81vYhEv1@wALjJxT?oCvN3cuORku4 zZP0|2{AljSb80uT5!a>;T&{`>b|V{c4KWlb`AJ-`t=NeBAQ3J+IA zVk0v!U-CZ6zT_A4bp)L{%;xv~YPMkW3jgV?;Z9+Kx`imC+0;v?v}1_d< zT@{`jaZ#yyYd2iH;-XVk$f>I09)TF9*7b7cS9NOztg8I!qN?iVBpAV0BjLNM`!7z^ zDCN7AJMR1_IHtK({TBu7%C)t%ei2T#F25@TQZi=T;7pq6x%8T0G^rE(I4i*!? zta)wS69BO%mG5_*xOGu*e9yTl_x^eUF7Im>cUYx*F(>GlcEX*){OTcn;dI<7M>wfw z6;9&`N2l?G@~6{y!r>Pg!3Rgf_X+1Lz%v-W%PR~cp?HJC{Y3G`X39{*dJ5PD#WHzo zJ8X&;hc{_k)a!I0;Fg96ji;R=@}ZQ)TO$xwyRB7C6UG4g84MT)Wax@fqHe zcrj;@vKuf)t%63mxUTs+oT9UQrjdYd?bOoZ#@YfZZX)S2lm%4W%w#{67Ep0p^G=|h zczA=QOrYX)HJxK89)$zXZxpvT!(144;(Ktpi?ywX${IWIeK^!Y-%{L59FA?U3@?Yr zQ53VryAaGpT^U_J#zn=w&9m^*;5Ep47aUJ&)g3!?Pw<>y(yrF{c~T9JvtVf!oOoU%}W$lD7K9#7QEIClXf|U&5bLOAGd!VHMwlCePu;{JIBEylnD3G@M%* z1+SPq4-uo3<&eonbql2|ubQlRMy$I!^t<2)HoncrlSe8OWwZ(TP2=Zf1v~YEz=Ee` z5syJf7sBH+stR&F858DW-(|Aeahy-V%qZ9+Baq4T&{p6+!6`Hg21dcNf>Wu(PT+Hb z)2Kct|21=qO7C=9(E)haWQDL34{fxl%F}Ro)4X_=s_GiIcCO6u4;^T11 zSO70aOwJuU@ohLHHHO2xsv$(Rg~M62#Rc!1OOZZ1@faLd!>TAaCJv|IFfSGk$Hn0z zI5b%ghZEv(1`frUa5!o1;xIB3&%tFXNBxv}M1^`D4so#33O+E8D~F44=)t=8p?O+4 zT!O>555VEHI9z$cGW<(dj!Q6u9?p9Iu9XY$JNzjB=1^4%l&bP2FsKyvb8xlnS2*8o z*7RT^Mveuanp~u@Pehr8W&caN6Tk`8%QDwX-z9&BkOJ@olnoD02^Byfof*Cix1q? zdQCBAmOowxZl=<#w&9k|0ynq5RC3HL4?(9~&_d*xS)Ml#+{XHg)OT?lU3Hn`o-P5d zGHE$`Xm2%&<`-fn*~4no(dw-jCs(cI;_M^=VkX&F8{Ea3tmK$Up2LkqH{l&7-OmZ= zVU;TRE@(WfE4PX(mnE7}VOD1UNpUiK{0ln&nbQB)S;kuRZ$t0nX$v1u>A}}omb2n$ zIX|n`qC)f!i&$%J5^+c2dl)@CyD zBGyCI(pKi5$;Gdmb-NaR`&k$N&%-_rfzN(UWDl&JH+g7u7v9e6*&*-Fa@NP2RdQB=z`vR0u_483CpLOD~6(0^o#&0hD|7|sEmtX$L=7|sEm613?`1blxk;d;pD2c8wFmv#;S zo)fG}&CrmBz7+J)U|6T2uLL9MX=Fv{yr7@LQ_yCIz80=YY4v~?1OvqT&qCh_M$@1? z;6=e0%31*YRuJ={n}GinjHhLB!0!a>(B3h?OM(g1zAf;3Q?4YaPwjhye-LpJ%|(%h zE(OQM&B;~) z$}K87&NM#k2ctdI)S_x#(f)>-$y*F+e>XhdB52Xu%Ye-#9GmXuYLzMQE(fE(HuE@Q zc_Og4lA`_d(HAwqeZ;q)PH}a}5DWzJS{R{Bp_o8kOC!`*C_a#vW`xj?s@Eh0Wt|D`I>%wKh|{QHE^vroI^LRYgoX-sr0(UA z4ioG`^EU&B3-%yi9pDJT-t-O1J2XM7=*x}3 zv4X>?8mH-Y!4dR4dg;&|qA?>0MQMb_3y!9@8UnM#^H}1A?xAeKaYpbkH>TknYYGZ8 z`ZpBj4w#Pn%@7vYMpQsFTjFRCk4i#!3fjbXQ-el zPX&eqW9USfyMqFYU(Yj44Y?IARB=?NI;c3$6W-~fS=^!(smIkR4>e$Ehl+*wq2;Vn z$27P|D_hQ455Pm%YKic@4Io>921d!EjHp52@Pqki074I0TGf|I_89cxG(5OW5MA*4 zMc{Ia!-zV?FR6w#P@$C;^=}8kDoK$+ZxHY?L7SW?;A$xnFTDk0JG4fyD&;(Y_9yhX z#f#XvBK*Y3TPqk(E1Lq>38omq^L@eVt#KTOc6Ci-Fy7@4VetGrNA3v;7SmmG@{Q0Y zK`SsPd#(}Md?QM8xwqOP820LvZWYGjp<|07f5tk;Z;4Jo($Or%hxXtUl1&ioy^%vo zN%q|cRy7sRiqxy)@LXl6x;1`Y&`+;Ef}r-pGt$qeK0VeG{DM48^d2-Z^rB!iefKQz zCBa%WnLDlnf-!V*DDa?QEN$Kmd_^!wudsdbnqZs}%v=I~)9Q)ri@H(|?_V<+3tdA0 zv8XP0%SR-N1{GHU9=(yg*O~+074*`R%Yp9+`shpx;QNApn!&B;F~I<}tqVLZ7(*|x zVRAxa7)t*I=21c?MVvrwYXVORCeZ;5L_;44CQ}*b+=qfG#Pi&t(}JnAk?ZtFf@x$u z2K-nsou1}2d?MJ98r{kL&!@s&=qShQj9?GCi)+AVg1rMX(F}hs)K@jNXN3j^^056q zbWU(6aDox~LU1Hq!h1qr3XY|e*1)d>!{ezIC;z-~F0C&Eel0ken$`kd5S&iGaFzH* za5lZdx_nVE&j>#JF!)=G4-AYtQy)zl?8o%bRngs_MGXvUnh$^1@SM^=o6d43|03ad zY0oXd>w-RN$NiKej`#hnzY>Y@y` zn|v;A?08~m1(#%mJST~bba8KiFN~NO8V7N8&52d%J2u$;f<9_K9#}&#lK!X)tSRWH zX*MuQuqJ)j1Q-wu(9#7!5{#zrxn+qKjG=hcuyClBaFB+^KpZ0&Pw`x~v4VAI)$xr1#W=%eGD_=bX!l$Ql;BG zmyADR=s83rlp^Aw5ggYE+{|?q#Tr%708{Je8qz{(E_#_OMC%*rd6SK$HaF4}!=_bR zK`%}20ZbS4(FYxY?F9X_@L}kGsJ(E2)}tE=br6i9wya(q1>@=V2Ebbd6X--du#+IH zEzZZzg30tUJ}ia02&T|>He@R3jMG!bZqU5EIo&*jI3;SqG zHSi!oKh@))2MY$MadqGj2`fgo_d`XBW%v`g=^W92c5Qn(*<*l zpquOH4A(T2VARlL)0nsimmh^@{UI$DjHN}~{LXiAWURy>?dJNhKyWm<+5QNH zUC&^OU0ucU9lv>@3R@ikxPLSFZWWq30#GT*y&^vhn=%&x->@k=8^M3-;eq>Iv!Mgg z|1>d;{K4peT%iYD)GY~;hoyoWw4IxSrIqy`N67U7FB7p%A3qIzM9@Qgv16!Q&`VD= z1}+z@O8YrgD+GOXas%*D!AQC{6}VCmtIU=GR|(b(Q=Jju$Aklv&q}yjFq(F32d)u} zp<&Me9~TT#*>K=m!FaOf0M`lDq06id>je|2Q6aEGus(fM0^AT5PNJsV?{5@rNSUZX zp(g~B=`498)F%0bxeQK|3&rZP(l*^{TGcGP^J|gDKZr~nOA6$tCZTf)|u~+yr zo8C_W?-TyZraL>b{yi%WYu&oKJ+G=80&vqt*5(&P-*CyvvuWTLMIUj=iK>qW<@pbA zUKdx$mxZsn>3KH24hgUD7+!xf@0hZi`gN<*6m)Bggp~z9|Ab&_mI|%6vlpI7#!1ik6`aXNKvnx`{7%28 znaNYWZEdwTJk-wSX`2?aXQR<zMMhV(<@F^e(dg&4?dbI4#^U-$Bhgu@_ z2d2!q6PBb6a~atZ2;|Plf+Z=4g|xHaIcRr&S=qnwREztFIC(gMVkQCOZ7vRcnWt8q znYBfl9LS!H!E_zL6y1B)6-=cStjr05X@R`F=|-rYt?lsiz(k(PsxR1%YC)mHp+tF8 zdn#*=hm!<5(1>(k1Hq2ejvM)gg16GW+klM(J84@dS+Fx+JP)>~U>7>Y#!M55Ru4Tv z-Bcmw-+EKa`4FdwxGzQV=(U+VJdm!l&fj8RL?6vZAMt+oP;ieuOY&a`>CfjVC?eE_(h&8+}7 zskmvh8{FUK`ild6-L#N(Vt~!lG1#^1rc*n?1MPE4UgDvRgTRATe&gGyhwk8>aES1I z9(uDM+rL940!utJCkGye2`}{+!3(T}xi(j#s4-Ai4?I{Q#NE%YepQOnpe1(!UlT+P z+=50cbl7f=N1_(tPsI-GatOU;(;@C%aE7o_F3gyR?X7V5k39*V((AOqA6KZ0Ti2y- zZk|}z^|rg4Tke>~s4bx$ZZTUFs+ZdHYO3w!7`H_!6wYS`P&vpBly z^>K66)73x24dW#&b-urw>wL`ly?A(_n`g$1=(k&&MlLd7xjTfjELHV9uJVRkG*vxM z2ugc*($+T32SU1X9^mm zj|9gDvU4zpA(R`)MtA&)&}3>c9Z#N>?3_+pIsnfJ&Y&<`D_@A`+4RW+z%K>!0y7Zq zS7A}}Li&r#{=7tao?7b``dS6$N_@;z_fLf`2(QLzC~S6qqn>spt}#j3ofn1i*<2Z( zmu)sYU5RT=ZFyc1{>+5wiPv4V!`k#*Yw3~BPx1mBO00%DKMNnk9e7-auL-{_gPmW5 zU$OM?=2w+E)GkYpZ>|d;w)FVsH(}hht_C>2hsEKjr5me1BtRTu{B0RtXt=o@#Ii_B zH&2%E2}`$xE;n~YSO{t9rqC9~A;;O=P`KT!>Nw`nB4t~9gg>*$>;`$*5r@xl?D9%D zR1rRl94QA^6~?K^wYY?;34dXct2Njs{G~;0lfe_Tl7m7xVrGy7WI3S z+aJHg7{@B}$zq`z!Z=m=ZLUf+g>kB~8qr5d060~-CJ%uFBFCx9jqeAOFiurg-)N$R zOK_-hb;xT8FT#gFo7I72fHhrrcH4 z7k<}8W%q#_2!HRQTX@LZNWy#2R{MoR$@0FXHX1;-KO2h!j_7U6F>K=I;U2aX+H_(g zxTyqyBX^bk*-ZFJTitvax<&jyg-?u|;J>-ZU&IS|_?Rm4mu%`k2HeukO{pvK2oA^% zcZEYMH@A_l#CLJVFRaf{np-#FXm##nBQ#wC#EH4Zi@@!LKeoAp8RTB7o<3t6-jC42 zu)-=kst0B}PEhFL`1UsO4e-_VJd8wyaC){}jTvAIfp}n(bz}>PrNUWW}-x|;0k9Tn& zwE=!{pW1D?6*SZa_{Dt^6=4HBJ1=X6X^+L7tK+nu#a%d->@NapySS^iWpEj91W2}E zdL1Vpge{mTMtnbT=AtuM+(UcyJ0oEHFP1%+0kx}rai9A+RyaP*vN=+g&2No(89BB% zgB?7X=@_*mEqxdFbB4ykx&H*Xa5Q$fKm+bkgyT^cfClRIVBYF;!q_mgc+hi7h}*?c z4;BwTuE_6Hu|Y$=R}^r{c7ulgq$tMWqZt+tlVxSj2B`Pq;emGi!UShIbY<~~c8Zdm zWG`sc?TV6}TvXk~WAt+=P9Yzux_GR9MXK|k3edQD%4?d_4xRqu+gB?}cRp_pxHBI{u)@qo({Mc^1n8b^;riYUG2jZm-q_HspmUD?i9EyILz6 ztc=MthltnnVs(H=)ZX)eOM;?T^U=BzM$IuG4aA3WMz2*$3HMHY3g1BWp>MtrIACm0Uqk5z@jS8`D=42JUW zFejkH!~xy-!o@EbFTC8MZVSOV<~8-gRTf>G2hJ6K+@k;Hf+w1PD0ziNA9eswV&(&r zHd(X|#(Vx`a}l})jJ_<|{4{uq@D7W1rhunOfV(VOfCe*vx;eTHM`)i#C(*X&&oHa2 z7wpGzeUE@=nhh1hz@0n>JWKq;VC@g{E`PRpJRNfq>e`J~tcG{Off*L-n8(0#)DmUh z<3nxB!E?>HZY+nvx(ya`ex3w)$|AngK7WCE4{8(k;#g|!Jh8!1tRxGlCp+ z(YKw!4~UK&!j%paz)MUvM36w2np((zP_?f}po=`EkS{gEe2|yAQ^M*Ahh=6LokG}y zBf#b67{$0#q6U}gaxQ0Hlu%7a_n)gL>1aODM z7k=f!E#x-YJY*pug-2eptLo>T#1f;5ORUjB=cfMZqY&|2_IlEtU0P(d{Kfa&VaFZ`$q z+HG!?Et{L%*x&FcJ|8MV0S-2#beH=F-mj8hpj4MXSD2jYLbE$GnU^ySYyg}m=%c33 z0E-0u)CCnZzgRFpQCuYR1!IhATs=&^_Mh!GHU?nKppQmes&QQr;Y%Y$Y z6V80}lVzs>{I|1E1;uIdF+#+1ZRn}k12qsY}=cw`Bi5 zrtB4;bmtW;=a%jN$PxA-7I7P-Mal@cd2R8h5LtHNCG_-MkCm^LTL+mn!zR$rn*VNGYs=oU=ksIGS1b(Yk?X&^ zGAh?8uVN3Z!2d^%WbB8l_bdD%=#(0Q)HSNHs!17s&H9Y|&Y$)hGO}6t}ClGI7XEk(w9s)Y1$>%(e&NA<~ zCcpE+aL@@&0Vf}QPu@vQG0tshH1bYqig!Apo5}k?u8d7^%0j>owJ^!KAAM}zX-&z_ zrz1fhX-aYSVwykiV@;{f7Sy}EPc)@Dv(Q)NeX1$l`4LIWJEN(ib6_iozvgp4ZA84t zaXU-h(FsIkMB_;5{j4()hcVtLJ;1&qqITiu!Mf<*Bfi6Tu+o?L^yR3YJ+TdSondq- zt%94lQsG`zwHjP~TVNPnT1^mxPz+B>ePSVcDGK$qG@{aAr1Lfq2amQuDe%frZz9+) z;sEtQ{VlB_7!#N~E!!xqDYj@lt*QxWlt>fk5Zc>P62vF2jlgKZWOayBX)VDNib5k( z8Y{<@q=sn;MB^iz(1U>JY4}S7N5ZoC6<+qll}S~J9K&n&y6Gd-Ptg7sHXyJzCO;C}8bWXB zSTw@C7q4`z`Oa-O#eS^$zCzgO?EW^Y&Gga^68Vmmk*5xr(JsAJELd9|0#e#Z&`bSb zT9tNI^_Pw0o>hQdMCzwf%(j$v)pi1}O*@I2REh&^F(+yz5-p4ZR-R+qn3kajE3G`o zwh48DvX)k!W80Kk!R9ILB|)c9uNlDG1XGoDUfNqQjdni`X&=FGI&DJTE6p@JDn;x_ z=aYa#1iR1$)V|W8;=2bu-4HlTus5}S2sm6>k5*z|x&#ZLbcEnQx*Ju#bfo$7RjzbH zX=_K|D9MkJ^eq~h((q_?B8ZhZnm$F9EFB|xJ60FfXdVqI=N(dVXOU2Z<95K77Jzb{88c*QK8Bn3P9M!_nj zoN_}c`G}v=sS;B!ZA4>PI!!Xcr#=If&KA#p`Vq5ZrFkL^sP8Op*);K{kUM~2_{p2=wWG*v@j_&vjSKwVWrZeT(jqk=QNs% z*06MeS#L1se!3c(l!nb`R0ecZ!@bf{Qx+xyKJQs@2tf%)^Y1gLT$@b9 zK{q#>{A$w2C`p8$)g}3n<^x zdYiVHpQAK56_jm~f?9s(rNt&}Mc8F#aBCcY3Li(1S?Fe=S-7CDTHeZs<$Yetx9Z_( zcoAt^t4)c4V=+>bF|On#soyo`d{|4^$UZ1*8{7XjQ)=VkpuEi#Z+#0_dHDIJ!#}7j zte?QaDlGYq^wgcE6u9W+=S<`E0$4WG%-W;RSF>`>pJ0?!kMBgly=H*~m8$cnly)EA z?hJD7U@v9uH)|?ie35l7M#Y(s#gYr@V_e@)}syJ7$`a#hpf&z+}CvPRrzx z?aMMs9W-Yv-w0=2KgdJo1|`co%W!nhdXKWQQ=uv3`{q&QTh+;yVd=1WQ^}gn(@PwnGbAS&SI@bBL3FJ{Tu#;?JoO4CwF|(4A@y<2b;^U0l+WEnQ zJYjZFzU`gv`5`|tM<|)#T$XX_q&ZK?E>2C9(wBA0+^TdBr&lX@e{7yovbPf|(}_>a zAC&CxEX;;HZRSsuatv~2cYyrVtfu5p=Mv6{vd%DWnloY{A08Bz=07tD7d)w`gnatyvmjdww341&I7URC~BWpGb- z=*!f27c^M9$>-DyP3Ogp&|jE#XGsqub4{tUEBb8A7m0U4>&db1D$lsl2ZCjM{gN8* zf|ltD{gqipC4hH9hsw_X+H9gU-UaK1P;WP#jk}?*QSUaL@Zr$c zmBvMoy{2QJeP`WZfCE@Wz8&;Uo$Pel*`uTkwUcUMSD{$vmz!MpSv@ zJnN46ozl2WwDdXXpUt0?#$}@7GKKxc48V&`>N3$A82_^FQs2QBR~JCvGb<_od$`P0 z5BgWLNf&hy1lNhuaY~c*n>kbkxNkbAan&U2cQae*sg~2DA@m>St4iatQQ|b{KdEuq z=s(gr|Dwiaqb+i1`Y$q&0^zdJ^WC8Dn}?OgWuv{)*&moqe9D09Mi&xc_}lzZXHcPLz-X~=@T&C3tNZiBebj3w?ycg!=?xe6DRBpSKle8ad#n1J zfdM~=p^`SdD~9|SDZ*PRL*Z6%Bg1di|7zkfLOeuFFnm$X#4~8{d#*at5(8rBX?O)rkyaed^cmR<|R!wL9;w1n&uwlv>9P;%R zMw&&c3>LF=<3|!!0aWVp4=K!%K*zlf$*8n9#r>T(0&d?Ya9e(A-4W@@YKafEMGay8 zRRWe1v;2E(L*=B@@(YDIpL95029RJdR|CSOUq4bJm4aLs(C@jkSiX1(Dqa4`pbU^M z{xSqS;g4MAivcVIjb(g07o?Loilv50Ep&{9j|h?+_$iK4=Pp z$@=bU?o-GJI1Kk;%v6IC0|T$%TqrSUrR+3Z6)9E_Dp)J5Mvoqy7$T|&CRBmDFo{Ua zr#%CV@QdDn!KUMr#PZ4d{$^-(3{au+d0!OmDlFl$&cCiL~61gv*-$|0V=$6S2zD|K6w+(-|aP4c0C&s-^XtFL|L4V1 zmgT1>3-YpdAj~d-^9YJ;f|r`?RtfcO^yHC^U6g0>XQk#?-1< zi8diceH|iUh$Jsnda$2&C*s`#OP*^TBWWX5|+X*tHK-md-v_ea<3brv98oT;Nt5!V+fd zjfgkGrBvo+41lV-Q5RAT;ZnMPt*SwUE-1JIp*}%SgsLc^hI!u&G0O(D6Zaf1Y$yhb z47l@c_NouXr!E%49Z-HVpF8fSKGs>|(G zxqK(*7j0_f)%5HXsG3@Z2QKap6|GefRhw;UX;nN>K26f5P92qluQbZJ17!$m0WHm| z%n!3cVv*{i%2O=TuzZ z8*YjL**m`?D>qF^+y)DD8q|Oup)T2C;kE+KaMZn5AEi zo5A}7GkmyuGa80byhoEA?i9mK9oJQ-&$w+C?hKv+J(dYB40mc&f*!~4OK^)c9C`vX zSQ_q(#x}XntE+N2TMTzT!yMerr2m?5XJH}eiA>M8KHPZ&)$2|&<)aR`ZH5BPgr3X{ zE=D-#%R&2?;1?0(v^@-$u!DXbtXs zQyM|NDSgmWO1LkYPMc?7UCe7FhO@do_j2A6wd>32y}U+U3&Kt- z=dA321lOwT3#ty)PF=^Hy1ks62^KxRMg>9Fb=98t+4W8|@rM zXLMhuz8&oxuMfR}1-cXMjO_@$kpJ-wECE!*8eJ)@R-FWcQoJ*$?}9+Nb87YmqO%dyehUA?#$ z`b{k(Xg=yzj-skd<09^AXxZ!PO@g0nqvYlxxM=6TW$s0DC^5S)9%XfL2KP0_7k8hj z9}G2|dlkk_*X~0pXMH+tm{NqMc@y4LA0K;O9q{zl=Y30 zy=6=|W^P6elz44`X>4?{$eL`Z&pr8YOXaz7_mn#POOusHVBL?IMiJ*G8jAY~i&I=z z%cqp3b+w$KjL_9`ma@FAhjWy8HAd>;ypp(RP*wM&&*)uK*TV(MI!>?W5c(qTD#SSZ zrJY`)j8zXHx|dnXIQ5#F`?+c)R%CN$fehAPP-3|)>A_bhTRO`Y%l^Mg-C8|h>gKHy z(^fsM;eN$ScJ0;U8t&K3DZ%-<1k(BsWheD|wVStSOrrDK0Qg>`Zx{98rkl5BOgHt| zrmNPBk+;cusK++lyhUS@)Ki;o-l8$R)kB+Z-l8#m)iaxJ-l8%6)gzm3-l8!B)f1a; z-l8#seWb?zVgy|J z87Ix}zpAJ>?Khnhau~i(y~uRDp3n~%9+!gDVe=nmu+(%a?1sO=4^-evkQ$#XOFyZA zD?$If4u3zNr3b+EnBY&5mgR3P#z0VF#X!@Db%XE-hqS(66-ti&s`Z6X;`#r6@XbdV zrnOV?oJwz?13q{MI_Nk>z5)Lpn1WrFU)wJ8&w=kQ#PoA)i2E{;E@sctKOj zcI5kE&h(+su~tD0QFv@8%-Qf7bYuD-3v*V>l(LD`gFHEPGR*m784OLWv#FBc=`iPS znX<)MdWLl_%sE^Vx*7GgFx}bWnc%%J=ZrL|XVo6W!9UE2-VWW8`hHjuS%1}SZOI!| z*nk2~Bk7!N@#&fdQbMe_ALzo+j$61FEAGc)+a{YlST_wYib~n;V*H+Q7zK5nZ{U6B z;`F7|TZmW24#p!3avx;^PX62o^|l*khQZDSoTt0xY`yURy!YRg_w-(rsYxA0ruFi*jle zfPX{#q|)C;IrC-DH?nUleLKp@k;8sdJJ6NzccSq402+q9b%~VcUX;(d(h>ggjQ>ZJ zx>x14vUN+kAEiD`?6#(!TE#ge<~<2X=7z4zsIu;mmV6<9^R>E(9h9-LdnDTw>x zu6_p|6;#Ff24~G~f-UEuxC7v;;yBV5I;l@jq9s*v`fPChUwv#rlQ_Ey33 z_wI1Jpx)dnPGK37)6`p+Xb^qWeRns5+28M@?zFq3sHgT-x7uC(S~!Z|*XMj7)59^g ze7_In@9R{T8Ha1@g}c}Eb*A9zw>y^gf3mN0Q})L=W_Y@<^I!z@cw2^5ypz(`DJl(O zg8h`L?~8q%E7CEZw`(i?MPDac8dxUvSH8YZ`4uosq~Tg$-8Cnvw^MNgw6A(M&YjE* zZy^DhDNbR5ZleH;pncSL`pTNt?lfDLv&0VW>vXRH@9FkcbVa|&Z>QT%C25f}RE_vW z`fkG_3wXM-?anBoU*sJa{&^mT9F?SBi`))_ypZRvu;qn3tm+Fx^ENPitVRr!42HR~gU{G9 zP4J7HI$Q3(%GgvgVFB#E4%SA@6iO^e!#dw?Cmu8tA3tbze*B=>g$I}-`f${h($Rgp zI}d|AhW4Q3F|;QokD*CB- zxQsGXpEoY24A`Uqu<=s5#bZO9pD0bN(UY z=o&Snk#!L8B?w$Tp=|G@ZiQS&+1sff0r@Irn(nvjSy_`D--Mm;e$CQj{!~27Ctc!o zl{2oz;FfAn=nd4^pW`P&Z=}Xe{@dvg>LYsrR#DE9;7Vn{^eZEA{|og08x}rO*1~&w*rW6pfBFN@2$ z)h8-*J8~!Xt!&U~hR41=D>LCwsd05FO{V&1s1KOV)aKA<*>(=$cDl5kbNVxy>i+vv zIP$uBH8o7YOlPmm^*^)pd#AYJ8OwP=`q`Jv0B=Ry zmLq7MK7vQIq>A-YYwD$lf|H^3T5CA>u$;MJ(0Z{o^-@F!)TqzZ%dN?4y3Uzw1klT^ zskb5$Wzv4#l9#L0Yr3rxp>I%sWjP_TMK`Uz`g*hF43--Cj>9M3q9`I$=3CTwN#e9@ z!1vU6NuqmUIW4?R!&KX;&;7VEA`8^(?3wUlwRBob6VTkx)%BmR`CkknYa=9Pj2BF z+xbcwkzU_T7MV0kZk1Mc-|C04ql7=^y5VlH?c|e|5Ta&Kaw%hw%rx^+`Z-r+CKO7E zMHb~jMK?b+-b$-74LZy|h)x=_Ns=t#_OhcV7;Yb1E~iHiG~B-SB^;5|QUGp0TaEzH z86(FSZhu<_vFH>`BW$?{8=Yae$+lc@jZVhg!ImqM(L)V)uq~Heq7lQFV#}1Ocu)sq zI>f#s?itceD8 zR+$w48&*PUDJ2M(1axu58d_BXekyya0#GLZN}b)q)%>7cs2J zp@A2$J9ARBN(;=ud4J9jtuhMWq%2$ZsCN$H!yzZjF2k{xJ_aP z%0=y*bS>X7)w{hpBemRQ78o-w*~rO&l*=NU%>rr3=|;||mDoNR`vYYKiJZ|Fl-zEr z`=2>(x{|xiz^BnZbH-|k=NRRs%bantp|UPl;PS5U9k0ivLuO!Woag6E&}WUO&A_lB zkk9K0#J6VPZ$6Bl?nWESt|?oIGjx2# zX+2!>NeFeHtANqyD6~8{X|*=(*!0nc)k;H&zr`XZ8*6t zqaJy&8^0ciFI~*YHluy@;gySNrhP70-)3tjjoLmNtcHX*AG~)oh4;I`I;!@5M|n3- zgKvxYKao$o4QG6Q{4k@S$pL+X1oa?I#Ki3n1C zkYV`G)=s^Oob(l+8&Bj%1bkoc=6w|k7? zw@x|REPVy`b!wn*)4z&WVvZSE`CEi^v%rkN5Z0hSJxDkyy&TG~~If%BA>MAu0S%MTAV;J>fw&sePC znMrukz79g1)k#aT#ju6HgF5LmDrr37&ZN(nk~EHmh&>*$|7eWZ>nv3;iP;FhWfEEy zY^@~)`#`iR*jh_se*^8)C0nbi+eBk9+P{V5{u_$q4(sG3sowa>8(TWL_f>LDMXTiA zSIPB}*eyRr?2=)4WW^`VS1LSUiX}ayBUaqNu_XFsqNTiiCDf5Wr)BO{aMaB~OGmj)jiL-kId}I{CF~u-H=+OpF-(N_u z=NW7PdW>PeADsB3Y|=OQm(&`TUNU49$H>r2hK*+8kfEcC8Y_(6jgg`ZJSUO-P5jJb zJ?23U5$`_Y5sY$4+02g;#RGdX4N+uAl!CRMY`^(&Vl!wRz8S2oCH!fI$8&5rp!7BU zF|Rc1N(%VcJKC@7*FI+&USOC8bE4jz*@!16h?)55hSEtjln0_!L+PX%N@;(?=%;pf zXREC2??z%6gOSecV#%fKo}yJHclB1xH;emvTJn6{UYG|=#PuDi!;{GDk`y$_N|cK1 zBz2f)e5@Y(=UG)9qN&#b=ob~t04@U+ZNMQz2kZK7+J(+!Um8jy#!)lLJM^X$dsyOnZ zoGQ**I9MEMngjMDF{z5WXq)l)`6NZDkN$aUU=r(FjH9VL#2ok_z#tZ)PFu{bw+X@1ecmZRx0=tHMJDx zfq%l^aZz5A-&3;ME^&u2t7Cat4VI9yHCZYoj<&x~$Fj|}5!TmCjjLv? z8YR@iKDw_rm%iRg4HhkAuxO@CfYpnf22A0 z$r$Q*il&}-Ks7oxzxrgTr9kKO}6${x@I@=sF1gU2T!Y+bW?DpF}XG9|^pr?kYQ z1-9hL=@$-4&GD)p{QhsRlwTSd#!1Y}On=)aBe4;83PB^vBKbBvz6?>jyRACD4EbR- ze6+hoTUE?NHQ~qWxgps|W?hIXn3P5SK1R!a87-}kjH1%wK7_%no46b@wc!lY_zDd( z{xzsx+kN;SmLKwMkssn;eW+fa!Z8kxfnUI3E$Y(lI%uSppNVq=jEud0hTJ64?!(c0 z7}AuE)DL;3;AalkBYf{~;URN2G2#ps15n~$kp1&?e1H!%pS&5tWS$v^q;2%$9#yV5IOMN)qggtC$-5}($V}Jy=V_h)1LmLczw^(Bh!XjK<)7!L z@^|y{pPiR~PvkFC>t=|KNAwMIV&VYE#IE>f^d1dgsWxdZXq$#Piq-Z4J;b;~JVuKL z>c97T`n(3~7V*hul-09M;{p171h(OG93;)Pi6zicdW7NMrzlS9UBr~BL40{wdey+c z@B%1QLpX-X6lpvB%pdg>$w-bva&jO$Cf0nWI=1`Nk?dPo9zT)=;UJ@qWDSs@I+Bfm z6L}+gj8^B_0Rcap|2${>>#+CQiGO90 zbpKKCU5;P;L0B+J#$WsC*ePd|5v#DCZpl=uF~W341U=mOY!11;S?bzb$p8sUw&1xW7|Tq`n7T|;IYm7bxh zMW<(|8K_RrQg%IXYqt^iA(CiBWAUaw zk~Qv7V!L(L(;rDgyW6Ts!YsWL;&5tgbgPKuc0HEd&PS5lDarYm-tI@zqg&O?TTE{Q z(wmG+GUmC*(mVS|dS@Rg-uXw8({7`EE_Qp3aY*84orJXNX+B()7=@j$&))8+#_%Gp zCM2X{QEKy!C6`2-Vv3uPJYtY&xjH%qI!)E&FDjdz&_h)FysO&hvuelRv*gU!UUX-q zJ`?y=ZOMIvO>X%DMs0Mu3>!Veyld&9Be^%s(!I0Mam_#U6xbNB239#W*oWdC$M3OD z-apT(Mv+Di`*}}s$f-dZ9GDOP#gy+N{@?hSem2iJd`LOZ`gqEDR+X|ZFXb2WQhrUP zYz(M37o#USN)o03i|{jx*omdk1``Y5U(yOiy`@zjCvs7|058jU0%t1mn!3DkNb0i%DOmx_Nq zFMbKRDq|$KLwxCycVwT|u@kSsop=%dl7cXJ#ozJ4+3P<3HAndPAhdGquGxqr{qZz1 z3`YYsTiS`Wp%W|NUs8-jYzkMecKA0J@p^TK<1>|EC+T=)5U01qYi}n`hfW-ae@O`v zZ$4bTmgC<&72NOz$xvAl*{aKpMU86GO{&RLqCsCj>Jx4Z8n6pVI={f`Z^xsY>OG>M z!1<5FuV4%sDkmI8e^;TT3W6#>8laLfs6{#g6e|v^za1w>hCx5$62Doz8l3(%h9G0m z7Rjlk%$NO9Z%AYKqiIw%1|98)0CgwnG!UR#FF1o1JsPT{F)05O3AIjz3YAdPBvkIB zp?vv_L8*8e(yV(-1(V#WZIECW@lT30!btz6H?B0)JOzVkrnel0S!Pgo_&}6sPa z`wO2@^cV>7IYpU4hA}r$uJa;=TR4u-8>3T5f3OB(EX6)t)Sfqv;t&S5dE+T6bjFpU zceDuFx4<-J;!sM6H(sN+w==HM zznJltieve`9AOw4tD74}q21?1JOnV6WRj$NvZuf^yw%x0OKYBe4NRcgu6& zh_L_xilUwK+IjkWy$qxJdp;E{XajJxrX-i)bb2&{+Ol`JW~Op z%j;?rGM1v;)r(l|uob46F&~Ag9%tPisxtcx>B)5`6mR=tTx2iwz0RlbB3uzbJXMGv zjr90tI8S@Sh80=u#BHUeVO!>_tOg{Y{maPF@~|GqTb~6me~-MZro5lFKmOTN1q2<4P))xKeNOqXalmB!m2|3V`P-U zVZd$?RN2$T8VUJa&%wG_2O-Q-ui&zoX&UA7y;g5 z+1$u=W>A3Fb)(rm_lJ#UQOmsT`E52^CjXJy*3Yz8`KQ?DCdMAxI>gVmmlO&rgH?V#%7KgqT48e85@vgi6%!Ft?JLdTe6QLVJyQ%>HUhP$4*az#)L4DIHPVYxzI3hg(mZb}?L@hk4ED6eRIRrfkGT|6hVC z1{H%|nJERk=3UrgMi+g6ZGrm1x>jv0{1#7M1$Epjv(@ZWyr>)0r)T$`7wlp|ZISvx zzhC_P?H?z)-odSAv4T>_S0@LxwKMkzWyAYJZ_ievlwL!=2`G%QU@Fd(2|q?cHXCX+3m@d9~g$3z@by^nMGT{tw+@-jzLO zu($awGuRB&){_z^y3f3AR+6hJ&BB73g@rZ?3vU)yq(xYrXTxHehs8b{ z7WZsee3t(#zuERoD|hkR=EM+h!n--R=AyZA(muNnF+gVcZ{%ycE<{bgHTrC zl}!+~)$SN!f_BFWJJBvo*6upOL9`1~wL4ZQcXu#zM~#W=HSJSJxJkQXgqyWHRw!2p zRJp~mSBoRcaRoxkC;X3g#|XdC?pUF^ZXi2I9Cz?jJIE(42RmP)3rlKujIfk;#|k6x zQ<;lHE*+@o;^=^%#1cV}u`ScdYOu{3Nzdxz1{J#1O|H z_(^o3+_Qo^M)0ot)Yj=!ruXe`@-=Yv2aY20&doG!kz4 zqy4MvW$JFZ4vPNhhaW-;N-Ae!1W;Z(OCsqg{BS}hh*i!6=3}&h<2n2g{Y~I4?c9h! z>PnlDAlKLB0ssQQ5BcNo7>e|xE}cmEn}HvuaR?^oDC%!6{=bYLE@x?j&M8Hix=Y{{ z+PMYzK|5u;)df_e`|A(O&|S)KQk9{*${%6X)oFiKhKH$3I(h@TOLF;@Z}(CECizG@ zl7#%pb>e3qPeuwTn}bb}0y0HO4N2k3iP2q3n4oI6dpF<`Mg~~rf+?WK3kxCt>H2P2C{NLN@hu+#oMeqJ^^ndq&@8A6^@tNm3L{Jy8 z|NrHA_+j+_ndiS*jtD4k7;@5p#w^eq*GV=`ey|EY&fWU4Sunu+>bzMb_slsn%=F$p zXBP49oj2<#qu1m!b9D97I0wnbh262~X(I;=>NkEsdOv)>ZE(6FH>{p8g)Z=}erCp* zALo|6V194OqkIJAr@wm!VM7eBQxN+Ckpm|I;3n7a{k} z%UHc2_r~XDegE9rUz@K6gpBJqFuGR1G2;hhAA}vn348dpIR$Q=Dt+Q+UH+rz=YHhV@Dut z^6jAE|SF2m= z8Si>UYe(+dN>-Y#8#dJX-aAv#Dw5kZ)%rTzd-{$U`S3KjqBru6SunR=rd2-F8RHIcQ%9!v zOCFh?k~(DUXr*#{&ayny>;J$knR{opb;Hj6@&zlyDmVroK*Z*Z9x+Cq8yTDI=60NK zt+Y%1Kei$_;6HoYvmG z-Y*hrZac5!%Xo?<&TICvRmt4$r3y-Wiv*RueSo*{Wy{aI_OeypOz}{sm8|=zUM&xi z_Io`cO+RlM;D75g(-`V)^^j5dVYX4zJ1@?}&+*Ql_W(|_8*bGg_KZbd+oi}F91Z#> zEVYc&-pZv`WI)6U%jji!SC?8vbH7+>mAB20J#&Rs%=g73JuVzA_`4_cUr*?uM|z%w zFZP6%LwDYv_}6|y$5G3)p^#C)GTM7@tgtqlb-b=Ct?>ox)HnL|OBtJ<+^=8t+I4Hy zs_9)>X_dEPYI*i5Yj*DPRaOBjxIRw(5Z#LLcCJBVY2dY8Yc(|+=FVAbg$yb2%HJ4H zpTU4d?j#R+TZ8QJzQzA&?{(y6atE199wl#*_sM)1t0no8jf;bbP6LoOvZ2z{u!Jv89fl-d$J9H@AY{F^LoYkO5PmTXVijr*NqcgV_QH*z>RnOs1wC3le@kQd1S9M>e>Qe-vxe6<*w($I-aCdZNM z$$jKU^~tv61ae-0T)#yDR@1P9JWQS^Z<2qK`EYcWcxA};==2Jb5o8Ur3E6?{O%5kB$sBSixsN5Pk$mB@PJ zvt$=?5b2UL$R*@1@*H`M{E-X|)%iW8*aFw>X=q9&kkiSR$+hGb@+0z+_g0wQ)Yk*2 zAF@M+ljF!a zB8QRBliB1laufMBd6K-Mi1GGE8vY@}!*v15k+sMcWEXNUd6m3NS_O6df@B0)gKR=} z5XyMln}*?JCYeJnB{z_J$aCa3$4J4o<4o@JMbWuaZBKMT_Zh70H@p zA2N-cSd8QC92%C98_8VqL-IU%jl4@*#dU@S$q2Fr*@Wys_9ln>=*T2<$T!G+} zd6%?GFk>=;tU)#*JCMD}G}1STj+x|6@;&l2`6c-y`G71{QWqeKY(TaqyOSy8SaOD@ z&sajkdU7jyfc%KOOnyiHK?au61t>;VB5RUO$&O@SGF=h@Gd$d}0VWO2w8%xOx7n`l3mF`KOR_6D zh#W&sCl`ULSFfdE2f3d-PF^H$lE0DiL2^0B79k_aT4Xaaf$UFakh3eYSFfkxJ@PjB zUoxbU&Zsh3pKM8XB?psZ$tmPKas|1W++WG36FyGEP4YL=zcROwEKk-Uyoc@Gbc}8SsoQfJ2riYm?2%PGo;_BsqngN3I|@lfM0Q949Z5H%b2} z)&LnvHX{?re&k5fM=l^&lW&p-HGRe>G<-?^L>8=~GcHF)k;&v}avHgiTtjXr_mRiQ z3*-$&^#9*z2&k$vEI^hatC6u}d$KnN=m&WED{L{~k2VB$tq{k~_)w$kXJHG|VJ- zk)M%2k^#{=qe5gPS&fV(+mT6RDmj6iO}^)&<23mt`6HRHmd>yw8AY}wlgMFYCOL;( zPHrOilP5^uWjbz=e~~3?>x`qwByt#;NzNgclbgu>V&v5*c1k zryozIlZ%DY|JTy6n>4* zKPSHE%GliqzMZ^Mv)B_(FNMlkVFn6Gs!vR za&i;7pFBZcCU22{ks(c405XbfD3mVHmWCv97@0}VA(xYz$o=FA@-lgg{EG~UV*$u0 zvLWb5=Wk0x5;@F!t-M{ycarjR@)jA=g6WY@lQqdEWP37+97>KOXOJ(FYshVyNyY&h zPLLPL8{|FGiq{1yNR}omk+sOiWP9(m3g{V&DA$m0lBc{Y73^Z=f}ho?7AGr_^~jdq zQx)xEZKhCWlOFjx`4)MEv|8$9i;)${hTi0g_Q6goT50di=1t6oyhGbhZi5x~|l5@!A zT8M%Rciwy0q!xbT)CYzA$$s}?pIgXqGs^jsC zG^`=Fkq5{Vsf# zm5e3ZlfB6_auPY0-0F?3W|#Hdq5Ovo>#fr-Lslo7kR8dsWI8#8oKLPIw~_CXACp%# z+ZsR8@HZLOhXo+3lTFBuWM49!T;uhrZucvZ)K^DOB`1*Cx#z3f_3`nG{@VWr`77x^ zK-(R%0$G=Qmh4InCdZO9$(P92$+yW9n%)aF?M@{|4%C@VA?J}Ry&=j8XAJ|o{?W=u9C+mS=b@#JjMBR7z_T8W1GWGk{eIfNWf&L%gIx#Usu2KgHqFhplql&nX#6w1ijjfNC* z965_zPwpm{!9jp(8)Vw1@C%Ydt`$Ll%eU`yA)Z4Y(%yrdy#40 zyn1%OXDW`=(dv@%WEXN6`Mj6EzFo}s7UdE0Ecp#-XXxY#laXX?vIW_hOeV*WS>$5! zRdSc6&p1rOS@Ik5E@_Wq0mw+QHraygOeT|K$SiU(`6{_f5&ict4QI)3$h)LHngt*u z$=YNKvNM@Xjv=$i#pJ8xZlUzw<1}0(Z<4=}0b_IlGRaxwDsrr={c}ih9b|(juW5{Xb0&)|%mpn>-M%v?a`i01HWYck+8Fi$g51B^JA(xRG z$-U%9&XwvAISfb z?I-GV2a;pRS>(%#=q>BSfrnIICpQTz7{;3_fMM*XK1h9n`V;EQ)OV=w3+18LNt%8_ zq!%ni=O{v5LMXkZJPp+uprH^6G$EVQzZLxxsk>7Tq#i;&ntBp-wh-yfB^T2FB~bO2 zH8i{?M1i(b@2CEZ{ErX`-5~!IV#{P9aIwqxfrZ7$Qe+(=(rr$5Ci_m7-hv1N88AhN z1jmw@3^;>2hk7yf1|i~aCb!f7u&}aWTqM5{BHi26f0KbzJ!xGsjrj2lK$L~ z5FyeFBg@cUg}MeANBZLF=tinDDM$Z3t%wQKgH><+Q&_?xg)Nd7ivV|C{7L zv=^PK((@T*#eobelhI_H4q$X5lgTvtk0s{`QQ$@7DsmmUS%~y^lZRJ8*BQ1$<_G+Y%rc+Hl)A;cE{M17aEXTXk{DJX=0 zS+X+Ol>V)$lY~gOFFA%BKSTOIJhEt*O)e86gYDG2$&biS$ghMbzz@_vlYujJhWW@M zLWFyYtVVnEOlgfMKua3hlHJH8GEImAWl_&2SCQ+;%|c|foBV+Gx4I0JW6?@9dJTY41$kTZjbulcVWBS%~g6oBCDqO(DYX zB6Ec(;8F6l(1!r$7~nej9ckqt07@QCmL@Bcb;vlf6WNa(PL3zD$R*@DQ1$<9H0&oo zA}^8G$)CvwWXU_MiI{*OqW>cLuc3WC>3f@w zgXA$GGW?YMiuP;df60Hypm{ocK{7&!0@WhpXzwCK4fi02X@8$FfdQtGa~WVExlV`# zx6}VWLhREYh3Ixc^R+G_#2cT_P}ikyNZnG1qh>qm?n<%r9MJ^ ziTVb4mz0;_rC|BVQe%XPAJF!-ZZ3=A-R&=PaY-DkzbQPlIB8Ppps-I zvJTk{RQ4-^n72bjIb#>SQCbHQ8;E*-=&5AR0!IQ^*&{ zjpQEkFj*xSulAu)&CCa4dcDNU-v(FJgD?U}Qz$?d5n@pnEG}kPRq;-fur@}1v7<>~ zMJ?qYCwBPDTl&(pLIP#T#F8-P|l%!foH!*-&vA%m%hQM zAQ{KfW3*`4C(u5b_T{3H$T9L1{m;-}7O|H$^t0Hp%L4EstgxsM@ghiBlU2g?2`HvL zQt7cph=T0MeYU;bv|R8V+2@#O-SZ}ouq%1HN7yxk2^f0te7me z-d?qIyI61rrR#MNnN2y@8oeP5^@c>-g_Xa@1;E8J(U3|YvD-fb6(>NyH&8P hfFm;0o0oxtMo^abwj!{1E(04b%RowyF5Uy!{tw=&cf|kz diff --git a/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o b/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o index 207788c7a0276d472c84a483f303918c83442234..7458699dc1eaac88a64d067b6bc0680eccb453a2 100644 GIT binary patch delta 33316 zcmY(McVJY-_Q&tNdpENQ8?p;KBqY1pO?C+>3ke~R0D&YBk^rHH5^4%vN+=?rxCjUe zh{%8-AVpD8Q9wXY5wIZ$A~sM#M8)<*<@xOO_dPQ=zW4is<$k8mnKNhVy}9&=Yt!m~iPneZA15Jo~%rJ;`CFy@l9n4FBh;g$UZZTXc(UwDok|HU&>3&GLW3#fX>8 zVv7>(L*>)mGUG#r*ciZGfdC1<=r){MUx$PjJa=|rWq{uyGpn?$tAW=3LayRlBaDv z(z3@MjfP888S~8ncx-l&Jm;E}QS7@&wncO4IU8m1wBQsq_5@|oLOyoQ7OZKj$lp0A zOH}OqJa{Bi3bAe5;L$H1-EHxhHb_Uh)23^h!yY@Y5B`giCCWuwj@TLGIc2C!$ab`#QaxCFTz?~E$hV+WMN#Vr$P?a;Ighbp8Cz7CJfG(H!P@sw%o@G?9m zyh+j5i+7qXY~!DxX*}UxD&`#wk1co6_R`~rBG#4FKRg@`PbV0f z7A0(&HU)z4WW>fzn670seH0ExP-Cu4)F^HiQZ<4m`x=F9BnK<)@LzJW>tea9Bsdkq z$m+BQvE5(d$IR-?cC~<0XO#r9N+;Z3* z;9_bV!8hsZCWsDgFzi2!e9Wao%-?sIMHsA-wQyFlNf*5c<@ zF^7l7#DyROJv}FGUO`7Kz1>`0wc&Q8nx3mjXFn%{+AA{HDh|q1WMd1U-02-MWjvED zM;_@N71`N0;wPRFnVJT-&IvJ;vXf1P2BddMmz2)t4g(byNGf2v$AP+1e>H;h*x+1H zk)m5z%4AS6rECi>(%FJ8z!HVG>FhK#Ila5W#X7qi{W-md!sbhKcAO%YQc||yQk}IG z`&#&ns3dW&g;&2peAB|GXNxBB2VG_f!cEXWl;!dALUArWsF#W#;@4y+=fi7`u0-qQ zGUSc=3r(o30e&5ZA$_hyTX4J1_lo@qc}7>S_$r|xBEv5JC)MZ2BJ2{KEQAr9%6t7U zPUFwO2L0nZoj=h2e{hCp*0le6Ht=D-|M8s3N#W9$>X)6A@EqO-jhueFK1;mUvRRXN zARx_1ze7)ezP9Yz`2+Oa^fh{XENt8TO`#Z7nzqJBU#s);)buBGaztwD~ z$>04rDa-}^qHLNUO#T9l!9V!@67-!e%i`wDH;I$2e~!3r^MwDv1<#??36sI?A|fir?G_G}IOQk2Gd z*qR}rP!1$y1QXbPj3uqpSIIQJj0|7vj1p<_0_W>m#*fTH8 z+wOy^*@AcIe6;x4=hqjD_+)=dKREhwr6g>@Ejll#2j|I(P=`sHFNP(jrWB^aHQ&~N z@x>P0t@HaRo31u$S6gte&c6|xlKt-6v*6mpa(!9nKZ@6q{f4Wz_&Pb+aE=#E{K-bR zNMzx^j4q;&Ke@IKhArO!TVhK}XPv<_hk*xKxoT~pc){G%`Y=GY2ldM6$Ho<#6mTX)H496UmNldVGXIS0QJz0o({_9<+$ zE%=UuA0i1f@+Aka5l2$|?kf<0Z=ofpKOFp1aV^E4+XVXTTV$iYfOd}N(dZ1m+ic@x z+N+}ZSj@G2OD+F3(R_HJ=$e|W4-}(Pvm<-^!*jKjVNplXugQ*)#!gcnr{@h1pN^mw$Asa z73+=|{&08jTeh!cDr;i6)&l&#Efrl8trWvwgGKXwU^7upTX16xf1h%>*w_^Dcf~a0C#frbYRi)W_QpW@!l9zbyCkQ7+sdTt znHbG5YvMG`OQuja%teUpGaZx&4cy5$z@BJPCxEV0%r2uiTZf2IEy#uDaCNo+B@<~; z#O7b&=XX@Yj2dh3fG4*W)6Sh~1c{1`gME3?L<*xD*jZsqYZbYU#*UA@ z4BbFF>}Tk1d{Z@rFtweuh{2Tuq@$sxF9ODzH zK$K$po}iYB5bz8FjfF^@ZN{_t6E&@6n+eLiYiw1%rnQ+&0ccjfNE}Z~=+$~4%GzcI zqbO|}lplmZs%j1y&ayF!8Zvy491u{`yU^l8hJS+;VsD2vOZ6rqTolEk)vZMk~GbO(en}v|M&DHpyuEoZn znzFLWPs$fVGcsKFqq{CBRC7m-MfDSRXQcZ^w}xYP71Csx zFc=HU6gk*Y@lHmjPe!Y3jJBi>A^IxP*=3QGnHuSj)^jYF$YjV#jUl5juUasgp@9k=Ni zevF{O#zUVMJkXft$N=a;MJ7891z50Ck)8c#1n8k1vL8fgQJ!Q?n~szNx2Ch(gd@ur z*@!kaXRcy5Bk7rUsrE-}aTIFiYCnQUJ&PZETNufikF(dIf-`q_h70sFB?ekD^NEW{ z+|>Q(FDY4Q=$U(zLo#)sJ+K)w_p0y?Rt161+^3Yo$xIA6Gb2xRN9n0;qbC9PD^>Mq z&B!?^q-j<9%oRKxZQKyn`)-i=@*80;8rtYPC3^Vk&cL=7=JDCxfY}yS$;nYej;^wq z!@a0)L#}=T?SR!2PnlN?Zm-Y5aDstR=QS{k4S9N-`-soz{0C7Q&W`Bl9Sw#0G3ok; z&hwgpyXk6dUu5u!lxmU1OAS5&?b=Xc@f`-=029*CL+=T}*@CMK&Srpn>MOSrW2W>o ztWZOluEto*lwN{l8!B~@hAnu&i15cSUN`j9H^>M_41P02(=f;iaNOX<(7=Yl`r-R2 z!byWqj{;Zer7(l2hQY^T&f73le|r=0IRoPhHEUFN^pky~HEq>G5Bs*WrY+8HhX0f_fc=|7woy4$ zvGr7;wkqCm_EvchV7Brc#WtX67v>}csW3I{TNwX^d7UMVW9=wp$AOY2vB!xDZ;~{X z>0xoDZK5lW$G*xw=hfF4JK_#Isu2ZJZXFF8Hq zdO{KJD53c=t+rkemF-HgD8Hv&LaUWEu+b%6IYTL#+zUdYA*8NW(@LiFmt?X>#o2Zl zdZG9QvDS#LxyjMT>M@9vB(tevTyBQ`xmcZBIOH%Cp(KMg;?VS3R2@uSH|R)3$w;;p z2DoI@MOh_{)u4bSqZ?Z;DGM}4jm=?pH=IkxD#~G6SK)6zvUm=rlFpJPY-?9|E>&ZX zCI`Ke+Z%_hc~~BmEZZbYj3Mg;a-TaC7N+D*_PKbreOAWzNV!Mi8Mw#(f#M8uV?v|F z`p|-dnwc>1hWRb|^=K!W<|Ri=m<~^mn^^+J;vTpB3Lg?n$_UWH#-U*L4WL^&#SJ>x zJ?WqbP5Ehnj=CMrS)C}6#c{K1wH`~-WH?O=?!rS1q;4)}p<^iGatDbbbZ-s68!)NZ9Vy$lSF&pOvJ-x!@ivkaG;E zlM=Ma?nPf*-kCyDalNfX(+;^~WU3|qFV*f=stAGzJ*c>HG(U`(p5^7LAQk^FO0UK! z$6ScgTjl6rzl*IMLJ7m5E6WEe^NsrafMguYhqIT&2OUCAS*W(XA?;8X5z{dcUzCr~ zeJ3MO=tVmohfubm_eDv^*7_AOxnqX@t`PVw6wi0`b-h%InRin|sf3faz-Z)iS?J<_ zRRi4?dU)jeiASha|fts?kMb zwCwAaq?#BymI%$AhmI0z&g8VHx#NFTvw1X4h-ozYWjLnyF^xib1f8~dlXe&=p(k+- zH;wy;Tb4~s)dD$m$ZS)IhQIy`$Jds*Jo25MqGF=e*(xZWXNnR|1-4(`EXW8Kz~XwQtEL;y zR#t!-PK~6(jbgK5!aTE7t!mhUmLjcFR_~odG_6BZ8p%mXX*$>;PE7|f5xs!EG1hq# z3g-Q>3GL=TjK}X_xSg&f)*fx;@-|AkUzXV1sZ(?x3_l)M89O6B?3AScE`IG4h))}@ zX^UKa;~MH4G*`dgZB$mLL{8^oy{(wpxkaQIHQwsRUiu!)QX@H7Il6u$IoYG=ZLSSJ zq36+5VhscBC_wwjO;ECAp3g~@SwttLADZ8E7#Ksw*=Y7LBK-_w+C4S!;0&$ z!ks}@1Y_uWhUAVZK#;wSW^f%L#lv1nkbMLz;W{?Fr!3~)AnOi|a-CJ7-wCoyRO&aa zQis_4RE}$tREk*U^8o}?Q*f~1wAe+HO>vaAiNwu9$1vG=yUMLB)~wfI>8GQ{%_k#^`^J!h`E*_{Ms@9#_6qbNfZXM-X83ceH0g2TIE;~B zs?Ke)z2bD&&K;^ka_LVy3sGhGnLtXHkSz^CLc2yoK+CFx+{Q6#o#@=Hqn;^db_?k1 z#M*8J-KX}_wBlwXS+P^onvFhc(j)n@0C%Py4sE!?*DJ$+`q2VBFsqJB}i>uwk`kTVtV`Sb26mnkN5H@?Dro|0y zl+)V~Z`?4YTMow18{>v6Wppx@FShqctbaNkj-ys}qB1A2K_#Hk`z3ia{;wGHXiNfqt6eezB9P|!5^X#PXl_t5e(Bg4Z zcgTKG#U{2D6{YFEE)aNJgDT%RHU~+^%~Ujry(sP~4d@SxCrjfayOF&6xS>Ww2mcbo zi2DUY4X#c;4g-?=MdMG%4|3-hhXP;vXXX%s=-n?HYFta;dp*EcjQ+B5z5M-dz!S#v z5(9h;EP?w~BfUXZi!+#9_empKMK0!#i@rU5hVBP}`6H3x%+_Y(0+>^BTPjk0g^q{zXO2?hDAH_YTr0HV$G-NKuY;FhP2=mR zACQ5aoKFLGve3orV7Gjo_0!VV!>Q1|F4D+D$#`i!uu!4+r94M}U1U^*M{a?s@%7M8 zNwq298nnSzs;hoi!5>1|ePwd>YXmDf!&vF-r*D%|t>Rsvx4!-s4(DYsHok#YhNJj( zvA4pfH;A(pJ|nxO_@*K&ryop`Z-^D*7XE0Le~{)6d^gQ3he~f+p7Gm6MK8a;Tuka! z0ii%w%fS9SWNAmtZxu2d#6Qaz#LR%)w9>o zYT-hqQySZWQ8nDPQ4MkmLERKNSO#V};qIzYo$O8wlHpRiOh6WD`XG>X%;jMx&}iXu zWfv3JEHr<3*sKVJ46%n0BRuwgk<*7KKL$Ms*Z(DbirE`(khPau%35_3^?lZ4e2-4% zu={4{oCY6XgKmvJ{BSC8rk)Aof#H#_6W+>DEq&W89WLZAiiv%FmE)7lgEC6e#xn^)c2l|3E<2{=Ld`b zhjIFdW5Jq!$@*py>F0OL!@%b(O~)Z)7qO>bcI{E>m@nycv}y|;*ZKW0lD@P0d9)Vx zp>)25gU{)oOU6ExT&2CM(<;pte9z#&LQ=l-7GE;Bn_B&Sy)$$|c9SilsDCK2qz6Vt z)3;A&UqJljmNC_s&c(w1iNn?-k@CGs|B{W*zJ?N(?~8-MHG);_8AL6AYU@`-<5)F% zStCu7J6`4c)wPPLEEh#DKR|Yx4prIYj^f+?-if5M<%g8(VV#{w1|DAfB?UU7r*K$~ z@@HtXRo9s<__ChT9yM!piIOfoM*P>sE?tIJ{MW^lE}O;70l|@flKXR%nl1Q>&W@lt z%8y)>1v;rSjJR6)(Q{IgXCMhoZpx31nN5Mu>2Y;8PSDDa54%SAj?PkG3(H@yDr2xb z@!bHQ>o3e0%3r=4U5EAv*%9F#=+nKTGk%{G!v}US%9F(11M{YQ)*9j7+95MuZDW(% zz_-bU*n(?p>;&4T{2i6_IvX2+F|7REyY1w=(Z*V#bCsW`T|{iB+E`QQX!!*d_=t_o zgw-p5PvLPJZVI&-SN$lRb|b7A;V=(7_%QIfL^Jt(%xUI6Zj;OmETRBQjtiTiP46 zgyd!fiy12tdj==!cZ=5sCq)LMV;4Q~y$o2T8Rk!DM(-e09H)-IAh+hU7%G7=@%SdX#1JW)>QHxU}1pYlL{PY(AhJlcf4vSaIl48t$8*HW3qO_UVza{H=OG

+`6WOrHc|5Zf-)-?l*vn{RUYy$>#J$@igR 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 delta 33281 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 a^N-JA8W@>jzV#e)%V}f0fzPu~8vYAwfw7bT diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o b/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o index deb059667ac266b0ddf1ae301a9ff47cf3bc02c3..75078d5c3b4e60f1639129fbebb6cfee0ce370d6 100644 GIT binary patch delta 59075 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

Jp!faSx1;TVI&3qKNK65$1x0 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 diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe_src.o b/patches/kdrivers/src/wanrouter/af_wanpipe_src.o index a48213bcce9cbdeab576321f8f7c10319358fd59..e9d5fb331565662e260ca8fde353fa0d8ac88b14 100644 GIT binary patch delta 59171 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 delta 59039 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 diff --git a/patches/kdrivers/src/wanrouter/waniface.o b/patches/kdrivers/src/wanrouter/waniface.o index cff3e31ec02bbb18495f3bedcea79d59eede2e8f..b7e76b4146b2fdbb35881b8477069f156266cdc7 100644 GIT binary patch delta 57239 zcmY(M349bq_Q(60sY#e2lgU&VlF2Y(CXhe^AqgQsLJk51NFYEENH_w75U!9wI0c4F zK?MODgwvw zx9g>&iFqRJU$P?xx=Mc;#4Cz0KULCz-FR1FfqrTBds2mP)_5NE?8lKWSa@`-N7H z-(0stw&b39$Dr}`<`P# zw%FEjV63WW3jJrO^!slc{VK|5>58IG?V%{9`JA(><|{G(=}d}J5NojL-l?X`)h<#q zN>Of0M;gU7y+Tpiwb_r$=shipqA}M);}GJc5LZJdT)JMMNXG&cU~{FnK}cJXbHPMh zdM;9=EZvn@g^)NAx!aFRPB~pM!*CfdE~|2J+3tl11mAa}% z;?nmv9Ou6F*TU;?i}qqQu7?r5sbxgZTK~l%QZCE`4`Xm)>&V zvi%{t{1t+WPdG-G524QZ#8>FD|9o5~-9eWhn86qxSv(y9!S+<-NQ^^#xCdQ+vmBQx z`Elj7xc5%hjH!5A) zK7;@*q%d!$qI8Lwhsw2(!3r1smmI92;J@T#rDnigob@pVCB64!$Q^qHKSp{V7Dzx) zA6W$2wX2%&ZA98z(BC)BE$$iWEb~9^#H2=ay7Oq#IxQ4t?pn}Il2X|@Gdngl<}?PV z^SJ#YMK1f7IWsmj>8-8^8!y93Vy4YkI@d}lWdn=N$70)${B0sqOqPK|V(O7%iiC2u zWEP?<8WuAhQB!49CA-CrD2qla_DyJPG4wsyxt{%ECU`nl7Oqm1eVu2rpV61jvwpxY zNocwzWjD9ECrW&PX9q+xcx1>}>I$_BOtwU?C6 zu0ZAcCrHX<8d0L89QGzP#xE(4U4U2VpCl=t-5&%6Bo(oKL>*pG;AgZ@DRU+RgEF#= z?KPkBcG4#IGB0_P+=B`grR&(fFirbi_*rAN;bAQ)&FsPXpbH%oB`s^AN`~Y8{tw82m%)EU-g_4#r$5K!c)uV@2s?0V3SS)ds${v8} zr_I45+7O9bRMv4a zuw3F@D!bPStRNBSAyZ`^n)k)`R}Yz=$2YrU$`Mtsek3~K=f&pqb|H1Yc}Kfdg>jT? zzA6X9$6qB`wOHuqBI5$}MW`h7hQGKHu?q$2p?xavGQ=F}%U16)BfjPWk#_ab(` z?HZMur-f$oEsZze9R3lemg}*N{8lrgy}#!9m(o=V%SQkM98 zq2~XB05@xCcd0xnh?rMZ3WVMBA=LKQtg3uGkYwr!gVaIh(1fJO{iF|Pthg%v{lpt^ zEN>wFct`zAw7Hf)R|Pz)9znT!=wpME3rTxVWY$BU8GL;%_mFNTR- zkN?i#4TUs5AE@N>_0W$7?^$^RUp0755%|1%OjLNy;3-4E7pw|a+W6gOr^L*51#rE2 zsfq0N8bwLTc4mfpLu#?X~Hv?^T**-V_2bIMw^zwJ$rULO6`gnSm8_>_0 z{{{^5H3qPqey?a`n9svHE8t7ecZr6ib0^ZnwyON)WjF8+6|NSXWySASxk}~bh!&ICCw`5EL7=B-qoH=t z&1*^C$dJwm>!mkoRL5bJS5r$1bQ*F!bX4WNNn*u9%zEg!%KJe>10@!pPZjr zd^XllfeNb=D>Yt?gn?oD-b5;3t;Scy-@xlNejF>)z;G-5290kZJ!$358vj#0xKdAO zPx-fw()c7ehQLTG!)}fL1aEVl_i4O<)S$|$@PNh(JKn&DG=7D8JX&ZCB&hK_%*h=( zB*(x<1;*(Q3b~%q_%l>(E1%VP$lTwdLnLM)LaX&BM5>Q9-kGeal|Msg!#D61jVHp- z1Zwnv5Y|^3{{>PAjMu+_wdtYnG(Lrd(aJw+e4FhCzN#h0=YS_%*MLaqn#QML1`ABo zYhi7e|8)K+W~)H0{{289V4Z)4p$bg4c)iZkqrg*iIe%@?d3Wk*ouze~bzYhco~F}0 z3;}}|gJ)Xt2XwyKbDbl4=#b8nNX=*KkHBOgK%Kvap$RnV`EVUjLEVeRVxUP6i$0%p z@Jbrcd3vVcmmT~v=8iy%o-g>6gRcsJ7wRQ~PdoTr;zfFy;4==sFBiN-|2wKf{bwD# zdEE5?J@lc2yC#8`iUe@>4!)P#ce7qE1oV}IcMgJ=TMBc{!A(+#75XVLh%2M`V$#@% zK2cP-Hj1yw1FzJ{@xsib_}VexReIfEC4ztrQG7jlwzXD*%~AaC1HiZF$cFf>QT)-B z;PqDgjwt?YBltGGNmQ^qiqE7Gyj|}H!Nbm@xQA?RqrObUgMS$hzSC;(fhfM4{On!2 zrlDgPfhazNDl`#5d^n1ijRtSiZx?EHG>Ugz0^VWq@hGlz0PoiKiwd8K;v609vvA%6`qaa<5LmvvK}w^Toiwayv%8R zQv$_*7{&V_BJie8_eq$Kqj*Z!8~92TcaOb+zl-9jH}cge-eVQw&sh0aM)QLc!Efsk zS>XC;{%r*U-qF7h6>N^?$)tnl^^T%JTcdeD%-4Ynx*;00BbrxG11`3@+GzeDtR?WF z#rvZ9NfP-bJyqmC5Y4;L5PfR7!9&sfAJD$Q-`nUpBEivUe$IR;)IIfk^61~{MI!VR znsF2OU;047r=ziWs>Rs)_n8UdV0{3t+rc>d0f|`rt70Nln63H0WFP}gka1t&rzZvt zcPSeGb`nz5Y8<1BMUxUo7ms0qu9yPWYX^l1xHnK%g z+C&ji5kZ>vTz_DCX%pQAVX+M&Sz9)07=mJ2leyZ%6x+B*Pzus5BihS~p*qogAczWb z4aG%ta6Y9tEK-Ci#T0BfP>~`@6viMra~majlajQJWffBurL7>*8d_es0u2=QG*Y^6ZnkmVFv85X9U*qR2^x5b(mr*I* znq&gVht$=$X)K%EOHpnbJ5nrFAcWFdLdxe_h6yI*Pe3~Rq=ZtmY7RCaaN|kqwooz+ zE48;7Y8eX2m7~F8FhPXElaPn*!5)CDLMd_?=2Toin7?%D9f=>SD9%up82?ZbCqu3~Qx*0V>dfgT7n%n1Vvfq`{(@|>61x@o(z9Lcym`KJTHbTx6eT-$ zj*yO@ohkx(r2NC|FpMTUPWC)iaXpI?vb|KTtBud>lbRG64Gl_P+L66BOHr1F9!3oH zv;xDuG-bc&gTa1>UM%fIw~SiI&f50}b(X|fIt0EnwX3My!G0SAN}KGbly24wQe4_a zHpR~x=YzV+GK1`)RiO0!uxljk$ka?=Mr*5mMdsJ3$rH9jLo`eKvPa-3mgdVlI)!~v z4JweNvU@O?OZ!RE*m$g(mljIWS=S6ui7eD$u}eV%B{|q9=B%`iooo#1y>zIoLEO?( z?}s4K(u&p^IyIWd(vl__;>rL!dIET5Wf?c%^@ zet}-B!2IJ_xZueHpPDWLl$8SDUxTzWu~ zjh&eRIw-|$SL|MBnmd5^Hi`y%)-Wkg}gFV=#NT*Rnig$|QXo(2V+_m~U_ zkPk?K3eGz!(>quqL_P0ush>`!j08PV5~Q-+?DoZ=W71f>5yeB{-P07MN}YE*PwK8H z&FSid?V?`(UKe17dR(BFzX}~~?q*>QA6EwKZef+UM`+GeWj!tYC-l5IOMSJ1idxL4 z3z{>2+R3*lflIn zV>v$zlT~wnbpVoKt)%gDE5QTQd-f1x^}QIKY#yk}i5#o%rIW$sD)k!oD;htN4<4pI zDAJ$M_|p(T^GGZHq!!|#8U&0|Pu)uyPHDUsRJyrJErkW6wcsh{>GbxIpRn@Yu-wa* zz)3FWVO5BYJpc<^9uF--&kZ&Pl`i*5auXd7>mQ zy9&!%?w90a7jOr?JV}zDRZIf~rba|DK^A~bEbp*H5WEu{#qyv`n#!KRI4rmB{nOb! z6F?pFMAI@^9U8nmv`OU4VZJe-6d9Mtny8_j9u{%=tRLjDyz@yxMQr-&fq zY<=I>8LT$j+?<))J6VUB7ty_)7V}JJiR!Jj~xuZvi$U+Wmrsq_&ulxwKqhy{; z8fIfK36;#3l!_MJj}~bLHNZ|~--mg~T@qkRF{_j;m9;5s4m70XW=RH{y#lmM7U5t6 zpl&708%1SK6g4^piR~YtEE~jRFX_YzFnA@M_lx0D*d}URDm`Z+mz@NQD@l_C$3F$d zjD<0lmDI3qV-Yp}q8L|&9fNk1Ot9L`M&Y7lqFkD#Gu9h4Nm3@;lQ$4pdoOh?l*4|; z?McaGDd9Y}V-;wMlyJV3=~UUTBF4?Hv%*DZ24i(ovW7L0pw`MIhaxnk?i$&J7L_KPM!4%Rx-lviGErR5z`#a%42V`UzM;71 zVGpCc{U~k%ggS}`MO-v~?X&Q6r5on>(wkWf`ck^=7i1wV`5Tm~bh%VJgPmChTEQtJ z7Hn0>Q5uQR{VyDoV!s99&JrqRb7Gh7#L370R=&7aN|3)a&xL zSgCTb3R-7v>l-YLqSy7Iq}1Lia8K*{Qd@{VHJ`{ynI!5c{+~KZtU6@+{#JS=_8Ao8 zT{lQJtL%TW3~tTR1`4olNUOSfXPdb_L%s~?`MMEuYDM>cL^+OiW7$8==APkF(Zp^; zFqwq&T97X17}^&uZiCAL5=5s-^IDX3rMbuy{wIudUBwK#yu*&m(bS~y>MZko&p>2_ zTTxb)MzN2mwlvuUh56uM)^(9&unv&Yx~{Fw8$u!W>I?zV5 zG?G7B4|G~+$c+=1h1f@dss*OCwb;pDg%$?f7P|R^4Zv6ny?kjS(5p$6^6`{JAh*!Z zKc|X)8toa;^M(e@A%XT5hWTRiVs7eqs?S~6p2eYWg$Z(5qA=R6DNK~g2s=sWiUoc% z#N%aRMelXoXkOkZx+$cocJ*|OYILheUN9&1N{oCCKj3ZCBb`!s+38x4vp|rK{Tu$h zmHcd5_J1j;*eT1ne7J2d*6I)?AJtmveP}DMx(H3DO4sxOjg}VfV9!w8OX3xRcthDnm0-s%igX6HJukJ$Frw; zfh-?i%L=hp;PWqwxH?5MNbdfz&@)vtdO;la+4%W4bkp5)VlQ^jR7J^cE5(54(UUgh7%itTa~Vu;#S61#57H9QeuZu z2sxn57_`{Rb1G3PqnRgmM74-ZQyg^hX1Zd2**ht61^U0z6MF~SjBdwnl&w_QEG$-H z@04V)siprV2m4^mf62+7N(62H8758|@PPxgKd-yB%AlQ)*at{=u;@r;B%jzv%0%qi zWOi;L_5x!cCCMQ=#8TlxVjs6shuGiH`q(F^vsj{p*h+ZtSh29jk~qZ9!N0^Frxs$j zFvLEGs>ePlaYu-4$^4csV(+d5;9iTA=W7m zc!I0}`+^}h0j@pv&tpZakA~Ry9f5Dk#Aib+a}n@us}EszlG^cAgA_oRJ?{s8Eh}Cd zW^cn-W51EOKFl7s6@Y&jh{mE%VRp6&_>+v@9OfTTO{(=cY-^Z*PZH29-Vx?Y%oqC( ziR?vgWoT@WUw|FNc2^@{r~n^Kb!Dm~2_v);4^GyR^n0k(awGH^0zRbC$yR?8DXt*k zci3ZWPc;fjjL=sIh`_vKi$sk^=sN^VY(hY>74Rbh_<&-Blvp8G5%QsdfKscPYY4av z>J~ddCDTDew&7{Zas&)iX#r=1HXtB+uK8AeLi8JR$R3hZe%$;ae{iP@(5xWZC$?oW zJ}0q|YPV}ql#DCVR~hVPb4o#<$|g)nuwmMXv=7A3h2gN__T7bLweQjD*JxLzeU|iO za#y8&wzMUf<#J^E2!6#`JD9o6uL=?~UGNjNSanlOGlcx>Guy8NrUXck-!ES8D=lR6UWVv z#iTM9RWVZ*lO8j*X@L?qOExBxWx(IY&0ZtAl*8OXvwL9&^+R)bVM5Gf82WyX-h3O}D!VOGeS z!sxDhKu_APq^?p019BH5o{FRj2K2fl$crLJ6?coA$AptUpflT!Q6F&AZWK-V$cGLX z)2g+P%><2oN0jMcw5dH{oZR_zvUGTz0oAewHygbKRC8NTD#gbhivo?8PY=-G530F>DtSFhi+A?|$)XVC-B4pOfEoCP6M0>?v6IDnl_43Gh z*v*>iky23UJTfFWOec`a_KF zIrKbD3yozdSX8?k<&MjEmb?lySH{({Ea-{5N%psnHI#swB{i`4MWA_-X0!DkP>YmP zlM+WA|EdaGI!90J~N?{JrGrkVp@SN1->dnFJ3(YyD{)l@TLSMSRAkM{t z(ett<<>}-7FfyK3H0!>fUn&E>s>$vK`D+k`=QS-4jstSyDGPz8th`0MH-fKYDQ{{E z{HwN4BrfAuF?)Gl*9J+0Y~tTxf#Er=N!hjV!;^t;S-64tI3WofcEYF9iu3R+%9&)2B{owofVdtkpT&#ABMAXKQ3!?3eWC-LMnz^EdAWa z<g$m5DQS;E){ldpk=ll*HqdDIv$7efY>oNNfJF69GkRc4$sKbQCEvY=jZ8&~ zy|NyK-9@^(PZIW;6G8V)=tJUiuv=kx?)zmuPS$_2d2(R;m?f0q0ZaVsbMwl;)X1Ff zigH3tOVxOLOmKl7>h1mHhz`SG1+rA>EDU}(j6RTU#X5Kr^evF99v6w7{O%RN-WIy~ zHFPP^M}1wydO0;a&{xdzuvMNgADAyO67uukA=yBI6&>VJUSK~9!``OpbxNR6eOr{3 z$`4LKY>_JEpU$6$^#+P9%;fhk1D1&80}O~aEdlmd|0?V$kAG4OELEjc%D6EGOSr&5 zv9YOz%6V#gL=RKj;` zBr?-x9N&a>@O8!s84tATI^%@Q1~`@LyxDXP?ijg*2{ACnDguXKdQ;!VT8y)A#j|eU z11evv-@u1dzJ~^|H9Zc*tj0D~pj!O^Lq-Q;5D&=bt1pcL6||b(^B9thev%yQoh(p^G$SWliVkIz(xGCy!%3+H z4Uj3lY%Zl7v@HU?qgi$VEG}crYFI9vBkqlraKR{8`G{lz|%LELFxzF*F%7q~j}RIy#pzQ&wMz9zTNaxR0A%hSsL7gfn*7 z0&}qh4?qGx!1 z2LB%A2Nnxq!YOfkC*Ts5&LLqH!$&T-0o}YU)?tCAR$?!&fvB#dPl=y^nQH!2?5?SS zwGpe8w_I=KL`W-etAz$%LmIbU+%-_ehcL2%JH$N$rf&X4Dez8}PN$GR%D`X-wpe{g zGx1JiY>A3hcF9N;x!vcjfh^6X} zSPW-y2oqw!+*Oen5of@j6~&5!apDYEE8{-veP~6Xm2oick)by*e1bS5_MByp@Co9K zSS!OP*cKywE5j#jBp=brhgFX}Gxoey08YvMWDXqGA@VpT+dyk5&c?liQ4YMM(rH6I zbW-L2qW-?Az7Gq-qb8N#0s9S{Q9l=aQj^-{S5)?d*|#z&G9V9uf2ODKdgzQAGi5=&Qg-sL-w4mD>{l@k=_#RI)LO3^a8 z2*b|9Qp7EPTg0WZM^}PY$oVOqeQo|RGA%+|d_}9D5GCicGw5Z}8WKLub?pX&)=DZ7 zdpkv&NCNb(#X$^f(QbLygD0(+F^ld$D@rM6cDUf8BUc1fVdnc8R_?z9ox;Y?Rp?>d zgh40-2ICDxx@i0n3{xQ8+N)Ri%pfqsLW6I?I0U*`=-`>q#Xt`Wo%{?&JdkCfTZ#KS zN`4zQo*C$?ak?K5g znzyb}Y^8-kzPB@QghnS4>4s@s9dML|=}KHbtPAKY?1sSm8XpLa4t$`|fKxMQWCQ1{ z`?QV*=fZ1hl!clRhkpYXL~3#9y1)5aRqqI$^)>>3XzA4s6qEiI6iiKTS%oa=KSCn9 zB42wko^1N?p^2GH* zy8aBxg6q|EO=m4}eJ8HtqG8Q+*3uv7q_O1@MafE#`lT>B#-Bx}M?~XxLI1P-7X@J- z4i#r5Wg$K7&wLLJ&I*uLV}0*tUyTQL7%U>aY$k%Uf>PyuP{m!;1Uk)$Cb&_%pAJ&u z+K+2A9E$57i%W!bqu6^eG2@z!cWMS{t$htHe@(^)ncpKO6Mr0qkT|1Oxsb!#D$mPi z+c8NwBxA+Xfs6hGuU5j{Q(Ah)6#S1|ZyKVU;P0^*Vp^%)X-*mwh~(BHg|6;Kpjbk5 z8Vxp7stmj6n9&1Zo5ff{M4;F;)gFA?D|rF=GRf4dW2(wSuvR*x3dgZPt_SW~Q^ek5AyaoFY)=xWe!r9Y$c6EKrtl9m1}(o=mwEB+kL;}>DL zgUMk+qr*|OnU}x)q&SxrLTLkW6@fDTdG#Q*>Esegy+6wdd zb^Z?T9+BWOt@s~R{ye*Zul85@!;2A+Z54P;<%j!%bJdTbqFB^u+y$Kp_7-ba!8HrO z`4-~@(F11VxDJv3kOs)xVWbN2pE0n(!D1l{vk&pbP}E?#3hAKK4I%zGl`=vt72Vz( z;t#@%g7TJ_o~rPPH-ks1a_-v^;X_b6O*536=nV5s&K)NRZwEp)$-Sgr z`x(8fk(_rDibVHVZ>58J|3joqWfd64>UzmU~-fRPo^nvv|N#I)6niHx3$$IJe5o-q@)HeBcmB6%rB&Qqz5Qz@;% zW6%rF2vt5)ckp@Wxo4y*kHt8-))hEPl^bGizJd~0sd8@c@#HXYw1q+b=5pXo7GgK& zs`*h(`)Cq{(XkyH()X_M$(7XIvB|yJ0xvqVq|FG~VA1WRvfGAm1Iaf_aXHw7(A4B* za>K;U=+s*Ba(QUY%WOfjd3?K+moOsEKk_Wbb*y~VI@OL#uXs^;0X)~( zcH)Ti{jjyIEd~wjFA$q}c7`yr)9n9KjHq zy%MGto@aGsiMe}H$Kl_=KLvxC>?Cv~*rOcAPOT(m4rbja9X~6<;0AME6Xa%_q0GUa zmjrp)yA7b+9|if?Po}GOcfsO@XPEALZ^dl2ZDqDC;N*U-$FjqAW?i9Gkso@68!EC;Q?@1ywI$f>{q9nizlb} zVwxz)0JZ?i7_MuT7Rxf9oSZj4Ckxu!y)F9+iMq#JfD1nj0Zb zO+JxRcxMcz$7St-JNSQ~+n%--x_MrEvtp`0auC|!X+7T(=EtEx9*-tXFqPjm1{i0p zWz+e3sG-NJN#B;q??&%DT$8>nhquSzdg3){sd@Y(wAje;*; zvh{SZ*5gh5S}icB$@}&e-ULtJN!IAr1$(R5bvg~1dOB(YAqcVLi6SQ)(p>NgxZ6|t zWaz0UtkF>uvE*qcf1jeoLubU2XAnH7r;~PiIx&_!akvfhbk^uCP8=S<%ns}Gq-lPU z9us-RcyL!S4tglER_i={7Nx|Y-ed8I>0zzO@s8dfZ~&fcjeHPVrt!C_rMW^1Xqm?C zuw73tElZS)SN2{V3+`)`yienA)q(Rx&&46(xHxd3mH!!ymo33@3r~?1fK$N=R(qZj zA$9E3;4K)^pi*%UfeitTAIb#}5D!_zA>n_(tUUuQ#v$Qc(w;JnUMa!mfChzM3|+U= znVsL!79XF*KAZ;SUE_uf$ke9wUI|>=L!iN?p?-eL2tf|E6^74moi519_CpGM-4a1= zmNUUjs&5w=j=@}vmm_%x7?x*&c(DlO@~f!Uvrw0+=-{VmNEeAWzi8_ zJReD7T4G@=--UtpEVW*L_3}R!0B_cL3$@tKlk0)Y^g4uUp-7O=r!iWt&lDWy?MPxP zbUZ>wbSm$SS;G_2F9}TN-(&z+TJ6Z>lQ1KCR#}+Cho%Bo>vDOL#~&CCT%*f-?0jBB zYPMFFYFy6GLXMuuEp)&EHI3(`q&v4-Sj)Fg2ClQPjvrYLTyMRO+`t!NqV(J*UQDBx z+aDk+zg_=Qw6ckZ=L0ubvTWhqRsc6zxQw^KBSU6KxpaqK?u0Vdd==*jeidR=-DqMg%=k!{wQV&&q3?8z8^^|w?iTQUzu|n za@DWQ0}Y!Z4?#hknMv$ZIDt&@$r#ekY4J9Fb-oyK(iz{*y^E#vn9G&S9Gj; zjwBx&M@2VE3bN7)&|FEW>>fy>x=B(dI|FY}-7G1OIVf%(xejcxDE2?2Eq}wR*;l=S zB|v4XBQl}F24N12RIiliVDCXit5?Z*f1@y5QY|XR2kVj3SqwIKrADS#1%!G#FGYsf5u%(V7yO zvXng+3+gY+EMrBmp_)=jm25-=f~*-JaV%Q_fz%9?8Ee^F7^<2=2m&19tGOcD&d~}KzGSFgFO$;tTCy2Z1k|oWuUE+{LBMAsM#hf z%Vht=R917h>{||dvJABSpnOLtj~$~bcC^ZN6ntjQ&Q{spK~?OsWUF*rh`CZ3&+VzT zit=g>Olg9bZNR@1_(epJDNTi0Oo*3cuy4Jfc9O8BI*4os3$e1P-cE*6t5olhEwn6U zXRGe49tw5b^_et5X(;ztf|G`_Tas5A%Ds|&(opuuWAA=;#>|`(ADQJtS&x#0!&UjX zeC%JiRP3S2I1-jgZF!Ilhi9ukG#eq*g_%&}>W5l4Q-qy7ELV0;X;P2K4!MO%RUek* zjai^nAEh2*dk^PHQP}RAa4Qk1KFFO^J{Py_G-(}40miHE!4cAp zRqaz{Yv}a>YN@>^bS@3PWm)xmtScb0W|k__)&lL|FI@0ZS_~rB7~&dnTq^clEEH8LYE78eDQ+?mPCo<{`Vow2UNx1 z%RyIP5M;2wlAHbIk{}1mP6GXEz{Y5=uN$02^?y1DaxZnDSI3LU6 zpxg-$BSs&` zmubKpswEKqA}ppl%0dVKM+acEnkN!Fd0jKGjfHMr2?RJ)o(a-l{lcPFDJs>#9d%~8h-RfHc!#q1|u4w*sbS{QxLv=tEyW7-k;OQ>L$FOyrRS+?ILPt9%V+OwXgLJR+~~0Y$*a)VqZj zGx+P&)}!JO11&~ZVGi>=Zpqin_r?RCP(Q{RiJJa9t(A^hkD`P8c1(YsI^(BHW}&p z{F}MJH>{!}`FtM9>@6#G5&w$~__j*xPc2l&UnW&~#}ZOGcNGKQRY!~1N`4K~kmo%s zwu(j8{b(BY{cCWYxeY&tCtdSR2q9aBMvowU@4!8Ix@pvQ-}V?>ch~-nYbB0; zQ^#Qw2_a%+0won-wEpLb_#TL!bHqxEbqcf^J zj_!buXOPl%)cDI9Y8zv?;rnRx*3*EDH8KSn9HXUp#u=3Y9Xx?7sM?q%(8&#IwX?>! zL$I3<9A|#F*dI9wZ{V3|oDrdZ-W@ZBr`GsMAkGGofloI0%~WBS55~WqDMqHiRQ@8I zlxM0@E-;;kmI3Pw+Knd7c9Y1a87lMj28qKaXJm) zDKjn!EESJJJ%f$k1(xv{S%@8Cgy7;xcrMy68fsxB|Ct0(Zd8caD!!XcufkX+aI83u z=ox0n(}?4F7TM`=L%ciNBUH;Z$jMV_Y!|8P_#D*e8DUl2z^h2NMj9`Q*x7uJx&7uq zWa$7L-^b1k|9C87V|3cVA>A$~-{ZD!a50BX2F6I?ErTz@5x5~uPDsL>N|?JOASe85yQZ<)U$Di^`+b-8}Z8Ef2yM1|9=5jK z3^Dh69NZBoP^Y(D19%dEg<-eJquNYpF4~=k-bBX7)LzHvZacDrnx!d&9#%{lJy-3_5F!@ z+EKrVYbB1f>nBDMO4K=>fbvvXyF&`!ZC;2ZsmIK#k(9{cj@V_V{Vv*l_w=$^kK=f_ z5}0Qr$&+hqPsZBE=EN}4X@c^Jz`nMv!b>`(TgG@=d>#KEH_q*Vig|n16NpHAMUjgxY9xgPo+szF9As7E{{#ylbtrhF#_mii-#X=u{9yNMywGi$#8@|!A&XD~H@>TtS>n#lP=OIha zZH8Q%r*a&N!1kFHo6ct}0N!C?Cf|cu)w98PUi2Y{|46YLjf(=YNlqhir&V!2*C}z@ zCWAhJM7|(97QDsS0};{OR9XeR%fd4LiFtWdPHIsd*?L6h*Crq~U@O6}lkUFW1sJqV z7id8L`mRpO8^RIT$@Yv0bn}1C0;bzO73jr6U?H04e;6Ht#(jrt&7eaS375^ys~=NM zvuF(;lHZTYHRQVoia1*8Nw(1NPM$X%yW_?dF}XPSZ)8uM45>CwCE@W(GGyZRHFFl6fcBDsqAf6D#~*n3`fRPMzd_j z-+~CiU@$%q^tvR2z1ao6A>(wBh;*>KOF(bb2y(KykbcISw+nKk?K?Ldi=i(MWqeD9 zOoe@9)@%$$*JEPZyefnbteCfKOir8xk$Pv2N}JIzTbVhUzN4xd22v+?8g0I~F$n^_ zyfHzYZ2r12u{M&cC^M(X&&@`$-@~A(ax*8I4TdY6SrVwHQ^=Nk$gE70~TZjlJ!qR4kF4N^?bHb*=NV*@5pWT5CDL_ODWk%zb z*codO?DUA9JH=CB>Jv%D>6QCQ2J=A-PARn zvbe-QWGz%&1ZR6Bx@CDuvb-Qm$70SIkQ7#8{|_ZNoyoFD2S zAw@R9p``G&)P&gZcWqFRF9F4c7x<|D4%F9h0ep_L6SY%`?SrI-vk%*cadGyQDxt6p zHz;3{ro>J{BF$MSP6RrOWHs2~qkb1lQt=Wm62&`9Wk~~CTP;c&D5wED!=Gx%Gf3t! zSk(wnnIs!az|`v;OhbpSMJXwNM|nPH@9=79y|aM26dn$5=q#Zohrf-%p zg5j$kwII7BgT0Tko7jG#d=ACc0lL`as6$n;f5(rzDVmAg*6o#*+xb7aT~==PB`m1P zdZiqn4Ldy^7<1n(a3-;Fw_+@sV%Z;)5$2H@6gGAoC{B{5xY8+u_ZzDGHl+78#j_$P zdXu%es;~h>zShdCYC!EJIoLR&1W8Udktk7;shb@l_fy4z0E&%$M6@NyJS_-HmTB39FEQ1!cy2Ff0&|*mjd)Pc@7WImSuFt*o zH1dS+z|hZK_YN*Q;f0F1>(5bO7!}RE?Gjynk%Y_JKcmaD=J2hh5i=gzF?W^F@42g6 zn?_U7+%=N0gWVsriP{8xQc{Z7Q^W2Jzdr@Rd#Jxk%6SpCKYVs5!tOh{3gv&!ae2SE zblGruKwK^xh|7cG@*Mgbnfrja{!>Q;KS&#?;qRymhsbG$V^GfAhs31|K56d5@zn6O zopJdH)f;}H3oZ|f%XJHId4xP@cykdhAN?6=6}xtuq8zbfnKySAYmYIWyEg+(B`;SL z0;N7iy}@1-{3`XqH4h5DM*K+wyK+0evk!R{Rg7Uv%xAYHCM|^JRaAFGI2qP&m{=-m zBstmL=D(1FJ`+|kNrw4YZ5UK5$Y+{ zX9~(;S21iA4U+QMD)WxJS4Spy!?BZ!jqGl$^D8zlxkGkka6V{DL=ap{GU%?>3I30j zAXAc)(aSIuTeS_M&*B3?72D)6d)e2R!z#8*^05@69g^_<3i!>6ofpv`bUn!C-3;6% zBg5hy-HLnUA*)n&%{;n2(fv2f8WsEHmy&Z>ukPl>?SrBZz&?W&TUoziGkr%wR}xms zK$!+dh)O|&JwRl`m+DGgklHkt%NVhV^M(FNJ0zdtcfPqK+Mh(GAO|;}CSbj&`1h6?}1( zC{^5p4C^P?`RU@^@36wY8!0YR9Gq#T999pP)=GKe{pn#vvMc$lZPz+P7Jn-WEn-1f z$*_{21eJSl+TDksplhRA9l*zMiEE=}oP#wtfh<=H z2m6KT-_@&tzV6u)quTGJmMY>~-Ysrxqs|a3+Ll=By(0&w?>x46RO{7mZkn5SarHOz zfnDA5cnUu);m z!I5~hx_+*_>vuAG3%9;WZXCE{@RoCZ^BR+y=M`_8*3YBo-`EKfUa5Y*e7+J^?0hpm z-2u(7s&8c9m!OOl87$iBFDxMNBQbk?iEGiXvH+l|MhEL5$I%(4nfjezZB$V zOVdH?ZChpSn+Ah!PZ8u}?I~{K5J7%%g0g-UDY zQA11F-UiTp!vvKvdh@mZK%<~?w%gpdyHn()YHzEz)DPs|9GY0r()KS^)$-_Z!eSe9lj8*gmosr-7sbu?MiLSS$@>j8K zwV-z-jb-_LLGMZ$&qhxLo!xbaN~vXO1)%pNHL(~E=>1(0MB)&z%6iWRTQ98O?=l?5 z*to10R<^1vo4R$LPCd}^C-y8njOzmRi%vhW7R+WY>wT4dDw_kLyFQe$2UK>HMEH@! zLn_OI&blsoKA^E}Wx!wQBP(<&i@mrU_@A0b2oGzl z78952nrt*)nL0p;f0O+@uCdFBz~5z2&uA=X67Y||yiIveXd`(smJ%*SZ7-UQ16E<1L#u8w#buWO^Vc%Pm z4LK9J`2vjZtsRa1D4zCN8_R(q<3mCN8{nJGllS?9Pr`BB+Q}+0%uf(@wlGym*kWG0 zuT*U`i|;R0v&>uX58?3S!}lka)BXJ|@ng1A(LP4s?r$YOqk3B@h`O$zM*Dq8ddP(p z?R?IjtHn#I@p39x*cCJOKvARKT1yk`&&dxYF z9Rbc}HyOZGAjS@F>$R%@rcsG7REUdGTgXDkwkSMUBg z8QAT(z|$I|PpCI%ZrMeN&)~1q^a5r*FYv5}uYE?q*>4Lzr?Gb9fH@LB)P!?y?)i5S z`!P=c!1p!h{x0w{joCS{mrQ&G$A76smmy(qbGkUS++0zP$%y7JIxe&P9i)nO^eObq~zdvh2-jm3FDZ%2SId&)qW5(f`Twcvy}jUd8D9P|5Ipqwqp+bF%oL zPV@V+D~cSJb8=W5OnlMyJbloX=2h`M+Y9pfXF2Org%)3=?$Oudo-$8Alvp+ki@D}Y z(pk+GtJmhs7etCCwrdRHJ{}_4&?3A4DRrN|sw!mj8OcTqEo1(~W8EKaqegztklTXD z()}I$G$mk3*w{J!38;dSeqs_W84IwQ(b8{&&(;;!!aj=9nEh|eLfx++{j(aSFG#P# z-HDR^bv~tkc`ni`_Uyfiav0)uHV(l{Ajmb;I&06amVzp1e#JX#2KyPy(8ghebdzfT z82NT%>Oa*uiM8vBsM_Lv6s0iw9CG92=>0?ntAKtrPN7EAEgd~hYMe$B5DnQ6=tg7x z$3iS_S$hMyIH4AI!?qh|h`GwlI~*5znRqshj+o!8(CNlG5;4E`83Al`qf&BTik%ws z%S`yy##;7Jcf@U{_cW+^uRwhpt@|#6%_#uwyeNAmZnPS$8!adM5o^cB-BKUi8XIVy zKJ1J1tiz1eIGM#@GHeuoZ;lETNsr5<1{>IdxF;n!Wxt-5uG=d<``7r4w0)nr3u}B% z$|IGXftPJOF-kNvofX0^8vis+P$pZCA#D8f?Xnj+tb_*mFULh>9(&zfawO6JJBj+Q zGD9hx+8`PbgT~*r|JczZs@iT!681@K<6;)fpQhNVZK&z;-1VlU4G8ni_@lgTJZt9Wv;$+u=@2m{K2F;+_IL~Z{9$wFV@c{q=F^WQMf$Hm zR7Wc+T|61GhgI32O!1PPy|en}6V!G*E184D=~m)AIvIdZ0$Yjm`F_m7_HyfNMiEb; z#1$5n@)X#ay;A*B6jjFOLEr5o)ZEHrRCGC?vI;y}9WStwJEsH3sB;8X@h36S+T~kp zaOrqe^0uQ%kvD<}tXDC9D4~vTDFjZpu%3^_lE~g*VFT}svA55({(RU>{`5-VEDL9O z=d>(P>~pMBCbK!cT5WH%@;32J6M=IroX2So&EBj=q>x&;)&;y!RqfP{#r#$3*&~3pW^?Ui-5@V>Mv2!T$zV zV}H&nV5`B;6F;xY`;{FAZ-Se&zbJM%AYvPzO$~h6>d;yn-%R%WsxWUz*v1<$BoX_Y z>fNv=h!hE^fVb5*L<4r%_**pQ?^?XuCXSfc-xr1qCA0BE)Z-5Z9guZjGJ zY}~N~d|6#7%0F!5QOm)fSmhnH@hjz6^V&aC+a0F{9JlfBNvZy+_7ePzjc3!CeyNTX ze8R?uF9v_DKJp}`KWXDTNsGTzUlaVYjjt#Lf3JQj_>_%*G8+7oRpDtHe`N~zs%m?R z@}IGBXS)ajepUS<;H-_OU;?&Zv-q5iPw;^MP!f4yRo&1PmKJ{drmRM%K{^Z=qj&TU|T0X3fAH_Un;}$mX?U1i6{BrC+Gg%%`MW4&MtSOp>1g2cBlR<@v3kcJRW4@7O9RIXF| z77BH?rK-J-N*DWKBVxO#gYP3;#;c=VDZBJw)%s=eoxD!8s~DFcaTa zD5uhMExujlt0;XRl~!2djhUl0-~uZ@-k71U1lUT1@WdNw^m#g4f6H9q;^_f(lC4yg zpZb7LryFhC0E_pj_zvvZr@Q!G8c9oseQXC+zrXdY$$&&N{+YCnyb6Io4?BWq1NAUA z+rO*n@*Nt*tF?5w(472C!l*p>Mz8Hh_D2d{-u1OU5L}A}HMF-L2#SyUHzdfhHP|Rv zQbVF7NAmyobtd379dZ9Z=iGBM7x!|>9gQRi34$O=?G0jWHX?SlM3S2jf{57FrPXRJ zE#kU#)4kPJtrfLbQEj!=(pGgrQFNs(UA6D`H}i{E|L^nsJ&%0vXZD#hGiT1soH-w( z?;KZOxwPFFKw_P`;{6?=tb!Pr^BW>H)e7{u_BuSTxG@ZN9W>R!aOf-4*{~i+lSCtS zIj^b26yK&D;HkS}^XpLoTEs4n)MjXR_KjDt`g}AA70j~J;5T}@SN$G@- zr)|QCrfU*v>3G6Sz0~UxA6As_Y~`MgVs-vY35Y1D*swFY#~Rdam(wssY6DD--uIM2 zAsJ#Wo>wQ{uL+Ys=o2O`($kN&$ihuv;sctT;+KjVyIQxaR}05?J6)z~+XeA@iqR02 z=*j9!I{z7djXn~?Z6fVqvR7~0x8K8|C1+Db7vQM-?aTK)HR97vK7PQeGBE*q+ z*tJ6#@E)xWF)e7XDMs}6!LFlDZ=8q<2X)faR77Nf?x_5X{Kbo5v7i*4z+qx&05^yN zK5lKKxPrI}y6Hg2h%&Udg6>n%wPV~>Yuq@apvU+v1mnbx9m+D;8SX*|CPrMX2ILjcIMGyqW^1SM zVgkxCY>uV`F}@LKuBJqBi2U&v5!#A7i$L?VT}LsiIw+tiMU^@CdqB;d~zo!0z&NK^qP}3msU@y>OO?VmP!e$(rG9O!? z!?vjU8n%^8sM_cBgu`v$DY8Z5d7#&HMUNA;Js#k8Tq`(@7o#gm_r{NkSb#^ouwCLL z>TTF=T|4lULN$9yD6P1* zw`aW@6A@uT67pjvEW=}wmCy#I;7ItTB4=Mp$DZgyWAJ<-yH7(q?&sjXNnXSa#g*fz zbB+>g$tkEju7Qq`3SF{AVa1_+EgJlSI~{tdd<=$K4Z)x2gShfA7)!q&s_^V@YA&m2 zyZ`HI)DY%}J%P5~@Qoi%B( zDaTM1!ryzqb}Bd<-wKI*vw6aZQ3xtS&(PrTYf5C6zJd|zBP9O5ItkHe(G`>5j0`j$ z3nw|+NrKo}2pXU%QGDG3L|;ci1Z_nzirha)Q%7-eI*30_gXKw7e*aKymnzaw5&V3b za4!)y8Z=znrHL&gL3e4&5;MBkz!4hzixn6Z_(y6QB*svLqcjae7t;kfjsCqMFs%|r>%@uSryz(qyP!;=Ch+TsJxOZtlQFj&&B>YF+nkisR| zysf(yz9_V$zrJ({qJ225a&#L@6uwN*08MShKX_1FGEl#F*ijVZg9d3z5qA*{)|4uC zpp7jVQc9m9rM1ii^e{_?QtwG~m!lFv!^WV(V(P*OJGs*^_VmEeVR0`}+{Z8$_tx`P zhUh*H)Mqb}PIvbCgFyTh34Ma`;@_JKeJ`ZL$k&9zDjCmBn(@XblI z9)oxKwraA(1vHJN+jO6Aivh`?*EBiB2-LEr+qKIuqps@+HnQNEXsMMSu;r(yD*5y6 z`Y^=3TaKInyw^@sXv-cL%m?xpF}vh5sFe9j>|$l@mR->K=P$JvD)h>y&;#W!v-N>+ zKKWrc;6wIv$~HpgH3B|tzoRf(y)l`;+|~y~#K>8*V7o%UA%Yi(Hlr%%ue7hiF($*~ zLUMfd!!00OD;#BkpBd45AQEep(f=&Y0p)*gXDRN z_$fQ2aF~2X0H5Y8j+7J2fzR4+DBCe|XD{G$_7@8Ma@;83^Y(8F$H|-yz!&Ul@95=1 z*%enT|3zXHK&fnkYnuO(-9%xz98v^)*+yp%+nI7%SKtOaMcK}kzo2pFZ?uO3)f4Y} z3Epf^Qj9Yonxm%YZ?);&TJ^+x5ch%nZE9OP?j1N}We$1RZm&@u@Q7PuFnEXkGAgrr z#Pv=A?^G|8saeeN)xf*d8)a(NGN~VUk9wm_&04N&0N%^~F>9Gc3Eao-F>6_O9{3IQ zt{Dzl!K`H#)vPzw+h(|nm~uGrK~=J}I3XYRfe+bqFp2tHTK4QxECxhR$za;wreeUrpZZrAs*^YN9f@65y zm1^Akb_2yHOxdJ5_ybPRNmIt4)#o2$`!7tn3N14KL%W4?f5w!54FG>+4^n&{^R!fA z$L)EFFCoLYFXf-Gp8yv*V!t=#*KJ_%iT%2AaK)7W#)CgqZH+!bFOz11PulM)``>Zs zxF3AV{!a1VrrgvL{H5(ZN*S1M$&Ee1XY549IB;%u#ftYE2Fhb#dY(hYWb6dGaNpQd zlq;NJGc6l@k?k=V+lPwbvb{*z;|!an)E>UIA6NXOCF#}2{O|0Iil4RQa4-0K`-I{b zEoqbgADLgl;lH_L@RR+Aa)9GQc2PF3*uM8D**HEV=m1~k2r&CwuQm8*W}JcZ6D9Z; zJ4w067K(fF!N1yfD#jLyYm>m&RF9?3!0Cb;PyTi0qXA299}k1yI6&;7SWY?q-5#d` zIAO^voxy+F4=Fy0>1=ev`G2wdFD!YvCirjWGnP!C68Xn|UAaGR$?GogzifXA$0g4I zTh4RJKJYzG?P&)Chf^2X6-#~>1-6}kDhIz>@&W2p!kkg>Q;Ga;$ztjmUCs`Q|F+~Y zYOB?p>54HQorp&0Yy=csDeb^fjx^WzR`OSd_ze?SSu{P@q*DMmP(D1O!<%cp5Q3!6}oT%L6T=;5z!3~`cDBj_aHG6|&n0Gtm>U3~p=LTiJ z-yyq=2FE$|u9$;}kE&1;=Q(A6#34VXI@#Q5AEWdgb;$eZzSNTWm?K#xP>Hs3E?1q& z2^>^k25#eQt~{J{$d=TU5}Chn$PX&6e%LUuj>@&YbG~wQ$syZN_uj$jTt(4*?~o_j zfIB&#Q}$OJ@GWne+6$dWiMXkGGQ0V+t z8GLWcs~FDZ7ded+l%OlNJV3X)vCbI9zuK}}8o1b*s`z(XwxQZT-Z@6`-?mJf2A=Gk zuXw&w)}{=VI%zzK*=nbZ=?0$ae3I<9K6av0^=j|dz@%vYD6CO`^;Oj1X#vB?Yx6a3 zUo^Mb%m+%;B*azRX7iHu)H1df=Yek5giisYD&@7+MWgR1`k(Eh?0M^D<=@A@-wl_HS9IC|WE+ zN9W%f(CY><^qlD5Mh~jAchubqcCQWFP82WdM1m?QK3Xvl^g6F!eKdxKPhu!K4*%=g z7Q2S>3DuSZI-^%yo(SB9h6cabHFOPQHvev3+cO0Y;0N!~yvY=22>0q;l}AjGkPF;L z^CXVglct`{*{^q1eqoB;-C+BM4*HBK+QtG8+>L~&9g}pfzW>eVkXd}r!xT|ud+=q2 z-njL)9QZKJxYF=K)J_4u1#2KSR4%BJV8^0_zSJX zU!o~m_@;v<-JDImfU4@}>09inK7A5jMZ#@A+W(NQG^=#QFa(O)@CTjha^p~1)I|Sk zO)fp{71GmQZV~5%-I}TyMVepquhrxe1JRND9|2XAU1(oz3@)e3PqTWPFKi9GgPU_= zL6(ZQVDM91BD6kLFhr9jmZE$LhEh?Y1=Jc_U=$2*qQIqAQVQdCQS#34mq zv3mf#jXJByC+4;Vjs8thgh+}3<#yPVOdg}fVzldmG4x&%O*T_gDag}h5T|NTL4lrW zi$@iykQblqFrXX{o7q*HBx!lY)Blq4Zr7SI#qi|l?d#ZuM5f~h8b+F@uMDsF{$hRe zvx@4M(gV+-Y(0-#f50o^l#P?#5zr^CqNyMxN~WU@oth1-#5D&?#TbtWq)4dr@Q z3(jTB22JBVF5*pG0?%}v?Ff;Bd#h&#B1WLm;&Mf;%eMvSt+GvC&uB?6dwNVOaGGp! zDntg*w$>@MrFixJG54??S<0b8-_e8O6f~3v#p8D2< z%5kEk-SnPD)*gjz)!_`DSnHy~juP(=7@j7ar4-o<&B+spw`jzK4epZqPftsWZpye? z^0Ohp1jaPk3bznXE6X}dwpsE@CNR-L(F6O-t1W;@*68~P2g!$f0+Shs$um@Vova9? zolZR*L9GG_D0}V>#nmAxLi@Gs-@LhsB?n&jNMayLf?ZDH6 zBbX^CP6qa}W~#)^m75y^dt2Lq>cLml>^m*Jp%V|j^oEWn-J-(?)q^j6;m_mAB7zSzJ-{;{yRlE|x=< zg^R0$3}cxu>>NdBh!yBHtH>6M>Vl-UbBUPRL~iBME$)~Gs#~VAfNuk$rY?)njmswr zdV=cdwYmtA;Q;ZDC&2}>{1th4lFmm$Ayfd2R?Mm*>vgRZ9;aYk!4@EI$hT|12M z*AUdT-dH7fy^8(yX!)*<>cm!R`2{0@n;31mZVGTSqf5R#7Py7cEgR!{y0$Xn8xtQP zU}qgl<1S0OieR~$EwKm0x_U0u#%V?cjL4lRiu7=Gm_y_?^mXYW$LSaGdi^L2IMUZR z=*}NW=Ru^ebc%h8PgBYGt z*GLsV;|aaJc%=AxC}Q7&Yyg@uZ&i^os`M@hKh5IPo#cAmeFGC1Q3x&@-A! zMKBEXtful>lQ7Me@tmfaYDFsJdA$TZS9~1925y zslMxzu~j4Xto~IF$J=N+m?nYnjz5}L#?EGc5@QQKb^IB-x+=t2i%$5-*fUz;Q3Q>_ zPR8D83XkE{nJK`1ixi$P#W@UYGWI{N5CgOKy}&m#Vqiw^R%N_-K-pqoc3Tec;ORe6 z{%T~FjtiS{NQZ@ySz|Q3jKdl+GNTc5##2Fhfh2A;iU2Qwx5+`w&$T+HTp(REKP=_<#)2^{(lv*43zDJcFmW*oRK9F%NTp^Z> z=*7N_kLoGJl2I%wcgFE%Dkdx$oj}Kx@o`sWizTBr=z22L`GuGRu#E6_7Y(BZ8ed%c z7Kd1a@nV*H%O9%#VQ)qe&;wLe^&l=!R!vPVaR@zfRxM3#F$;I9Ebj}-CBCMMW|38U zkD}T}cpjqo2>nt-`aD}+=!9kxu;BuM8uBbU`t@4D%6B)a+Z-FBn%%A-s`RZZV>^PQNn7)PYI*@vA$k0 z&JAj)?R>RL^Gc01jdY+9ViblUYZ_~+Cn`_}*2Gd0tk_6#0PS~8oTj_PQKWZG)4*9I zlJ?n(=O{*1;`;41)T1@cbpfEK_(%ZTP@HPByX$3yNtPWU}lfI2A(#NH+n&`MT!)|U8a0h+|>J2ch98<{D< zF2AExyp2#QW)iaQrVd>F!Fa$8)9`%!>6Hn?U^EV-#t<-ApZ6{r@(NmPumPhj>5>E+ z@>Xsa?!T`i!eETqjKb;mJ@#ZF|Ixt$Q&JlU`q`x+sYwP4{~JzGRXDzhWz&q{ShjVm z9pb@pj9%#+2fxMa*e5R{7eTeVobJC;et>2ltlC~)SAMzxSi-Jvleu5 za1vuZ*&mO3!BWOZSve6nl`+bQe6j#M!<ceR2V+Y;Xf(gsg}58hn*8TJA%m3~pq^ z3GD8f;7!bNvJSe?;1)(K`(el%+{&0BAI3!vZevW81;|ZsJ7ZfTvNI)fhnb1X82&AC z8#W00dV+tNa?e;;{B<+4?sVYaKwNul2b9|>mK$ts$-9z)|1dh_H<7@98Eu(>`(DuC z2N0KBOX)Wm-I98WpvCBw0Sei{=##0{fwsk!U2Y7-f}Ly~ZA4zAu*0klNPGBCKN`j? zRJw&hkL4>*GJ-YPogs(d{u!*rX#2{Oji8swB~vH`wHe*MNwBQLd0DO#6qUB(#ontkv##yIuUf1|~j0w8&L^3AI=FJgpl=bQW zD(|+^GZh$ZnPIB@d&!;_xIUPy{YK<&Ke&N)9mP<0@l|}9<_^?aM-b;)=Af4e#__iz zP!JKoCXDz-Tw7pMMq745&k}6L7$#em0OJ{5a(R99f5GO=)nyR{-Gb3AY3eE1lCh>- z&={D&h%+&%LbYP7BVXwXY|ZGCS#$~7FxHhFX9E)%BjgfFR+2*WzmYPUJSVetwDePZ zzn!sxoLLBL%NQd!4hFVkY%F(-0Jdk0llyTK33gy?Dl<@hf*l#-<>R=i1v@dekVj}~ zJJ^{yL1s6A^&O0@rKb-tg)z}LD7m8%?82BV2hkPn%Gg#er9^jQY%j012c|N1^!dvR zjbL}K_MLUr=|M>S-yJfO`j1`~U1^#unmZ48r>YH(*gdw~N4ZF2{?e8|HUy_L->_x% zmf#HL$DO*eWvR*r|4um;gMwf`RTtIE0Lz+yvsG&F{DGGNRCOG{0etM#)o~#6HK$Ca z%nfG7LyzlGq?Fol`w6%m8I}=wA0=U^^%t6Kc#EGg{fG)25gcyGJw0JDf^%;8uthC6 zl3N9an#m~tQH(C%AhgBNOm5kn3S|uY^vcbtz8{^*Hfim!)X|2xE8?O%?(z`Mr8Na zuwQGnhjIAp_%j>vx`J5uT}{{MarS7)I<0_DSmcC;+m=lMMQ)+iy3SfgzJJ4?eSN6? z2M0UkpVWyC;gdEEiDS1>oQ$RsIoAgs?s%6x#{6O!AEQB;!I4-qqk1-~%AXN=2+s$> zT!#a0I_$(BbQ&K!lJd$Y8o^H;G^|RRncU6@o^;R^j5r&M_=BH0sHaWxPc1cqryO+k zl8VZV;O7n+)<(QTZRQIHjWCk(ipq`Pmkt^wM9|r}!LJ;2PfaQYEvKn(Sv7q6Eh~C`39y`CJX)1ok^jMkB~z3FAm#K`}Bjk#USKzW}2LCciI` zkA^v!ahyEa7hcP`I7{UC7QktY6Xk2vZ%t>%rSeow;0(rc-$VpF(?OMmHlWZ~5QDQg z#j|9T2RK`W&2cQCc_12o`)C*+oU6P$Vjndn4djD&Ge3q`BxuyI&_Sbj zN9^OKq``dfKISj+6(Gv=B8MK%=%Zz;n-c)#agagDr1A1TyKFa*1C5<-V$C$se zWM~5T3Fgz5oJV8Ob{on7M~xYZt*GRuPr$l6)E^M^Eqr7q3it&Gd40< z6u`607f=G@!OwAmv9aL^8rwY2jC~CcQrmoi8T%TB4X69>iyQzpHcSnNgZ1nH8yo86 zgI{9C#)eK*XV}lyEy~^QZU&Fj&*l%{wD8muE%pu?E zOZUHRY_I_v8`9yRlKDM{T$l&m$^3&uzEc~#n*&^C%TI=Z_i%*EZMnY#crWuRTlS*_ z?sL$n2fL!M-*+l_Kl^{tmdlz@2XTN6*4ye`(cqix;U!y-q7JhCPMq7_9PSUX{Vr?) z=nj6%L4Bzs_FY@PK;82Z2X&E-*!OICoyJjbJN7C2W47!`ccb?>JS=uc_M!2@2W;?} z?ZZRNH`o+U-oLO7S2=o^o85nXBhpR&FFB}Z^-M=~>DOurTzI#IT0717z=a+#X|s<^ zzQP~ylxDx#mX@(T92f?Xj&sTr9slPXrImI2G^M_$PjIPmJ zaX^2=v*Jx2ha2*GGWLrcGK=5@_ZYdo^Gxtz^M1uHdD01d%X~_q+whV*og`Y)t$KW< z2)y@)T8EjDffD*n?r(X@d>onpV@vppT!s zsT7e63cCi)Pnzyqja$LQOY@Ys_~wQ&m=%>j97 z*7AQtg6T3crOC@G(~7J2_(nYggBqWasZI?2gkzf4wd^BgN%M+q$tk%&#x%dk##FiB z`fnIpHq|A|R`sWA=&UdsCO3pjoV$OX{!)f z3MISD=7BuStz=K8e9$5aP3vZtQby@GE}9X|o}wv2&C_O=O-6t;3-%U*$u3`|C`Qfy zW>0@zQJk8>&7Mi6KpOyP1~+>aW^h3X>L9J`IiD$)iDJnpTP|a)@HjRG2 z9vX??fk)^!#jc)&|F>$mTcSz8-#%E?pagKKtGc0D0biEWunW8UhGD#i4kkLSrP_Is zmOv&{sy)$7rM1#KA#C9t4{A*>FVgB2-d_nAY5aDXTYaE2Em3E|D`IfX(vmd!ROzNA zYl=|k6{NMjS49zxL>lIizdSUF^mV}@tK6Q4kEKZ!sRz7TQ{s;M|{%2cf@N)Agyr5jpR7y(u42a#vH;my8RVd%4KL#0rbkPVZhD)?Rl=+DYGTQF&4=!oGdkzo;G5%;+6#yDhyDP0ftn(6-yt3)&d58eR%PC*v=)a+L+7 zo>JglcGF5Fo{qP4U&So|_ETZyIiH4*I{ttZcZ@SlBh|D!i;mH%)zF)%)u$gQo|&|0K^uxi|8(FiT8dD+a{}!{kHS+Rax{$R>7cQ!GP^c#6;)VT zRuQA{%MMncnCML$+?4BsS3d!+k&3c1^;9W2M`^Z!3BLD^+T$%EOET7#N%aMNUmuHBDc#k)yw=;@!!T!e0i36174`&-|YhSt-9~Z=Q;p$ zOo|YdL`Dz}G)E(|v>{>y8ujuaCZ>LXs3sK1E$LcHukE{^(#fYZdCBE}9KfEgG!pKB zRah4O#G=StE8Z3K&F>XQ7f`OyW4u)gdXG*ZpeNF>`VP~m+X8iJRfKZ5ia+yeh-i3N z71aUua2OEvaMxcIJyfAfL=}MQmnp(>3!Y0?HC(0$3ll>@F`9g$9~$whX4+qb=$!+K z*R3jAl;I|@swG_^+Mlxy)4!_{G{uQ6=;2nirpa!)&y;lT2yCM*6U0M!j#`zZOD|D0 zL6%nCuAR0uyp&{JHqV zi(9HRa5fXBoiHFaX4L>*Qw|)R@fxl5D^;dDXrjdWl^nqFen_iB_!C22YKqTBh_gd0 zykD{+o~A8ck{!CnES9i7*4ts~9Ns z)A-*MVdxm1qZs-SsuVdsBhxIr-_qDwRns2C{pp7?)+LX4jonpX!M zs4Dh1ZwA!}c9cc)$bW(w7>1zg7l#hjF`Fc+3h^-|?wn=ltF;JTmXfzq|M9k-ycLEb z!_B5i%GVk4brwld*Z4d5xI(@z{KwZ7@)egIni6i-)scNq-U@B@))BFG!GH70f4mJA z@OCm(8E&@IzOIw6Z=LK5uOJ$4ldr#T^_8-beC-WI`^@-El|+ZC>ATR8sG9CWV(U>E zR{u{;PpO8=WPUjV7U8BU-EMI75dNQs&n~A!5Bto9jj19}g4t9GpzePH=+qSf^y(Kn z=ELhJi*eg?ETVV5`rMhDJClFoil#QHhG-6iaN0-H!1wV8rD+^oeS&VgJ59@&O`oD` zPpA^#l(L*#4dbNu5j>^wWkkJ$qHobH5|~c>D*k80{f81k_?PxQlv4dKoY*LEGx26= z^?-GCB!{dU!>Sosce-iK#oQOB1IVWPEjC8#kCcz&q3>_zBa8AulL9&)S(J|&=%{o) zvM3+TfoZS7Bjw{6gt>{r&C&TFejfjIK5kM~K8|xjufWMQ@;2;da&VVYwJ!=aBL@G? zyqi`?L+aYv9(i-coN^1$FwL36v47^fW?}PJ|6mqFf zEAa#PuhSa1iB*Z62Y*zm>*3~A@>hOKid0(n!t_nDnSG0mkr_50M$OE>24VM-BMzx@ z?Lts3P_k-J>@zY8$x}1)Js3M37_JztUJl@QW+YXfX66;;GY#gM7jc(2<2kGt3M;I} zEn$TlnI8{VE+Sy;bR4I!u2WDAwMQLPDvUFC(+!|G2Ng|0<=hff08_@9El_3Qq(Fs5 zJ!Gry_?g+it1{MM;bv-N9-|(z1&0+uVLf(BSVkQq^Bq)GxOi0s^%4cOl!AH$;{_P& zpb{yl$8p0mTbcn~To?@)u8X&Zg)DBNytFj`P+_g6us)@*VzQL64lAC*Iy4U^37jl1 z1(oc+rL>U4v2@!^Fnht+>6lMJHO9}(F0@M!<~pnxm}lmfz@!z2g?ePT?!GmwhDK(M zhRVgmDy%VZ(P|=v3`nGY1fq%{YHA~sw{ZVf65@%N(mTbrj;SP2x?4hky< z{$Z@cq6}qTBa=297MhUZ3itdsi)$w-7foR7bkwDw9Qc`;Jxm$vpePZU_cw=0A_s-| z5!UGcC#)rr%1NmTi(ItoM`4|ssf=}4%Hv8H(~U68=sO5qQoF=OFfh%&KlL|^X)fHc z2_oUGdHzbOWM<#P2)g+d8rPU+zrhmm#}CsqsP73lj2IDFPdOZou6z113LL)1y{Bp#$vU>{qY%3}VB}4#En-%tOh9 zPi5$cY|oGWHb?odQ_D0aA};vv)fMLLMCeqM852l{`6aYLmH1jl-(}r#@!seJQ$(5v znT6JuWn_0vf%#YF5M|N#-BDPTYxdQA73nBkp#_76sdQ$C7r>p*qBEOKGy6|;V69TE zkH)GrY=UQcMnD?2jl*`zI?vU@ss!SB4;H11IT1e^ed$95eb?{Napj`pT3GX*Wh$<9 z)o=#!XgYZqxjoPukgFkkdO2n>%B;64Rm9V94f1C@|M@^U^u}X+p z12Dc5pnfbpJ(+#ykWB-c>;N;l6?HZ%sJ%3H>vQ0)e0 zduLK|>!jq0`C&~%r47tGHCFCyU>*|LGx8>t7MB+078H%m#S&lZaR#z~t6@>u|23P6 z#k&7%I?i8GP&uoq`LKyvXH>f4%_+5<85rHZ6Pnk-tXG#FUaCSaDK5<|n`z9k&Cr;h zmb{%F9B#Gq7f&siJZVy4LAgOg{#&gk6cPG{c?6_=NEKP-;iBo=v0IP|Q81&w&AHMMKwZHVrXD{a2WEZ5s21uI@CY*(9{D zquJ2^C^3XH47HNv)G(k`ogW}E)df<5NDW=5#*UNhFY?T~4l3{At& zu&?Wz#?b1aC-&mfEDgP}7wsw~beUvTsP;ZcuTUqFXF_=-3quc*3<_-~SsMBb;wS2W|2G=dP+&<+xyLja|1t9Z&C|i>}IWgUUOa6#;nP#DXbZ+ z!&r-0%USPXUC#Oh>np5Bv<8e%*x)?tFRa!DosinBF|2J^yR!CW9mzU@bvEmRtZP_b zVBM}1H|0ZYaDw$5>(8v_H##9+)`qODS-Y@iv5sIJ&pM0s0oD-f^Q81y_Se|pAnQri zv#dX{-e9eP@ibksdaTV@JG1s=9l)B;TE@DVbuBbN0lmlum8^$ZKViMj`Y)^Jl1@Mr zYjf5Pti4$WvgWZ)W}U~n?2<8B<>WCo*vv7hztUs~dV6AbPOMYfsjkP*SYb zEbt2BF4i|$KV&`4`XlQNR_C`m_%^IvSTk9NvyNq*#=3%aoz{S{fem)CzRmh6>jlI3F{+DQODn6gHKp5u>Q*G_+Cd?hqV!FB5NvZf7aow z<5*{~-p?9jeU_B!_*OPJ!1^KU8P=az|6%p~pc53$n!uXE+M9I{YXNH+>jKv0P*um* zvB9gXdsvUMe$M(G>tC#Oe$)wR!E4y=7x2ebNFr?TF|x`Opd){U%tf5P>r1iZ%vU$B11`X_6(E81NIYctmNti4$W zu@v-1LtdFt2!ulHPkF0?k z{KNgTjwp(?CF>omy;ujb=Cj_zx{~!#)|XiKvmRspjP;V%fblyUxPH+IsLk4lHJi1J zbusJHtgo`}V||#WXSbv!<$xc;$hFp9N=bq?!d))!c}vmR#shV?pY7-qPs zPSs^?%G#c_59<(8YX3!SFrD>&*43=rSr4;bXAQf~5wSL9ZO__=bqH$_>vY!pp{o6_ zW`pNhx3eB*{e<-!*6XZczi|Rso3gfN?ZY~RwTN{(>;1oR`(Mol&$Di4Jo=^| zS;Kzk1h6(`ZO__=bsFme*4J21|IY2-O;2yQ6p}TL^>)@CtS_=|W&Mct6ze6{>#X*l zI@}R|X)R!#!n!QLKOSXW&sxcPi1j$@S=OIeZ?M+*TSrijwHa$W)}E|6tj-(SeZa#% zqF9@=c3|zzI*>Jwbuw#+bsg&l)?KV`vwq5Yf%O-y0i!NGMWg5&vbJXJ!kWc8f^|IW zEY=5Dud~|!>hS8Y#;~?#O<~PY8o&Y|8@$N6o%JB=N33U9e`Nie^)>^~`p7^N*0!uY zSxZ@Qt5fbCVts{_+W#&#c!%{f*56peXa<5RCuuFetlL=+v7TU! z$0UVn|A{nPfe5;?=CBTD9m_h6^-H!^Q! ztt3UjyV?FQ^KsUbY<`iH-e34m|1cc1!iXHzBt=AZSnHA^z$UCMNa3z6a~D#$@6I}$ z?fuN-SW8F|&K%bHq_qM#HIof0ND)wob)#~C&jm2=Wj#QOfZk&J51CJ~{a38l+1{kp zOoZ!Xtwsv}5u^e9XvPK!q{vx&=5D0$*pqbx+mB_Qz&e=};RIM0k|Laknb(jaoX1#S zWBWIt0kSy67H^Xxp!eCqXUvybe#Q{~bw&|2VeQ45O$v7dS%;D$+#=Qqr0_S* zMeQFJv)N!FJ9v<}g84~O1o$lLCf04Ndsz>#e#-he>owLtSZiS=lEMqGre>sj}*9$-Dm`UUH+ zq)5QO%nq#fQ3Qe%33ZdgzAkeVa}(xdQn+u=8tB14`mpwA9mHD9I+68W)fg z;u{j!h!pNyGIu0}`!38G(B9-Bmkmlt;bA)Sy`=C^!Tcoa2G*UdZ-s`pvl<5eW~@d_ zSctzaYb7{$6?arr1XNT++z=Gk#K9%C)Y4wd zCCeoH#`k;n^PJ~-&Uw#!-k0O+ zqrP7kwK=GkZb|N>t~*v-s;cYE&3cmgqB_vJYOiIg>$Vj8&BfXP1U;>F!0(sZF#LAc zQ`CLtM7^s>x(UAlqe*?q+-=OqwZ}FY*Yj=JxPHJk8`p96S$g+QIotl2rFJz>*ykJ% zuw}NkwQg0>6#CCl>Gu~K{VK|WY(-H&@2)7*%_p55w3qsspF5MHelU=ZMSqoQ#>BLW zc*ZEoEg4;qIwmk&QChXwi_7S`21U_WOz8xKI4LBibqX$HPE+J1L>ji3q!tKiDRPD< z;nH)NB4z0@Z=l##aUycKAD5hR#=J;1#EZ+r-Ei6JbcBK@EyJ}>B>uyT%hq(M8ST-T zXm<|!V2|mLi|_!|5YsaYmuy%4kZL)ubp6Tg)@#6(!0pS{#MSqGIMzWWOp= zh;0NyTCSv!-fa-#h`E0-3X5`?6!d<7RBDT<8i^3MD4`|_m$DNd7vRz>DqYtTm#wJM zm=>dP>3f}WFE(el996Z@jetHr3`WfF2#qQbm%pNa@o`5f$5iwnKE5XooK9II2>VvKlv{rz;Q)#Gxp zXmxrgT>fn*g*vE;2WN@vj1{;(EK=mf$HZ3GD(zeT z4FOt6VfS=al=iXnQMnc}n0xX6lY_PD^Z(>z@n*o)uj@7pN=DCzk=y+RevFJ>?0jnk z^^!%PU4zRAUq__90sVc(+~S(4CYZmu5|dKU>C~~Lby_IQo*^11DUGc&v)pO1CvQU7 zguNm~clNwF%bk|g)B#}?GOQqW`T`}jQbHm7Dc^k9-Fo!lNk}n81`dg>MvAEthOwcu z5oOVc*cphLCZmekB0Hii8m-uGM`J(CRFq(9H9Ke~c-j_cuT+#hsk7MU=u7JC|KOJ- zwm1efM|QV_Jq7Pg}K%`LO3^xRGvg>FV?5 z)ENEu}mZ_FXh6R+7Prp<4Z2k{oQ@a*$h+lbwtMc_g{made@7 zoFp$hjbLQJKO4XdyrASp$j}hOdQ!?EN}mE15LR4mE&$lG50~mY~*>GT4() z`Thx#GTB9FS^q>y+3Xo=j9*d?J0AfhNy=pJ>}iS&%E%&C zY(C~q(VpmTe&|hd{oGekI+XT?Y1;3=Pgk=A4{NWbnO!&^v;n20cU`1XAu8J)0%b|k zSiTRGElFoLXMwtrDVdZ3zE_4y%yz`^7@_0VROZHJPj50SV$ny&~FN$?Hpi7u6#uR}Xz`aB?B(Z;8x$=!(HV#)O>yw#8o~eDHhfaZ%xQgTFr*e95Yy$;OA9DT$e_(&2h@ z(h^zEaz#n=FKZ=w&BmK^6BE@q^OnTKNCG@WTC&t^FB>oo6wZX)w2+T&90N+*D02B3 zO*Luh{e;I1vY#OBv<`BNve~cjhiRQ|6De~P4^{LyiYm6HUgRkloh z5G|C;CraxZ<>v;1yIS$PRQ@K!9>^9gCbLi652Xuq z6KyoqHoAE|$s75N8rnmz)2NQaDv#;~?xWL?>!G76zd9D&Pl#C$oltpSXlS6o;!`T0 zhOrFvx6;3$@<(TZ2kH*dhqEd#iv9Ew7}=25)&c<@TSYOoSPz{V)v(~p2PR)Wn@eCGi0 z%{sCnerpuJuL-=~ir*f^H`Ib}(d$G7yQ26w8o^ujz8GBCc@)>l<~HfeMLhUm1^70r z!TY0lE&16ybWKCYFal9rr3y_15Fd`>e`5Lz+^OFx)aqyy|B;4pyTvD>_%RacE`6`4 z@MIK!fn4Lg`g&2}*(mNNlX==|@VO{n7Y9D0Zx!(uqIlmZ@N;@}WC&GwF^b2eA>ai) zUhun7{CV;+=k(hXDE|E@{sVFbUeoD53G;Cje;Z?QgTIL4FOf)_S zNVkk=FS`oWiRJ@AR8Wiy7tz55l;W^R5vCMVmFRXce zzYd?1@eWvf#(W56KzZya#?EKm^cjkM4)U#s9yoj+nJ}(7;rbjT^sW`zknm0K}B&T#Ia4#)5M(9 zR@IOCL3y$SgKfd^CFaW#9E!aMvK7N1yxAEdTXsje?o3nIG1QseNiH-E_IxF%^J&>+ z#l02zGO}XWX7jz&^qiR!6eY_&S4amv&j)#={KITw8&I6=d72V43ngTEsoIzet;}9& zNs)ojpp0d0*$&Li%R)3CQ&0P1xRc6qmJ^P4Tn*1)vVH%pkjWB`9Mr>>5eivRgX?J2toar9AW7 zwB(7aq9K}Py;(&nB6H;(ox--4f%-^N*+vZJvc8fuR)PDUWqFcxb|M2*APY6vKbL|A zN^-Cj=Ir#gDL=!q9Lt8v8pJIv_1=#}%Z4}CaBZ%6JUuzG7JA}XHbW+@k&#woW;Q1k zjhQ7$WA~?^nAwta_BBRnnYD`poB0)*{#;io@?Kfw?&cz2$V9?D%|*_h2im(*jgXu) z_BbqW*}mp7^>(29BpGZhid?o|l8x<~3A$g3+pgHX(8}K+MkKd_U9+1ynG>}+9) zxJRhZRAoI4`~Z4h-&LjkYAv*cw;l@2QX59nTzyjI)BAw4oob&Q6mU-EKa4To@6bt| zXST>_6LFy9^?54wKrH9iB!l}|jOG0AlfeDe0Z4|mlEzH*yjYWeSL$`~3+3Y-442|t%TnKQ@#Y*`~H?Mz!?K80*E%%?G3Mi#M$>Ot+_7D}?}Cci{!yTgvWgOR zH&m~&lgwAje!!}rv9pY;V2@(N8#8^7h=wiL-+F+udkLyyy(wk)Q6Xg(B5T+Q!ra9o zat`|r9dGP&hoCz4EnHV)-a$bPtOVB8m@l2x5;kBMsNZQ3x10rIL4|LD#C~4|CdbAB zaBe{C;B7p9uG3-F_iYrmK-TvXGuZmx%`@2kuIA>NR4tc4HMkM7}U zm*v<(P{Bw+{@4Z6>y`EWWjliGKJ(AagvcEpMJX63M@?a;Ye3^A(R!@`GqQa!hWQY~9Q%rC_cs*u~<|tb$r1 zb94c(lBd@NvL3fq%^eXKD0uN#cj zO~GoGN`hJ=mmG@Fl!BX^S1NTdzk;jbHn0{M2{C9A9`7I|CsU zF8>u-NK1A>sR|pV+8ONBa?lD+8L?pdpd%;}q5EGrCdGa;!k_9#rL2lwFhwa`ogxxq zZFUeB3ECxQ?bG-0$MYv91gACm^URZ75Mo_F*ad1!TdQ)47-ZUS{ZZ}!f z(eHoiD6r~~>HAyh757OL<6SpMHmm4=vJ7s{avc`AZb-Abem2|e-Yw+&6XIJpN=~il z-j689v96TeW!85K7m6l!8Uhy|j&4A@?Bi%(xN8es_8~!}OrGDMtSjt}OyRp=r0a&y zq|4=YT#ltCg~NqTpcGwU=Zt7o@bVLv!p@TE1T3~uhi=Dg?S{QIy=;BLj zfNl%Dd{`~et4Wpe@wYL^0dAq6zX1&k_%zxxqUQ~*%7Lvd4D)pJa`&_fs?U|zni=R@ zUV>bfD2#S%@)D&o!cG#fO8mAC;_))EqW3!fYF^$bx+$cowqyoIHM&_O@#f?niIHtE z0dI>g8I;1yZmI-1`v~%}m*L-=$Q&l@{(`^mvw!Yd?YFoUE*A46uT3v}x@XKn;ANY>ST_N6Yx6R&ay#Q14!-H?Nce zNQ*8~z zl9n(#Y?{|fDrM_SKy~kllof0`CRT3w_)2!w4_fe%h^taGgXHcX3_VjdqX)!cpM#$- zTo|!#lX|cT(-ft9ODP70JrButkCiu5xQ#17%1Y;A{Q6hpu2Hogz~xe`MV#(LwiDyz z_BRi92m|I$k~)OJeg+8(%)*|jkvFDbK->exkh=%TVTD6yNM0n#U?V1h1~(5mX_0$~ zEErB~2%OsQ4KOA5@YuR(b&7igg^&Zv!=Sl~-&KjySOUDPdsLZ-OII9p@mhvre$_K6 zvK#u}Vu=!B zQSkY0v9QOIIKM?nfnV4>2FK$NiYZT_N@d6wLj>N)a}aov z5PPBfLo6FpoBIh8GFI0i_7;@JeTu9B`+_0X5?1eirc|{0Xo%g{7WkS>d@;nd#lY9C zK7`pF)Q)dzqyWNf4m8gFt*m%Wn5}|IxWALQKFs#n`hfp45RFBj!t6jD@Fy9)In38n zO{(=cY-^a`L=w;}-X7+e=Ci$rMADF38R`!54J5wKY6J`w;QyuEnd(DkylNnz(5mJ-0z6PR_W+el2MxJX<$W3vFi@ohoDtfHfcI<7^SKGpyXTTU zB&mF@`JdduDI1_!L9|b7%XIvV#6qh5CFYEdUr1kNu=eKEKD~;QF(tu@_E@%OipprWlA6OR)VT!NKfqvY3q6X>|*gxY@EXne2VIgSa`XfwV+?wvE|2 zuZ_CN9GRC8yAng+r?YhR4jj5!l9w4ZJRbt<)1B3r$MRBq*O%Zn+uth-VyeOq?FJj; zVdm!ddA>+R07=Jp6cge2E_A4hgqF~xDC2v|wiv7uwlsbK7PG@` z6lLtFW|z9y1sZ*0?EZs{ODLE}iBQ;HP(-E9wokemnxA}U0_K5x66=h)O7)&16 zzl9GT*s}_$?Pu|GcL`>NoT-fNx(9Tl?Mmt@RWP9Y62w!HRKb8A9}4oK$T9soMYdtW z$rzBzwqeuxc>3}$AJmW-YQ^|1P`2$}V8 zNtww#(H`#Wq6#Uc9v(RlyI4Ur@>zR`UUt5Rxx640wGOQaPVUU6n+FThBd>raXOWvn z3zc@&kf`CB5~fFUuBlW`O2dNLifbA<3dR0F4{X>&7E4@X+4)IGGOl^(E>ni_Qi&Wa z8cxhrDizwvCgp)9$VuGAPTvG7|9cMA=#4N90&`Vt>?uXmdl+cqaY24on-7}wvY;S) zGzgk}Sx}gr8w{!%g!aU_+4}9d72g~W${>4yK3c*O9hKx37RM4D%mGfL3OgfRjgG3s9sVH z`(hDjzN9&9sRz^`oF--0z{{rq&s(^JzmN!g zQ&l31hiU*pY@16sHGB34ljx?Di$c~%%|Mg}B|od9R$Iwos# z3eWC(L@I`hJzt5q6LRV2WjToIAMLDrdrPD*VHv#!u+*AucCX{^EgZa|_sz>FT) zP%v?xqU5^nWqKM??3VQ?Y%uBS9!Um!4oc(NH?bFq%fW7f;koXU^*GtTE6p1i7O2PU{c7xmV@azuZ}UQgf=;h$hg zZ{TwNb>R)9y*S>t96U~Brp-8>pZXWZ2^k$)bt4`pWG2C>+~Ccob8y?pc}$3b@m3Ky z1k-~0R%$WMzQxV{3-4F?O#Lr>Q02GN05+$`ftW08Qw7S@cQ9mhASUs6Ex1CQZFo~_c&FgCe$-bAB2Mx9{U zXl42UIAez`Fi++5FfmYPnUum8lRnj}?enNIgYPhp4-H2ihZ6Y%3sr81X$2Np2B+{I zqkxO8GnEG4i}C|YgfQWh_~WD(OI13DgjEa=!=>Lq7at9|1(sQfy*wIz^9K5q_=%XQ zx=d4)HELi@#A@ZuH(EIo(h97#(BNZ9jo~T>wnK+v03_T5p%oZ7r0;J3>r>-IhzqS&|zcw9-4_dJed_|kT;1b?;5%7>I_vDuIQBaG( zVS&OKoPov$j#vz5unZGoz}z`JF(S@@Jt2w}2jj#Uux7@6)05G(DXhh?0DwMETEM^}hACu@RD79ER4B(2V#LwQAys3NY4b%U$3 zD1s+6^mwf3xIA?|htU8RouERoeV{TL(4t2r9+fw7f_YZko|FaY zB4k_q|A%N4!v00Mo}x5*=p)dJFY%Pd%4PsxxV;<2p4HgwnZUo3U(-X^H1;~Yd(n#$ zuWRf-a8E@q-P2w~H|eYsykOD!%R;E@_2j$Yc#1CE5X?qBInz`}h2pxx)|$i7bAmKin=%J?3cm7i?SPAbyidXe2boR>!IyBOPUOPo0j4< z%P>A2_>N3`N@tVOf$vH@qq7+kf$vFtL1#|5>!M5Pkv}N&S#*QO>avVJ%h;=!@`~P< z?KsESLvWBqAIMH#VC-}X@I%r-2ph4aNFPbO!q~P+z>mK_La{$G*0w+J6It>##(v8O zekxbM*O`Vp%(Br1)99RX{*vaE@2=6Hr4KwMZQ)V$I)9nGTXnFnlR-EA{S?J{@j!2` zlD}Lo!hDQw(DEB!7jbFqz9!HLIX`8v{pO#e(<85ULfEQDM9H~q-8j%{5VWWf&XM6?EhaK_!^^eukC%k3y%g@pBD& z7)S3c(2-+rAkrQuU@=UA3~R4m;fX@O^vcpGyZ`d1TKlx;?OlWUn=Ptp|jpb;7=`Mr~}1htbl^488cTROU8?k zh_1-jUW_MNLeztEgs8Wo#5g*v{aSBqqu}7SxLN9%LqX(VkDy&Wd)_>p$Y3|ugL>Wf zglGk8gbaK3enJpl52Bmop1JP{bg`LT&D+Lyi%DoJs%ekn{I{7G#%4t})QXT<6henQ zG2V;l`Y|XAu2<1DowdaEZMcq$#=4QtTKWSi8k--%dpQYGzZ6Et_`4=bGT5lmApd0{ zK?f^F#a)xSB0cTT+|(HqAg#vw-o@^Qadd4nSVVeRX9RZ*N|pCP6?ak-=rkvq;6m+w zI!K9YKdv=nRu)2Hafy&l6gwIdGp>7ySkhYiYFr+I#X0>RF`4+|D1^lMM-w&@{oZDI z9y42xPs%14E1ou7^e1?&7>=9L($j(9Z*sk9h;o8|xG}`EQX61S9v_JO3yK}o)m;b_ zONbAUGiaz(8FtZCejot0S&St_cj$W1p?-yASfXPthn)qZ#8L@oZgKV=9zGbY{v_hD zgy;ep1Y@l9SVDA$*n%ys^oP|r{`fEi#9A4!gm|T!8Cx2N^qzoVuN90n#H}sB@m4ul zL-gzpZe^A8g37;|2KHI$v8Lz-KN?K5(&MnrX6S0rZ>7JWas_4*OtR8nRC!0LFKETT zi}Uy|cS1n2nvQaC^j75@$`A~z?I33?I?!=QJeX=7(7A&9qkM3Ci@#90Z3?)fwKVz$ zTilq(Z}3&T#6W_}wBmnM`C;}KzSdvm%aN5HCQZ!VfG>38HySlrb0R>bz_LHrcy?! zg`(S=Lwq~TC@61<>8T1IauaxrD(AlKAzs13+lKkkoZ3o$DsXE#UE5-PbH9iJk%;e+`mcb_20CpI0E zdq}UUFk#k&fl2Q9FOf2hy^Uc^?$x%KO37gKbThfP+|bHoy`n+6r$cZ$ z*jP~P%b?r)YpJ1m%-se?mcJDtWJg}pRz5zGIuDPR{loa5Ghu5Zg{~lycf-heiq#3K zXeoaYqVSATtPj2aZwYhM0?YLzg`zs+=2q{0%6HXRL)meykBV z&O+?wJZyeY-a48@VYF?=$oGaaj(SlKM(XI@#5M<`)ywdaXixlM3h{8a*}MjM*lszqO&r+FPgYEMwR`$)NoiGG9w2#xVO#Zrg{>Z>Kn{SIU%_z3_P{QKylpQ?N5y+|F(%=UoDQ za|AiJm2a{rnzf!+mXBBpMt?mb__Za>@p0-POT(m4tCuq9Y6D8aD&+|339Qi zvq0TG6y#<1*MPeJD9FbSm@$>RBF{p`g~8rJQ-ZltQEL zaqyD3g9%=KOLR_AI?qE?CZ-u9_)$i|05msaOBSZPjOne>I>mkf(SOEJ6<@H!u+QL^ z$)b8i&R1V$T@pGSWFrwA{95)GHJ(SlH3o^|``8)t>y+Tt4Z;K9uy|jye2O10axaSA_CYsgR�)*NzFxk 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 skCcq>JJMW4e3lKau^M=OA``?K!kN^Mx diff --git a/patches/kdrivers/src/wanrouter/wanmain.o b/patches/kdrivers/src/wanrouter/wanmain.o index 160da87a10d32d8d72d2b38569ebdf6d96459eeb..adc3bbeb5083ac5bfc6bc01b941c0fe0946e5d1e 100644 GIT binary patch literal 243645 zcmd?SX?Rpc7C(IN?WU`fbm$K0f(`^|=nhFRkQE3afk46%mJkR_SVPD{0wD=W2ZD$K zAxIlgR76lz5O7d%Uj`f%1Oy!!MRde{nb8@T;E2m8&gkU*ovP|im~sC9=l%44czH~B z{i;r#I(6#QsZ(|9wl|HPJWkhjE$~m*Oj-xhw1fkOC`uEbaaz1KKs&SUpv*+-a4>Z$ zm^!XfCubjJs5a{u)%BnL?!XoM^MeGRg~`W@PXY}Q=;SQ_>AjRney#AJ?&Gb!od8Gw z*52OU@}bY-ztaA;|K)l9R~Mda&33jN_pvMOo7bU@le1cm7y3^&##B<}i$8EqaYf6Ajidk1ZT_E2n@_ph5?Y%{9!L{cIDMSqW6L8s@=X-iS!`(gu$KB^Bs?mu_&?SDg+#~W?_ z_u4u23_Op|J2}(;$JzcfvkHIr6__+%p0F;9WI(USqiO$VF&dcvnC;Zs+wH!{%3KsZ z{kO_D@g))!iuFEz?W=4ZlTdN&O8Y^haRE3#3f35#GmQnUx6%-{yyolb{{YkPEy!Z_pJ_`k zY+q@vd?V03X|1H!<378P>x{5zQlkGosWkO<6)HG6b9Qn&rg~xXWvk!mUDq@crd9-I z$zQdc$2gmj)O-zlv+?!38*@W;^|=3}Z(#EAqpuLxPrp0V>hvCUVyOM^`9D?^R2ik3 zZ)lqn5+1vojLH(=&=y5`-%?(BAWw<6py<*C)T>+($fy3T41m`ANhI{IZCY!g)qkaR zve$g^sF+IrGxnDIP;=`hYfu}J7*k7Yj@gei&VZxU3hP01DGdZ_s& zD%5;oEni^}+S`5kZDU(+y@;&jcIe*f{~PJvf2KLptNBt|&8pvjQ@!>v(Wy39%U6xz zm6rl?ENo-`i-Kg1|LQzxdb3IG{AS6)K_Lf2-LE-xJ*`udSx3`Q0_MdD%X;oc^ahbio ze#(6pRvi1fofN(`pm3=Al3lh&qWM1v$nlDO-442>6?PAu{bRGH(@`eqlcT95c*dQ->L}B?V`fMUHT5i&_cd1j{o5qG7GA zhY*!iDoWZMV)C|yD1q9(oa?_jM|qduW02n{eEDzI^_TacZu389`}!}PJ-u=kK;>fr z6=SM6sQXwFFO9ZBS=m3M`!<;JbC4ujROX<8CCI zZ*0OWy#uK%?R#BY=?%28(nrl~Lo-3;(7;^!1Z^r+!gpr0=KES_HK~loZvKT$)M~J~ zwiM!WtP>Z}tD?E^n<)6Ia{=k2ctM+2&F8jW?NWwbn2y)TfC2Jfx%4EmuNmPUN(%eN z8n}u+>SiNFC;rsa#>SGX(udKO&CB+3CdgVBOlY2 zf<*}Zia$!xqW@k0n};7kyztMhKCc7m|BfEQS}A(?{iP(ZNPZ2v{r8VzeK&jUE#r{a zmRVR?i0{C_VKPI=7z6=V+Ha-!dRFDiKrva&#WnwEZ-?frmvqorW4a00pyV zQyZTKss~OHB={tKC72D8-fCvr}f&BI?@Kh_6+|-b#D5Fk^jRb;+Nx*eB4?c62kx3sy-Irph;hs*pF}Jp%Ge1o~K+{?{>gzTvw#B6yHsiH5j5x1L5F=r)p}w>o}@mM%R$1YODP9 zY7;6OsM>c|;d8d0q6)A1#swv7f2*zk)=gg@q?NVrs==-IT_Lr6=<~L25t0c{|2D?D zZ8oeO_S4>$j|7Ocwz10o+cJ@$nbDSt1nmym29k3MdLjR5d&{MNK?7&;aYh;lak#XP z9HH5}{?s0zPLXEvhs~GG2=QBwP{F!Untl7pTg-hk*ZI0-p7ojGwPtTE)Q^(GXq)4=Cgt)Nl^P30SbvBpT8a<$E^Xr0{GytUBM z)?3s$uE@eHYE+2K(U#geZqd4m#;XOSXD!k&%+urVI)VW zzA)+5I|b!=pRKi-M#aB@K3kh9xAjhugALFo3>C`WlbRD1Nd?6?8=_AC%GpqR7t(R^ zaiS3?M^M56{JZw>X!g;rzg}G&EzJ}g9t`_sumAO})!433WB#wdJLLabu9}#3U6PMa zY;^eNdtE|774X_l1KT~X81vc5=L?TgRNH)chX17hul{qW{HOJQqC*kX$t7~LLFW_1 zS|bPxqA#z=jSJ)skhy8l%0${=Sa|?!&*2WGmM2qO3kkkB=-G1BqNQgmdT_86Nt<(t`@_MuX(_b0# z(AGQTKsJ8-w7&U0Ibbd4U!n!f-f|o22Ir*zv`;LIViMXBe=C`7ZOcTHXGF9`&7EnX zkVU2_P9PwN_fj5KpB8G<7a`!*y9oHV37ZiIglAer4diYT1}kl%t;wmIX3+=!C20`u=fMM%>6ea#uL zV?l9RJ9~smE{Ws6Lwk^9vTk$EA{MNSK2v22bSk&P3uEIaM%MoJQ7BzjAbZ%n;dKFd)#|4KGbTh%k zB{~KwtegSEsa#GUYv^MweYnwD<;_S52|E=$K&9Cz6$NL+%tX_gOd%h}FSno+g7_k& zJdXr870nH{9!%hD>!dauHOJ#`J^m&j7^}lyHfnu;qxeNEZGP%W{(w$_(e zR=%>ly0&h4d5teIb#Q9ps*;+zs=D$)NDod?x!`B)>qZ}v2QG7Hu)GJ6SWMM;}UpzWzM&8u?tOj36y-#H1j-8d4Gd3%xL7=?+8Dpo98!a=W z2HZI%)z$8q4dwOjDUjJ6(}4f3k?KDwDx_YLnqry)bd5Fj(0TOM9UIdSD>Q>q zDz2z6hsyG2PM+*8m@(bmkN$P2ZTj@7(-S&r8nV=umiWru%gXC(pmnJXcSntmK`E`R zTkUQnxl3znDyo*a%SwDDG+L@^LmdW7Rt&aRSlQ^K0deQnuBz!^ssH=; zs??p|xO{PW(A;9mGTh3lGu)$dr{v`q=S&!zGbtmWoepuwO0DJBx*N)UjdgBmDWW>K z4;m?Qn+m-8R3yZ?ixqN;xRs*?J0snmw5>tPsGorXb?(`bkpA_k+P zzIM4B5iu11C9tIazYcLn_kvPX)Hc?Xx%;`t1;i2(WnC*1SsVIayrkS$ym)nSP08|d zx3txuCT3n^r<3yvI;M4yhH~rbYkjq)wbkyLS|3O-i81`wmzQ;PNtw*G_R>*2z0-6c zhA^!`Bk41aSi4E`j`5jNLNfhMOpJFAp{s7t;_=GltsfRQFdZUeioa&>&%BO+#Z{U2VM&au?>0E^tqsndgp4 zN+}u?{BYOSbSN8|=;%!6%K4KE@^amnVyOEoHLmsP4a*icR#d>37nam4sa;;;o>5*} zSyNkGyQHeT0lv6Yiz|(HCl4Qid56{e=2HuD;(^-x@aI^v|un>FARF%~#(|>YJWr(7%1^`>6Wx%Nu#f_wmvJr zyru+eV{QFntZJDxr6Q5tASdNuL|h}UtrkSE9*W|M%S(&vYOAZsngY10p}sRj_*dgA zF7?%4L(~y=bfyjXDy^fKEEbJai7o`nugScYR!C8?s+gQLtpi%;I{#JpD|Jiis)`$G zOP3+Q`>(2<${DMj`}L(CNBTGSJ#x1aQ`*ii%ZJNikH9@t}0ngG8Dth6@w?T>&qJ&L>4W;ow9<% z{a*>xSKfm>9<)$h?kg`2M%u)zb2&BrKMPgmVBdbF?yr=Q&n))Um(&Q!Rb%Bfr6qL@ zjn(Mof2fe+3(To&#x#&8xDYUw}Tmpfgrxa(Fe=^|Bwid(f{bI@KYc75jFz3EL<~nrDR@YI+jf9n2kUBDR{*PIgtL2aRe-oUWJRhILCpsm@1|twB4vr}BpNpOPQ|2) z6pbrM73|)rE{J>dkli9yfUXW=O^XV)iISd5Xt2?=UL9m%Vc}u6Fp@Sp65Yx~H+z#h zHLVY+Leu(EwvZfL+(SfOKUE*v>!{yfNCvITUU`&c3VJ)LV1=i$0O0_X1T`2Njs{4Y zxJU>gImLGnbhI|GQ)>|HIo1Tr#f(`+Q zW*X6qvWX50@dX`@rlxmv!2m4m4Z7sWnUkrcN> zf|6hSU}9NAT#N7kZndRqM5rG<_v%?x@9)LHsYky>=?k_nh&QQOH_sji^dWpYVa3A ziN0FsTy)gTLg%N`mtkIm+_0PRq1&j67M|CrX%8h(I=reHem3krBtx_JgB=T>ej{>h zloK906v^=CsqhUHn!AK|#TKr2S5foPjYxK*D{!j4@GaPA^^O#UO?ZUSn^Vp3@yn6y zE|TjfA=yJDvkxKZ61330);o%lhIs&nJoNQ^h-wLce+KgVPy^wQPC&A+NWPYbH-X+{~0~QjC5O@Z9(<_|raE8`w6-+)t>%F?JrJSJ&$gze;fk7|FZIm-&5!&n$ zo{7WbUJ-)9Z5Y{JvI`F{MA9kRjGl&M4{9^q;zQE)2de!8TClRN4e461SZcCsBT{kH zRM*Djp<1u&h-24=)D*4PAnIM$MoJDQj$IpurfI#Bh-24AN+uJ>@Fe)^URijMq=nys zk6vR$GX5~FiHC_`1L{V1A3_BEA41Y~2QtDZVd6zcVSu#omQ_ghe4LUc*#1WMdYO_l zA4IY@SwQ%MPaxTco&kj)hcQL>4JE!)z$esaiY+Ji2BFC6i&R(RHFjV_|I3 zEA~?E9Swm1hq&rUPM@R(WgZ#s~b>9abJjg@sOb7+p^V4#z|+9(D4Tu22vXd56T$C6VYwSl zH=kkIuurg;FUEzf$ZAjQzf#Y45&aN2e{N}_GuD1 z?d2t?H(eqZ+qV(%VWC9PYzaDHpCOT({n7$7Qz9?>D~8uTOQJY--8`V#5+&HntI$G` zL`nA22F*T)%-!&$u}zPHP@$o$5W{MpD+$vfG^)*$DASG&oqfKnmdzTnK&a3d5Nh^C zvM86Wqox%aXD>rhi7cAH=8?n-O|(~_Xt6As%r@PPB8BqpOHfoQiwal~POAcFx@LI_ z1JFDcQKh|tt-!RmFQFXaT2CNBV6GlBRUQ(uG z8c~0(@#thw%_hx~j{$OHBnqa6vsWHQu+~*p*Vyr{Kz51DY#O}PREI=X_UvOo5fa(h zpk6@TByzC$u|Sa$IoTvk#;Hz;T+Bs0#cG94Gh9H>rium2@VHqu?02eIvkZ@y`S%04 zWW6}H718F@D2Wo-U*SZj_LL}zt+^dY4OJQ&MY5=&N@q7?;hL(3DwFMpE~cuX%4W2x zPgO&e%N7m>QbRR?8Hqq@s3vRHg-{YLn94RI8iCE-irB&_n%1p|kTBsEBx(XC4Bu2! zM8#Cu@+>|MFM$3dd)Z60$Y>%Xzq2@)Hf!BRAavO_93^^WlD#Q?s1}(_9-VCd_5@9f zOp!=uV^e@qB{JC6en4pwnb=PgfQFE?VPy#qw!u2{kQwBIj!VNkblnMWxL zFkiy$a0}GU;3!%&D|M8l5`%Botjjv%Q5trwn)YrK;@`-Hy0dgunHE_rRx%8mvw`3u z1SO6wJL@>^-t8WeQ#v2e(dJ_Vy?ml|~v75;!f^9)K?3TX1|(fRw8 zz^nA{Q4DNoR!Rl?*jKZfZJqEiEm9BHv^!xyH$+~qy1YiUrMi5Bf@)yaDyRnLMg`Tt z+@zoym~{%OfmyGh8kh~ifq4xVS|XcuGCspo&HHwS%lU$tol0x?$-+*s)>*&2qiP-R z1D_P+w1ShB}--pgew&>EYG{M`GqwkS{(sP(*81~J&>%$vCfM#_77V#hV0iM@!2nZ1u@v*A_-_g%O zVw2}HGp8UT@{fX-$@7JozcC5;U4<{2dG4-G__CQl*0U47V&=!m&0f$iK!GOD_h$Y9 zqS7F~YUWGl0>7`nE86?n%-~ zmS#H~)L|Srv0m))bvW6Kz7PJ6R*6qAM6CD20+~ge#QIPb!((OSAy{9DZ1&Q+Mvb{C z#5X(+w&H%2^}{FvIoYr+Kwh!~!{cHO>@`{3cLM>^$H)0S+ZzWYaU$GjnkBPREh9{H%gxL^;xjY85 z)6rLzPUb6c4&ZQ`c8G>%@Yk{7cJx=Qiuh}=9*4(7tC``M&%YTC=vD15;zdI{!7@H_ z8eptx*mxqY-@95z-gi*HOUtz~f9KM3-LG`9KalUeRCH`E25sXX-hM_8+`vF;Hip!i@{$d6AR#N z24}Ye7nri5sQz|?_l2KwOjq=~4SwC)PI!;OU1TaVRD1gk{&8X_e9+(@Qh#R(%QATm z8+=TE;8~_9s0I2moQA?-=|UXD9rg;ao!X=bGqU zG?V8egMUwRB!E9Ncn(e70RF<@uOk)>;)@2~ia^aV&ooWw_cHWDGjP7iCi;KH;3G(X z0sOteHP#7VHF~{)IpSE*VM0F}JoON=7MkuHNFuE>@fg^OW05IlJmHNd{`73%5`{OL z`0uf(ITo8_z_-Q3hm#7*l+|uC@zbd2C^u1{haoZXH3xy0s`C9N{t{#j;)5ohO0%Te z^vM9CKWyS%yudZ4Vt7cHtceyaN1bW5=<#tYZy^h)Hye~rb*vD(xfiZglMvGS{AAp!i6mEYI`e7!3F!pbAC$#JYP z?Goy_Y~>DkO2=AdVLw~>h9uw{O{c_&t_$IP$iic!!?VI;gz&W`z;`NqID}ta1$>w3 zQLGkFe+WPHFz`-=p9$d)UI)C}^p0rnNCq7ZOa@ubxyg8JIEC)Vs`cm-U7RvwJANYOK zOd-#9;5y(BOtC_qouT|LYX8H4lMdyR$Z3D1@Sae5k9jbZ z-%Jb6pG`|d`4gdhZ3gg{Vs(ax33b+&HfoN)n4U|f{vHYC3o%fRORE0yP@YAL#@D6> zQUBFY?jR5RjcK*OXG0OjPy`cA!HRB}_rdIXo2|4Y(;lqP5}1`{xdiws9y?JPsAG#YN%|(Zp+!!3DFjKp}q^ zZA6qABLyw7BTj~ys`Pz)GbBmsrbm;qV2UtR@7jKc5g2k72G6mJR&ucU|}j)G!3JWk)F zBSi5HQFMu5U$)|5g+M|W%y}IB-br~MfFgXIRnzVrPZ3r4)K$3gok6jlB?X@CAqyCc zu49v9G;Q<>>V#9w4w(;A0cqytR*w9fmRW3I71L2P$^YBS7ke$gEjz1EC#W z(b}h*B#aCYJ_(=F$GJgN1K|-6{wtmcdoY^`MdE=3aon^5NIsMBfbeS&J^+Q;x|cKa zLF_beyeymk^BkZmDyMUe2CS;xmr7*CfKdY$2WCJII7f5$T1HH|*GU3sjV6bAp**o! z7(B5FpKvpt-xX24@L#ZwT^F5&q-6s>{JH>3 zY6`GNA?Ug;MuwI)E!+v|uj{>)3e9)o(?R}1Ja4j5%0?{3Qz9F&15pZcEuZ5f9}~lN zU5c=y>r%;PNKt})nq+U*!XGFE`=Ljujt8O18S?r4BiTw!0#Ew$N@t(N0gaLz%&dGB zP`2b?)hu&S&CSuv5ecH&h(R*`*4P_xFe3(&MUkre_<<5hF!WN3_${g>Fn5a48 z0TraPH#JlvF*%>pxq1|`u$@rP&YZMURIO<6e%g=wD50W zlQ~Y3EPMqf#Uw^_){lWnU1Bq2(yU(r2Tx>hhPfS+`*B!x!jAq-+o@?gJXC{}_7Mzl zN6dYyC+#rG9RsMQ;jysW5u)#im54F(JwS1E8cJi?Tn-dZd}({sgaO$xP>LMQc0C9r z9y#HZf_)9=y(2-k(4S4s0U8wO+&-A>j=>VeY1aK<7Zf`T_fvXfQg_7w>=?oB9|qD) zc}k$M9}qF@$dX8B-C!R(MoMI`zdL|NNn~OJM*)qIO_6q# zvwD!ABB4bc;}85E`fJ@WNj5J|$Vh7;dr@&pp!wE&f%1vk@Zi*CDH2p9*mTh>F9NU5 zA~s7Tn@U+x^`a`kM)YE-LxH;CpuLm#7QtaTm}5R7Q_1nq@qiONXx9_r$T! zV0HJz2OdgTCerxVpz_;?Y4M0C?3 zW}SiT!&DDS?U%h7=ut9b?2Ir;`bEI>n;w@LeQ2WXf|GB0Leg8=ANBw}DQ5;wU>ks* zYIGAX2Yc%v(9?1zJGE|<{q%4=*3z49;bCL&ggimtd$(woe=!1ZkbYG_C%>^6aIk`D zJh}ofQNbBvFSaU4m(BRN3*B9nqW?67ST*tdrGTmWZ!n9n?(2N|EZ{VKJv=3L8ah9; z5_pLIJApr=1El5Js$n`g1stmA&c%(moHs&W0DCfdu=6?wu~%j4k(hZV4|ZO6U%s2SU)ch!gvGW?52s~P0?7Uust6!C)H$lPJ%o_aNXMo4*pWaUxJEddL(yDQ~ zjLWc7+6YIsYO+phqn#2D#VWiiUvCriFBm){19-YBKW^}(b-;zXO_aZC@ZKT7GxTiu z6tT0ay9Icb9xM8Djt*&P^ev73HSIp=V9PEit6HRKySQ6;9F3)6vhV5+3xhh%Y!epcq+} z&T3&#y9RtL$}-ucbwIJ-36#wyU}Lc>PNH1)IOgN7c!?&kO?!X_hIpudlUc|HpoAoW z3fLqV_pU**g&8b)FwkIGuZR`a0wv0_`RpuAU{}&4QEw4@HXkT$xj`TnhU0JUPRL6b?L)$g#LxFtkGN$V;s!T@CN|ynR{zjDDz>YhCa;=z{ z;sHj(WWceFAQjIfE@D#c8Ykgq{3e?&PH@a*01g@hah_)*_ad)@80Pgksuw3t_Yr>A{r-gvTCC-LWS2UmqtkDlG2g;IWod%q;wnQ1XT4S zvMs+sHm)OTaR)L)RCQoPAgcOqyrvzqd`vkJt>0IQ% zC^{A)59~FgUbZZAvTgljmT()b|6QZmz&XE`9QAp>Rzq?IS58> z(wg6ky%~kjZ>{sPKEPpBy!ptmX~PxwRa65o-R8P*2$u1#$c5B zEAACVZbm=OkzX&%yey{-s6nDQ$oej1HOwTMg<5^@L5x>^A2w?k$gY=iXzU#vs^qVc z$jnAQ33P*GVP(_T0Il6C8nc1bW?~fz*ot;7`2*My1VQ<+as|gZHpv!87mX01u!KcG z@e(1Jpx#*Ejwj^LW3>q6^5=IY@u0JpFev#8l-TT^u|Nyu{w0A~3xJ9xN@8P5ffmtV z(Y1?Om~DQE)Oe_zW+eiVPwH zC=|6ELE@G9#AJiLp+qZao+Ei^o)3{&f^jwPXWr^tHEq9@#>aaHmfrm#G;Or-@I<6T ziA6*hmNe`BWOe`=-Je27%p}OWOMz15+%#(ub3x?TKa5=m^V^@kRT0_l0aA~<&CKQo z${0ue>=@}MGOH=u2QwiIFXH6n~rB1nEYik}wIhAPhe z<7Jfz*Hp<1R2kkAjZUP#lL(dA)a;)`2S5}YK+oF#$r3rV2m>p*d4B=x`5>~VN!LO< zUSwPM7qKNXkv->m!AY|hSCnb{=Sse2EoLo@G4h0?juXh4QDCp$Y-GEL*TCt1YgsI}-3P$r}7`4M? z(805TC)8Wl0Y)k4<-do(j^2h0%j4uhd>=!OXcFcYsljpr-4GH@j$(9cZE{aZuQ56n zp4>~$5zO%^*vYSjSND3E*q(c>on3=BgieYmjGTQ3XhH)@>xl@(8&-y`1(as5!+nDQ za$s9muU&h~0BD@aqU(Gb_Y`-?K0v%Hw9B85e|c znOW*|pqbKVS=lR8HfsT_g^V`&8KC*%bPdaA1~k}nffUolmO!wc3nyYbK?ekP^#xj_ zv}i9YZq#}%*&@o4*w9TVtCVHwZ1Ys0Dv7e$IY`lSsT{cpY%JV)&t<1X>yueJNnNeM zdp2|vWn~yp8lvd0 zV6-^KTnZgo9>B+)a8i!kVQkVCO&i-)szwusC}ZvN5Cx|$9EdUrR}x4e&J z8`#@iz1T~4;F)}Mz%1I)5m#^7Etti(Abb+;M{~v7n>5!z!sPg^6g_qLCCfO#`M1E) zxW)(STyFjZLP9Erdn6o*@D8=*Yt! z#Jq7mE8$KL+m;LXoP@hQtng;Q-%7a0!@h(bTt_6_?_sHxfJc!BRtG)IpAYx~%`7}* z^02$Hrn!!_3YnkqFlRF08c64zPA{*bF=0AI=qAr@ zuVy8+lC_D^#Wfrf`3dM&;84v(?tDI@}VGFy(d(^fo4tT@HVlug6@^wW5O zYPjsLnLYL!ps}(tOzRgAZ7+sJE+}BHLoo}c1=h&7VI2#m2W@abnx=g=31&2RAgep1 zX>-*TCABH|viREATsKtDW9LdZlGi_J|0v9q$l3-f;69Tyq7b77& zl8sW(`EyjuOuQ{b^yn5GAWVy8=TUpw0SSc#@U-Tp!pI-vxkVw0+IsJGOM2jv{2UbvMDzK73Yc|HUZ-G z0F_A>rRL|5ws?l(2lEc%0c=`VMmHSNl*TnNQfUr3Qt}~OT0|nK17nlcO$Kugc48aq zsi#X$)|?OIB;z2L7e-a|z{59c&2l|HoKgf_Mg+x>TyTfTd!drB>f3B%8sqCju>(9>0h&J5UWp3b@wBMm!5tE6WzK z-?swQ$=;T+>lXm6kf@UN$GlIim#CUO7X{>#TEbmX>h`KtI9_)>pgSwDJBT`FtXe@$ zX#4?mBI>vy_Z7Hka{%yVL+){G{2~lK>V%PvzCnxp#ajVS26uj&W&oZtq>f!Y%MJL7 zp-%DmvL%404XFb+pM`}n>Wr}rUr-(oeF*SXRX3Y2MyL^lx%?G4fT-7uw*~P8z5p&W z>UFiJtm7xGfM*SLJ_GiN)4y8 zLybVk=$HxjC+!%*)R#|S;^Pn=-S{^~+3^9oAw3zTY@gu+MKr+-^APd*3bGtz-uj!c zP8*S->@vQ>$jtRXjsalVhL4*2@P1F~{S0pqYN-#%&T8!RYM?z5nc1=dKo1f%spaZZ zK>K88ZEOmLCw2ex)C`tUthcET$^JOmqr^lZ7ki^G(7_#oNi<}l@Xh)VASJ{)%e3yK z`n6*;?FBtD&fx!mA9p0{FJf;<#(W3{=}6I~6E^eG9e}B-)XIO#101UVRS?^F!;^r+ z6?E`u#3GIi{okV0$*H%F5hB!u>*MS}z)S_Bc{?n{k)@!U??m+G7^$GwN$=Y^M(O5J zBvl;0atlhcb!krt{0?|I$7ltU_}?D`93#dIj)O;HTjI#k>4KHvN$2-q=j_PUr7kD% zv)2QTQ!(gdZo(4h$k)#cbDY74!;v|rDp;!M%OG<)}Hk$mIb-=SkWqKsU zmtpz^F)rL52=E(xs)bA07o-^nobLWNYGqN=L&c3{N)u zCp5;@{iR%XdpS_0T(l>!Uz|Wy(&t`=cz%T(!%VNtT1oGu0pWA5LoO-4`vTuoB_m#; z6Ad;?oDSa{^#<8PcjskiPAXwrJs4svI!LXwpjXGZ*1L~E^1!#P4J>V+!c8r;C zCtgjWTX3#?3mm>oH)C>lLw+7h{Zq(4}?X2G1F_1@G$X4$M5! zhn8R;?(72MO$wTM1ljp!v6ZKGi>3p%ij6$RoByx~@K&8}(2{?&!iXHVt1iUxkg6CaI;#BoTM4;OCWI}QUL z7Erh?oy2-nVJPpH`+*-9ouD|v>GQ4D98c;d%meYB00kJ1qoOhKo`ARnAHX;%d3JB7 za=5J>OFLn>t^K6n=fy~hce%tR`2dF78gQ^vIouZgsDF?iZcAL6|DCFjmjuM6`2c=K z=ihV#eE{QXO0>}lzo5(4F;43AvWCfXT<71Cdfw1OME~&8z?lBP=X80A{x~kN(>VQ6 zmp9DcGkC*T;CB_qrTB1KtKQdXA_$*pOa}f)O%dE!&!F}{){`-y(6>qJPMTbSX_#b& zS{b_!zht7KFpV8^13h+TIKnp^P0+Ti@NpSVS=l|gKu^3c%53b>XrL#@B$JuWU>OKx z3!j=V%F0+B+;jj{ii;f!YAZmQlUDud`1^X3WdLw zrAKu3I9e+_Qh*;PFnM0k`+bg?Q+SkaQt3J~c~0s5PB(PqSVYc{?HxH?L{9Hj9XV!^ zvkw|Bd|vV~iJV*ecH|h8!#<%}zatux=M|mZ2cs%{;ezPJt2!HvMBz))M9=E%v3$T| zdm)U;b56J87bUgA;~c*zh&$Xm+f$0tmz4$#c7z7t1jVyh1r2to58z1&UohB$I{;5n zFlzF=YOvR-JFk$h#q}MzX`n9948mj%)PlN@v#obW4%CI5CKBT<$rhYS zKj#>G9ASLnCuGqWCdR&=4fv^qUobYV1@N=f$EfssTtO%X{9JOr%GjoPfPa#Ep`RK1 zkvM-LM-8{14Ku9|R+`dua3t2Mu6X|)mOkZm&vRGot^S%ra&{GAyP*4$FO!B`d){!$Zhzb z7tEZFfd*fD8=P2z+Nf&05Q=vUQqaub!Z14qD`@4@F-aWB3flM{*pnkgL5CLEeS)UF zya@i!F~Z<<*5t?(yI9)jh}ZqH)b82L(`_itH|T{aTB>(KydZS&g;{`84Z74vOZAUb zTA-ktuNek7&7j*$v{{+36|hjj1iY9GDd_#AEsl2$UV!Q1xL}Yukrd(`#P`&3fSF(D zkJ9%IszFlh!nip;5X7`V^4A^!{?J&DV$40fHBKoSI$>9M3bGBD{^T_Q!%St@(d&=& zDxlfXZY20a(Q?9Fuy{S;sb|ql!ic-TO_M)DVE(8p#%APHF*avVFOpu`tDS+-?r|zw zcETRsMmtt|GmZ{~)eJGrLPKU6LA-`K5K{F_5>hPyVKlwm1na3HNz4=o8fG^>9rSjQ zh$jLkZ0iLDJ>HI{7lcsfKB`YI10nq|rC)>TBK<6-X)+=GGSZRsCJw!n6YUsau&?1i zGkZ#F*BE~isFy@$HU%>_Gx~xUQ7gL@VrKR(hk$f4n4JUEN6teByLSUn-y1}klhwI_ z+_H=whWvpfpx1sNK@J*^rmJ;GPemGXLpjloDv?t{rE8Xo^m0*3Q^@ihl25`#*y6g0 zr8q8s}8*8_J| z^oZmBv<%p;=n=>5nFQQT(IbxgoaBvE^oZkA)Q1qwp zGU*mzm!d~pmrm;FrRdM<{8h}S*l0z6PUjzu1@5ir-_d!0YR|38-_!ZnF~I%w`J#Ux z;pJ7BRIFF;hjBsNr}N<$q1ae;CHV_Hb({-4P~nR@U*rcKq~g}gI^T(fE{LyS`(Fl} zq{_cX93IjMU&Z^k4+Ezven0EngmH}>sz-|PTW4_VQsCh#ZU-I?dy36e7+0p>xf^(t z!kZ0eeR+izo1@d6Ac|IauP!K;M=-!1{tc`;HcxCw;O0EMcO~#-Jx%m?i-+$c{?qhT zqW(4y4@ZmuEZjHl3wndmCQGw|*stBkjmBZ74{3}YCZ$c%*O!w3+8}o6~>>fM; zjI*;j*K1mQTA(U1iXTF^*U3pf9|kmZi$E^%NFjchoKn$@UP+Em|4uaGWe<)78ty8f zdU0$4EFwN*ra%ddZpFlpkmt=w>})ttraUE0(=3ldlx(;&vNROjSka6^aqq%HlZuw2no{SCi7eFg7cUv z%oxq_fv~Em0)3`f70vtyOp2&!x(qw4{3a+mYPv4t4jb>635fsi6IjzJ`BSR_XXtV@ zcJWOqfHM_zbNavJM$J+%j(>pZ9koE0ha7a}>06SFR8HzP5A4BihUE@)sR&E6{uV{# z?!;OXsaZ(Nr0=5m;cQMcw7Ht15mK4Z`}I=qX5j+k*U0g*vNM=<@i)k0MF*p|7UI{+ zmlmAt?@)aFjk$sgg*?=vh1mQVV_=KVV0E{EVD1tzpt#q9@rs|fTp%<1$3~#}(%Q&9 z_d$Lbk?J-YDdfx}N;4Uq;lArH$EG3>@32Q5Q%@I47r@)T08orA3@ODtKF3Lli%1jN}q6-YOfFqaL#`18tAW zm9`hhK28D}D^U_#ig6n?PNH^&5Q9=1JY^6XG?P}pB2Ve*h5B>t4 zOB-adP^gdxk6?}Uu=Ho(f4#E5(oSPzq`x$4))^oSs%->*!wR@!h^Dz?lh|iAR7@6r z7u_T87Mt=%lvAWd-Yqump8`2pA)Z^r4vB!Hq?6Ui?Lb3g1#+=_(7o7U!v%`g92AyF zKSwDWg+Kv6NU|U@#HWK8|0h*vZ}=g~!>B!7a-cHQ)sW+$hUK&&=E&`Vj4%>F5+i32 zfTa>2so;|vJ3{!A*i7k9@Jn;GWm;?&)y76lvrtU-B*#^@*bl_PN$iI-5TyFV2T{}u z+aPo7rwOl>ptXc9d1xo$TNL7s1^wve$Vh79BBS*&_LAtMau>0Gqj^V<&B-KV+mvN% z76YX3W7W3Cer;b;U#G=hc}d8ED>7IbW51ztY*_HJGZG|%+<-){s6g9>nQ{%Y2cLs_ zk)Y31p=fiwd=vvf0EiveX~4| zvPGzA>(Q0vV?y?@hvV>2CD)Ue8(lsqR=oZHBsT!?W%L3|EhTt^5ruU{?hlJQ9`^ zWmnL}M@0ZS)SlbT4`Uie1#UKb`QOt3yBX3!$MFZ&07j}!cLF~Q=Md!#Tvp~icL8!k z#sq16EX+5myCI!)I)4HkiRz&qhG+77u{uP#)P_Bm?}YD(ic)Yge}4~PPX%Z2fBOJ? zsdne{^&n|92K}#B4LSi|2-wGvV^Pgd2JUaHUas~wH7URz@%SG{UOK1uj-tEHM&$%IrcV7;Pj&6jj4hjvH64Rfv*#zf%c8qd*G~bHem33u}O+b zR%ZwJMVPtp$x*2WEg1-!4St0L9V&DH!3nK|RnWdJ;@a1stK)^X9_>Iaow9(B_i@(Q!m6TIfdO^W9=xn9+My^G8-e zlt%GW6KIIvb3Ncnle9}KUz7^CO8k%rJxv-@3)m!n28JTpl&yfP6^!7=)&X9xexb?9 zzrfBWYK>_E%#(gkuVfqG4W_#r3A*_McEGi!`vmmz{xmIbH0={Gjz2vB@Fr8lN+M3+ z71@C6lo(08$_%((!8Bfjcp++oN$wfa`LZU!W|IuPGWlpSx{W4j)0jNaYgCJAkVc&6 za}!z8CIuJqm;8V?D_F)CJ^{E{{fbs4pOXaW7e8}CzdUz>Cj2d?-a^Pa9`PXH7Ntoa z*PaC2s^ATL5Ij@Vt?DN|HtPH(nx?mzzJ~9j<1YRK{AbiQRlZHg9G*SNKu-Q7C?lMBO1IrvrHIAmQ#d$rE_Inj3~FCTf?7)<9vhkCy@8 ztA4WOGlM@5{~5Jcs7XAdP9(cHpnf9edot1A!*-${#AssCv%rL`{qYeDm^}CiDqtB3 z&`{V2qFNTdqAz2_P>pIh7G6t65M<(A1#=z|kYRV?Lj*QOwUo-q)H}*i_ZDP?k;&^e zY8g3uD2L2m=GbUOK=xC}v1kjhVS-)T#`I>!z4(=X@jKl#%RYVts4xAm94V%JWhRi@ z0%}@*qQ_v4qYG3!+yizg34`En!qX8sqzs~4UY18u)Gb5Pa#N~UJxBIZdHG9Y#?wH{ zB(k!ar9jmZIoJS9-<0JNx!Bespc;wXEVCM@R-!oems^19BuZjW?f_aLQ92tP`j3qD^USEaTm~7iHg|qQ9$Ely+v#R#xi5P zsh2LrWAWMvwOvPF%8 z7QTBA;8xPUC3=yj-GRj@04X2XW~P+BVY3=*PN7@(a)_O|6}nCL_B`WM;X&fqF=U0QEgo>xL=iO}Sf6 zoSjlWHF0(Yj7dzKdwRgOsb6B^+^e)EC(dq(oO0saCy`4|ocrY?qG&mB9+1eb#r%lI zZ7Gj>KkNtNe~c9FeR2kpk9(2SEVD{*^*V=S`wbfbpPh2>0pw7Zx{n5WIB;kzX3`@y zs6wl-m~)3@2OVzn%EZZp`%HyRZ_WdxRkJNb_8`BNwWBCqPHZz9- zeIk3A%Z^}_Qa%mbaQz(Cn(~>{P5~<*J$^3VC!WD>fiF(^6Pb?TDbg$#(1krP=jfC+ z#%81F@@3?Z!n+X5uOu?FZyyBuyF^x2Gz#cziEQj$YVL})lwC9N3#n$P`gBK{$vV}rc3DMkI<;=3dZqlYXAS?>pkGBD$@V|bM8Gib0PPV8$-}Ht_4?IU02uc zVp;uvKF`bzaew>$^LlY}-t#=u%bA%o#pjxY$-)OVgv-QKePG7g(VHbWXd~w7-&28gEC%&vbOYMgb#D;mkp6rdFy3NB|6?dH z322*Bd$+sWrn_ssh?;u(}^&6 zCN?$2Ns=oz>%u5SO8$ou%@A+)A$;D|)LQ*Nv_edN3ZT?nRBxo}u|KL3p)g|%e>YQs zp|2GzR?=85K1%tof0VO#91_1MfFtZr_`LT4K96lo(h|f!8HTsFZ{o`5=Jri%CdaR5 zOO@uD7R1wEun0D@n5@s{1Do3wtQoSkxP7`y_qe{5XE3+VaMugwCQq3<-D%&#-3#Oh z6z3P=i6vL2N5GV@1&{IlV78c+lh#jkoMmVbbE3;#eH1NJ^mg|Fn6U_@!(McS`?{c~ zr*#Idbk7L}^>%chqIbCdGAf7kF*G94wQf`}q8~m8+~8g&n5;ALu8eMR#|x(DqTRr) z7E|?k6q4w6_ZE?2ihl@jhr3QNL;rg(aHo4zFjKEz3*7A{l+)iVz3>v?UiVVLZ2cp; zXwd`iHG&LFj=0PYCTD{Yzn(2VkZb?ZUkQCWn_vEmC` zfyZnaN!GVE1s->k*hFB_!6&nTC+woWG<`ezbkUP`S#zeIoeR9r+Rf5^8w2l`Pkg@g zY`qTwi#}knqyCUt@t`|YQYc5tX7nK|&6SfVqYu0M{*8{ZUXH>TeZ+c{ryn~BJY|EC zuMcepKI$?Ru*n$-_BoS>Mc_h`!?X?zA}k5DQdm-s2Q12|bWq|&0TGsuT1t{-QWyCH zr93LJnBY7sSQSV31W_4G<5^@(Ud0;PMYO@9b0I__4q#w|lSq+wDf%-VlR7P{{%IEC zn>pslSs1kW1V2eEb+eK9!Dtg#{ka!zUu$5#;XCU55#Gi2GM$$1g!e-~!eS|VMlXal z)~;xXA}psSWD*yNuq|qxAi~!k{I+4GP2xzm5>3U_=rgV!lY*3gRt|<@(RyY*@Ht!3 zJpDNf-t*!v-m3a?^qZnD*ajw~w+sNjD2HTm-l23L@Fkn4+4@`;;LGy8l&eWE?hky$ zI+d%hX0iOURqm-fDd1mR1`Ydk^b2eQUbp42zrJ!L@C|pVNC)YKs0YzEt+YT-M(Rc1 zvMvwTvwH*IcGrsXD9z=F(KFVgvAPl7a?y8eu`Jc&2LaF8LR*1k8jEB~eZ@m!`n-j3 zB6Vh*Jg>xa_Vf7hqFKI_d8pRWHa;E`nzHwHJh$~R=qbZBo-g%rq~s*=cl6EpAP5tg ziSHR_XX0fgMNegC;uF~R_6(Z6J$dqduxB09N6eQGRXyvPS)xHQP2V$~Wf+Sn5n2W) ziL-=1Ue2bXxldQ2NJb02-ZxRj(TkZy!@co>p1uM$qt|)Wg7|#O=5mC$RWPJCF9(kF z9uth{IS6}nl=p#PvJRkekB+v=DVj&@Mz8n$bLdg3{%AXJtd}X6rpwsGkMr^cGxSY| zfkobUL2Sgpn?5?;nk zU4B(7V5yfrm)KL!+XpQ3cx){el<6^?gDUq*1@rZpLf{QvwP1fe?nYpRw@r|(PBwBZ ziTQB#E>w|77tBB22bC_K$tg!~X1UDqZmXj6o*a%A?dqKr4C*JQLfXxHM=+#uGo=&l z?)@eh(I@dvkLG&VA_Tk1y5mS-53jdiistwC=w;q~!BpKBITgL!+d7lVX*#zPu&4K! zV1`bq23}z?Q#Rj3dwHA0ZkGP$UPya;vqd>uzf}p$^X?aEN6l}>(LPq1qc6G`*w=eY zq`CTo4ZthCZv=a4E=-N)dx^76a(;x87VYP?6U^7^`U0==h6y4$?*d+JagZJy0rvOi zi?l$0KO8u~yH{|y>;Z}n^voWhQM!VuagE1w!F=gswV&BI$a_(gi}lIp9ZmATjrzm4sK-=GmN`Eb{`a~7wco5A$kaoMfDP31mlOW6U)kuio7{+&eO-C(tS2tt962v5@Vwc9U`S36il3>P}{K zzfb>yM2sGgIez8?4`YoUwCI^`#3748-Odl`VT&OhJpsJOVnjcA9C*ZHvOX3D-fJ;M zbGcpgsKr!$$3fsRi)lKq9C+MfhLg>#4n|M;QcgC3;8FQzk14_Z&n&|;%Unb zu~Z_*=xjVSjY-Vdg-OyX{5*z=ks5VzuKV3^#pmBGjyn3wJAr<`34!&}^Z&uifR%=H z%0*C)vl!9!@a~8z>r}Gt)DjrQ>;HC70f#blQnWHZi zOGtO;_G|89h!)t-501Wk z6mY0TPoGT$4zraos2f}gEVR{|GeGnVlN87+pO*rUlKAOmQ?}!z;WLab8w>R=0e-t@ z`F;VZ7R?E?VgBNsk;rziTi|lk29}2Li-6q&&&fL|WZpNq0rS3z$cf+49s%=ZCs}Vi z4&}=NcK%2|&xZc;fZ2$irrR^rJ!6QVoj@>?_!($2f>MA_LYmVe(VM;d#5YI3(F%Br zeers_(`Mj&i$Q%=JK#c#C^e0N)t;GsiRgxGY!+E5h8cV_F1DDW-++(NB^Fb4%3k2D zo{43ePALQ~wTRc*F5qpRnL5eTkF&}zv(hX*WDjt;#caK2Bk*?bUlN6m`W;GFc=gb> zvzK|E`MT2jo2#E@Em`HY5NS{SK3mf}yuS$M>HF}8jNWN6Uk_k5ul0TrX@C7@5^$Z@ z;ugBh)^s2;+2_?mQ;Ow9#YkFyG)r5-)^na;pR0y?lfVp7cl7JsfoXw_f}TE)5*^J5 zJS-U0t(a9U0iEu`_^g{Wp;{hF1SkT5%xKZ8#N-a6dS|L zqY`@}vN6tV@S~$K`EH1^|BfFo+T3f$y)4mmFU>_VP1u3(W_S!5;#UP{qD?VtF$|RE zna%Z%?1hUqv*;y{n>GMXBRQM!AZwX~As1k>?sW1LZwu3f0a-e@f)W}(T<96m|O^m(JG$&P9*O&L&&pEY?Ed*3agI=ia1LPw90 zCihXqeyVYa<3$s(3m!9np!pg#*@dm;rznXX@zZMlOihmOjCWE=YtlLPEjR=62uFRc zh%PAEZ^iv6=P=MX@<$~Er;PHgHS!w!5Zy-6WB;#6S{ulBQ~tsKklW0BnsN>s|7Z9) z(uE`EsKmkKe=F4vNgc=|9Aegrgw#3fQ(MY8=9EbY`C=VQpMfxq=lIipwq~-#vcHTn z4o2PB*X+fB2*;zfLL+6trsf99IY6xy5Iep807YNahPfsW}YV`@HkCz)`L#E|Py@K^g%T7r5FQ@(9PiwUlbwB*=MLLxh9j|MC^0 z$uN!Qz}TdLnZ&Yf&uz5EE`&@Ig*g2V8+%|7&lkKKGkF9M`5R3ntt5;@D1U}Osn0ft z2rIy;#`m{Tli7Uk*YMdl>14JXGt(}GS%H~$1W300vR`2`;=%`un%s~ChUVK)im=P^->n)1d(fKct1Upna0^d-Ry=LPzyTm4{7m7VA z7h=*FN@3YR)o>6VBiuz*E50@=eP9~TO;m1(bJVeU`5R!8$nz2+dXP-T>6(+exV1uG zYjQQH?pX&KVozjnTAUUu*JQkv3*&-?pbRe5)WfQWB2cM3YXN1QT5(s*#|aQo^oR6# z#km^&;t-gyV6H3zy=2H!nLR--PZwEGy)YW|%1WV-nv2e$e)UnIi0Zr%^!gbg_7~5> zn|M0ohU|O$NsMv~il4esxpG+EFuqrQC9ztPUvgx{( z>I_OPbvqIL6igF&s9#Y3OX`UJif%CG378zyKbrY}ob8(^N?&&P05))^259^MjJLO> z%k>poGHAlSN-!4>bVI&Er8{w-fd`>GlRR}u>$1`cXX;R1%;b6=w41U1P90_pXg#44 zSG-OgO#@%Lt9}^?@%8QfBp*)@pE|~Xr~bMLqOpeJ5-Ka<@Hk^Fs19QSXKIn5I_g*l z(0H?6qpm8$aD8fV4{;J}748F-7>YRIB=l+~G~2=$rY>}xU%MjVCM2qZ<6)f1h%jO1 zZU(ic9D#CzS$L>f*B*A_Hi4U?T&7OwsuIx;o6yaaPe+Z#tkZ<<%oH|qd+_;XLN2w@ zi&k9wKB33UBEy9ZyFiy2dl7Zu2GHe3maL{#gL=L#n%rH;Zx?ZA;LM~ukna=jmP7R> zY?Rgo3Chh96YNS6Pc}#aeUXa^TIKT@e3O$JMPX zAUY9?zmo?#$wcCkr#BGPRrk?O|nHRQvI--{7~;>%?ddT~$Vi=&n@)>jyEoy5UVYEYbKTf0WfPp@dZsQp31y@NL!Rn09M)SgnOU>gWh(A$!jUbz z+l#vxYNynA$ObTOJeY2Meb5k-=>1W%7)YOtjeQ;$0VQ@@f}ES_sqgzZ&dh+Rf{wcJ zR#2QFPqp)bIG07wo$#-y7&C(k7894?Co;3Hu^s;h+cKJG{Sn*TcPByL*bSELq0hJj zY&zXa=tH;e$B#ENQROUyQGKKDs4X{xk_`Er@U#WM% z!dGu*nkw1_qh`i7Is)Sl0h@P$F!2`rB+tw+8ZE4bYR!1J}0HLg2!F*I57^7yX7$rm1f2s zdEAbap0QURc?9u{eO%X;G4nb+?q_YxXpQ&lj05r*-G|464tn_JWlbT8wAMHWaA#vpu6 zHI~pN(Z{%5%kb0Mae5XO%BIP};p~{w=AcB!DZK6kM!k)e!)lF7wR zVX>i1m4&x^Vaa>qdzShF30OGcTcK>VVHap(7`epuDIU#EVX2`U^*GwK!f7T(xlV+U zF*8fdbEF1iA5TwQX`WElajNoukku4Wpmq=CMQGcA83=d<;VJd zykK-&Ka)hs(lBka_jsg8Ah%s@0?9)mGvRw2u`W6s1%;QZF(|yD4kk{H%0s0Hbu?|9 z*S$q{C|ZK%sIAA?>`dXS-fjlbuwgAd(j zPoljvm4l#%a?Kiw48>K6p&p4?>CS!c{D>dA?7;!l%#!0rLYJF}WXle|7X6AoMCII~Fj{|lpolqa+ z3O^$pf;)*VkW=$_DE0dZY`hM}673+GlO1)CC9vqJRSQ9NjV!1h+6uBSa=e~BV(8oo z)Enlydk7`MjECt{tjuIX6s|iT)4Qo7@#yo$;WxetKdzaFRGJ`MTAV1yu{gvSNz)!W~jP54U0}C$Q13Cg4!HiW{F>Lr9jBTPvoSHP9*Y z#;KTY)-q=}ada(|fudJ2S(RT8H*PTrZaytm%rn{T$sYNN`5%juK~;btS5()*%r_U0 zFDwHsX)6>_11!xAc19T7@XT&q!W$E!jaifc0} z))>lE+v|bW{zGJ0()L%ZGnB2S-VE7>Bot$|x0e)y?(QL!qrN{0+GJ$8Y8b<^#mIW9 z#sfjyN<}kIeTbM)d5FIdFrMq zpg;Hhkd&{kx(f7~S(-3NEnE-!i>Yn}%2^6}-OzAVJ_PiJp;78fG@2!+KiE%K#;TWw zg5ESVRlSGiy5ubq&JS_bp}TV}*vvFC=Zb=5>b`@vo zOTIJsy{poh=HCyKP@Q*G;{xChY=``~8&h3X1pJX_mm{5hN=JbIo)9J8-}_+oxWi0Q{NrN8B!|s!=#fe%W@2c-W^NrANP-Fykn^$#6W^0i zZUy|!IQ5`U-HQQM$?pwbr(NtUeS@KL+({B>>@59-dFHxCj-91hOlhBG>@0n|G1zlc zU!#5OEPafXCg3g-`>*-569mUu{nOmWSG*dHGb3g?HGG2UftCDy1rYJCtt|@?r3r_e zy<8lEO0Bm4hgM8A0rCi2tqb0StX~}|ViWdXqL|fdC|~(UxrCzjobMDW9ih_Oh=6%* z(0%jT@Of(~XM0!66VYUmMkG#B&Ni=>oOuM%X^Pm${g+6>C-eWYkbXr?Hh}-Prk%-* zLMc*IqbZ*mCAc(;ojSv5G#rmbRkobQ(f^?u^L{cl*{T{%`P?dw+UeE1C}%rsrtL+< zLTe(zuL&`i9)yxlzHT?VIKgptz2N^ICP{nIqLH&wwz`@pVC}lde&lxa478xTns}!7 z9^GYy1Xciv9s@ z->wX=rC@4uaf!35g=cz3X?lZ(u%-1ULvJOvvY3e-)AZ<7|8ck+q4OqX_!O!sJ!TgF zZ-}6Il7#pL^$d!5HyvT1YB|CpVhWpdXv7hI5QWu$LLDb7<2P;-EDc4c zEn{b*`US$B^@pH|#%oN*Jv);OnO^VCWRrvu=^yXZET8OVa9)3B1GtilqwpLx2VjXt_GXii_kBdMJpJ+&@F#n03-|Ungc(0(dkuY@z zC~7F;#D5D%+z@}^EU!3@qi8Ey;k4Pw>cBN{s9A5ZicRUwLCvkR>W&VebaVVuNWIeu zl);0M&A60-!^e31*3Y{elecK5D%`4c>GxM{AEvs;kO=b0d{s^T}yKRqcNlJnfS!hO0VgylMRDXMC#v%~0-W@I9aOovJ#S3yaVC zR5%;b&b>tWoKKBJ!dG=M%Aetc5(emcWKD8amg0FYRRe0D_fj=*JS?&Y*aDtcT~jT@ zQ9Y9^j=|@@3NEh?7W`&hfRP=F3}#t;)i|qGEk}-$DT8H%9{)sZxR(f zBFT_qgXj@;L4#0LVlo6hBFT^mCPUC8k_?$>l(+M8hu;`E=5?*e{qIws{tBfCZC=oX z{QwN&>6;s3!oZ|4AVLo>=!JL#IYezJVrrQ7m`}0K$^BTTynHG!+iNK>En_c;GRm1x zM$TM_IdB_A%(Pmf+E#Z%6gPh}7D3I&WnxunCZ}$X)x7lkkZdbrqZ1w!R<+91!=TEX z4O(sL`BYO6?=Un=y$Tnr?j*6dD#x}~tx0c8TO0hEI$f+5uRgXGLujL$Dv>u5XCVrug}1p zN>$C|wxO!GOgcHHw4X7hJ*b!mRquqvn|yUq9nib%yz(ONLo-2tWq^6HqTC4o9)p3c z6|(K3>U|b8UwWyU(h-^;@IAy@!uLhhhYX=FeX80w2XuC&_)uw*_HRsDUdS!!evV=F zrO#C}TSD^_o+!s0L?Qecp2btw4be52uy-EM(7GZ1!sKa`Cd~Q(B20Hv<|vC5#}tZ~ z3AIGEi(?1Mnd(L^37h7M+e0W~7Ss~ewmKOi^zY=CCpAUb>=|9AOo;7dEEpRhim)C0 zZ+UG89~P&$3^8?bPpIO1B1|rAu+4D}w!rK{Wvi@{6$o0^tR;|UeK-;RXSErR1arbI zuf>*(4&Nc|jE(1|d{IlaYt;n8GOF?n9=XS?vYac+Wf)jQX@#lZ829}d zy`;)X1~KmIGz~bp072k8*@;`c-EqD^2Pmy_topGRWE)0E@bKODCXk)H^iqh5$^{4#xKAR?p%jPh>xLfkeiUP1VtDs(-=_%(_8T;p6~`$j|XTk*{M&Z z-wWWa7ak_d=!?Rx`7r0`zmCK8hzYJaWg(*ZMXgBNje9Bj?~{NHET-y>V}T7VrX}+e zTTzOPUol;!2VD6pDm~87PWHgpJ0$X z>K168i?Xb84m&MQQ9rAktFIda>@S6gn|c0&)}?5G#XOyirmkp^+g6;)*YBgvDH`mq z73{CKqn}VT)ZH#PNbkJ^Sm+)TEYP!2sfx^DwCKj^ZdU+DxsQr;l zE1KZSD+VW%{bM+AqQwciTLQ4uVyV8z2Q0U#QLYc31m0lrhU7_=Gn}GH*5wM#qvVSw zTf0;BbBlmeEKbw>vRZVbO^r%@oH*0XKS$9?%1c%B}L#ll6sgaa`m04%tdo8<6Ne1%E32V<{4-4;Dz?Q-ovh*!4gw#8Rs|W z^#w1ojPsi>MHi}QvE>I{JrZqN(Gtt2aL)#l{8r0PxSAcNqNSFfcJ+$h;1#mbl=ED& zqpxVSdj@%eE}Bml?Sb6f%pymtwb=l^(}ovEt5tRYuaTl8N2@K&2d|Ul;zXI=9t7WI z8Aqilyd8_S+Iu_Z`}Nxm!Q0$(;@={_-WLLIx4hJ^2XqGSu;IJiuOG*&p=f8!KfiwR z7VsX|Os?TBq`U^;{nmZlg%n}>AF%Fi_v;Opf$xp^kE?b@fKS-?Eb{bxv=&7tZTc+5 zHg%Sy`(1wVK>R)Z*^S@_t^cb%{S;pCMGss1Yd!rs`4QL58{XyVrN!VUmgqS@f3F zY?QBn{+12S+m?3+^p|VFAGkfm{{Dcz;{fQRq(2?cf^KL(pzZTHnHwFLfjuk!~&^vpAf3?>|8Q&Ia_^C19WLAHwGXn$urJ0iQ{~&k#SxzmD$*k$(};?E4fY`q=sLr+*#L ziw}X5e7}f%5su6A`2L7XhqV*;;LR1DB%k8KQ&{5IrI@%4FN&##Jh`qmY|q&;J(uuw zGtGj_y{Ys$I^KuFQ;Z}3{DUK3SV#CdDf}<UGvQ%GkN+{CtSz9 z?kIJ$lE)W0;Y4?gPyh&mp-HMcj#G%n^<>XYewV$pxlJhtUErKXs&<^w{*?& z$eB{H!kO+IiTEr%45OUz#V)%O7zOF?81YNp1(0$Wq^~~=ZYOc`^A@@$nc$8t7mRUa zt4GuE&X$+C`cvw6lO7T$DfFB3!9A>f9Ow5^DY%y;om>mRJ0!!sZL@*b4A_U^gt*iP;&Vhpi5+zeS4L-mn2Ozk+PZ82KUVE6|~o+%BD zf}@x`Q*2`S_g^@~2JV?K|!)}}tyK%Vcyv(Mwg<2Yu_ zjd%@ahJR|tI(lQd)X590jc>fc7$6>ws+$juX*2%Ddf=*$)`BXHcb;lC2{ePsSh1*< zbOp^cq-62vjkC;Z&!8;iym7W6j?)fGaM+h^F%`k_!vASmHWel8w+jX6cZM^id^F0E z<35e&c2byJDb!99O)Aki1R+&-UFX+t)T`o*8a5Af#RGWB<51v)(o(0a*Aes>IIHx}(Gc}cJ58!kZH9pQus6Y3rP(OHWql1* zsvVbu`k9(LOIA~q^?zT2GFPRc#Fq^)(+Klj#bceyuK5^3ww}lc=0WO5XkAc@halyH zQ}9!>g#1z`p6#?7;u{m%6ylm%zNp_ihJu2|a8%JG^~0@rmrpiva#St~OVJcVp1O|x zkg0}(>Ydv`ye$sV2&u*0K+_CGR2!s4(R4$}DlrXIX(&Z~d>d$np;VRK1T@o7nu>-& zb}eOw3e^GKWMr9YE7HDbj-f1dsx4@)p=|XDnz*8y4Rutvt_Iy=C`YM!pm~OJ)iES~ z(LzH#)l`JOsM=7TT6Ps^k)eEbCmMmG#fJK;s~NH-h6bs|n3X8H%}{}wJr=ag5Ki0U zIOYjdne3wDQs|3L(1h*6zmR1`CodJka$n>?(S4>`Whl2k=zddpGu794^AvIEJnUs5 zpO{6#%VCjCMIDR>9NZAV;?*9tF~8^$RnY+!PMHGdsI^S1M`N|?6OL~lGvzy|K1C0r z=ugJ!kh+BQ4ny`mS~tU?Zyv!3w5Qr71Mh)z}(QrVxi3HgpoML4=PuCao{4_b_5(v&|TYkDh^ z3LEfYl5`7x-asKw!w6b8+~YXo2l{QJuRryGgZ)>2!esO5q zrtQOKo1zM*d~S;~P{riyhnG1{`OWJw_`ocxbjHhXF|Bz>C88}Vw{ zvg(D(S-!wfinQ(J3(bo%RgFSzEUz|nk*pUhUu39>x_cjFiw!kZuO@(&n3|9#)1u|K zn)02IP&&>jUuq^PGTC64-)8DhzTyb9e3`M;Uz+Ih<))4dQa=rW>~^!Xs6bT@1g+rE zm90L{cPd}m;T_UkRc9__tGa^hXMmkZw|EZoTuDjE^pJG)eBKX8&IpHmwepLV6v>?k z)A$}@jR_axBaD0FPwLXUVFO>QsloxEDM?aXpmGgNA{_S_N7?kp{F^`#bETGlMA+Jl zKXDu#&RWZt!Zwp>c_z~wli7VthI)#F$@0Ga-eQ!4YHt$g%8^1LQxNh^L5L`B-zmR} z#gpISC7amc1ErV*A7BzZRo-;v1No-og3oX0<{+b)sZQMi8f+*_9a#ms)=;+kraOo? z0K#5JH65kByueV7`fM*~n4w&Cf`zNlP)~KqM$m9WdCI>Cbe*Am)qf#qgrWZGL;y6> z&>%G_6Ew!sOdbSjxzCJ*Q}y_IzzQFS;4iJ_=2i}ao^}E5UnOmn&k9t#2cGIxM;@d zD|gso@a9uF7?bx+Wn?+!C2KqTUc}WhobggmFNd^=k*@ZsHK>v?T)eU&fJ-z@{qkDYh(^+3NGC8{y@KMuEu$(=TbtOAd`G9*i|v3j?_yCUGy|=TJXv zPTD^}^+3G#53HAA^6Fxw#QtmO7W%2&#JJzqkt}t0BZvl@rZZb5l!LA{)KP8k3>spN zYR*wdkbe6M4CSgdq@jj-s`v+4j7$!3Mt?<$8YMuQHXVmTs#H` z?8rdB!x^xXZa6I_z|0$PAR`CKG(Zl?&fo;cfJ02NjHX$5JX`@CC-r%R5h+ItanVN| z=bCF#atB-`s}%-36kDxOX8~+H&JRv}X%D*!^vn!sGn@W24)n62kgV+)@aIh;i>PFj zivg$a5yDz(bO;8#Z74;J!24#vyHAS@t-1^P_?!@y@m~V^@)Ds8xh8qQ*Cur`5&3Bd zY-*oT67Z(b30E_2_jRVamy6%XNc@{#bv|zn9^)AiSKNll4w^7BZbwJT!Vm`DC7_e0^Wv#n5RwD;849T1i$M1q%{ZsQsOKH$ zxlK4O*jG9aN15M=PvP^u8)1lsT$gPCR(qQTJ$)ylS9+_(pw2+GD_!nAD$1vPnN8nwpQx8IVhdtdd zL#Lkr-s$xbtZ4K2OP zN^|wTF2K93-JbfC25z*Nr}K%MEavNLRs*+qN5!fBx;>h}(yjKKsX=-z>PP8z?=_JY z=#FSYN_Tkw6dbOftpnU?BRER`x(m45(=RfI1g`@AVD=`D)hP znt+dae-g%IYUlaj6W%xDDaT~$;^yF!ay*tyo`$G@zxRdcWAb!8v*JNH@>3>Hr=g!x z`mmfAD&Oc9Vnki~h@1f`-{c;j1b$Rb43%$kd8odnk6HWpCU-k3L+RsIAK&CYItqSL z4h`j^2Ynq2)l+h6C|=E&j3qxU$;#F5`jJ%dGhT0$Bi!xn>OpsbpOvFQd84~N<_A9~ zXM^JP?CQ)V;O9N{67}&-ZXVu-r7zg{KJV(YTfi@Q?L_`E4pv6PR{DxpDEykMU+VyV z)te@aJ5?8j!GE^lIfL*sy7e41|Mf-1fuM2W3PEPkY}Ae}Ow9+7aakF9-N@5Fv-={f5kzCkv? z`>gcu-ZP?)>zy8+0{+y>@eT44R>psLe-$~dcS^Yj{JHmy@OGch-2ncl=YNIa+wIeP z8-Ty?GKF#U;{#0Je_1~4(}i^JD{p|vahFa##{X-tR2X;Z?DW9jSoiVG^Nyb2Z!KdH ze-no9J8!Y*KjG7_ECYYmC;IpQn50 zy;EZUv`_y7FU8WIy}t>c@#(o}mP>!J`tSMlP08S2EuZ!2{KMeiyzr}x|2dz&B_8~{ zm4D{bOZS0&fi5Ed0_lA<*dH+I^|ep0XWQom28#T9pWe)7CN3~V_`FYlJ`)@aEEoRO zrzf-i)(LD8#y8-vJA>l`4+-NN@b(mNDDaXnz5&0?@)r*LT^Qehqtvfwd9`2jAg$6! zAnwl$|60G+mw}T5*~0iH-1|y!gFt^_d=uV;E>UU2!1coTCftjyWJ+MR@NU2UjjeUm z@_xVW(i+@2aJR@0`!!yIPU%H~dxeks^)oBMO#)8}pY-d0-T-bIcu)92zrK{^InDAZ zzwTcOZXR%7V|btN>pmEym1YFYCXJ{4+GTla5$GcF=l!}K+mF_P;leNDn|WLCC6-_F z>n%**Hi4(4y*cgIr_jGBy)(?195A6ddh0po* z)lC1+fz!gDA$()OT>{*#;ZOepcNnugb`AU_@~{2+oqpi%f%Lyn{=HwHW_#8nP)GF7 z`}GfX!IxY974c#F+%v%46=?rG{Zklxg>@g_;9so|?j7hR?%^B!@l0@^zzAV{gJ0JP zd}UysFuuWm%=RQdz}<4le^2u?oYH=l@eTfYrpHx*ZKA)~(@*eyd$r~5o*q&U+~0-= z@58(-@Bo`1`#pUy2p$-CTI?V8bRCwLYXawlk3v5UJSgD3PXAAO`fvTgg9Bz$&V!y_ zn*_c#kR$R_xaze5cu3$H;U_%Z?_O|0V1n?|o<76$85ZdI2Hkt!)87pS7Y2%iU&eXZ zgTTWBvxQ&t^gOmN*9BG!pZ0X|-Qep3j|!jhbPtAqOyG?0d!9bo6g)QYx$s#}4?GDT z7jRC~zjK~WVtZH|$P)ex>30-d61YtG3#11MTIqy9f$-NzZ@yn91}cTW_w;M%_?4Cg z)(W4;nhDmA^1w;qUp?Jq4|q!8v@q60)MtFA2G~Kxcs!s}hJ&XEz8Cq@fD>U)&~$*e zG(=~VKj^Ho(->L*M-eep^8+Q0%&{~M#_{YTx?=f)hCD%GCu9+J8f$se2EIV_6h+_F zi1-wncjP7*pZ5V3*oQQBX-yQ&50AKl((hF2TBF3L(B=4nNN&{iR!KlJU=(4W(zwN5 zI5e)NDZ7@&l!J1Zj)Orwdzfy>npDw*olIjA3+8PwiLk?HtlJQ6rzty%#x%bYA>w#L ze&GE5l(Xk}!B$N47Denf8j*|;pF4m;+|YyIJWoyb*J_2m7_A0G-%`Y`ni0`dRvVkN<(M>cr_ZPez~sN=gp!TdvHcgF59UYLjK__zD3kz-_B@C z1VyuETp0`C5o)s6S4*?@Xz&c>>;)P*r*C3b&qEZ?4xrhwjld=WBJ2XzQhu8yg;@!C z3(DCgtR ztJIcC>`-3tF~pe}crpa0@$)D$Z5bb7EK4`M$$$tulE&WPej-~=)B9^oCE1Cv_MZ;? z-9d%-Y7``K+CUzn8RY0d;P+3|Qm@7w7cHVBVTb{M(u&sn{fw&YFq&|PTTILgxfRRz zBq+tR>u96H@(2fdz$8*eW3kJp5WkH>B=cil0TmY4DDVj~PTt{WBS1X6msllj%&r?o^?7OOhX@vb* zBa&}7HgwG?y0%6nEfEm`=R^~JsldLhu`B8L$EFfW*HeidTBF3WXg1>5+EEQrJUh6q zX^d@Q-9>Bc=NfCW16F<*csTno&jl| z*oNoUFp02tTg!nWyl7(9dQ#5b?*EdpGxS+8OrI<@h zm^6L5GqLSwC?1>{{`5Fxmwq4=CkOLQ%r>Od>0^+!XF1`las6eW4u(Q1D-+bwP(+sF zOzbq7-s4-~Jv$)l{PIVn6fWhQ*oA?_{GuG5HZjLoOH<3MpxD(=20~teAjTIW5 zgz;$nX~S6IGdLdO+3U9&%o!M$(wLopH$*!jo&g8rd3cT-qOqhDpF$7d2cl#6lRCE= zBHUSpUNsdhd*p}f+Wbdj0z_9c{0a3(b|;7_>0nbg#-aCG9P!2upd5u9|fd_10XiTQYJ zF1(+V#mdRz8kYsf+fW-t(g`lW!_NpnlZlW!aXiL%LK4E;u8wRfZ+66|8kccQ%CL68KOM!d9Fx)w z9n12kenM3J>7Ti(2c=K{F8BqMZv#HVGRVnZRkjBBEXywEdeyZBz~_t#$q0) zyx34s%{mI2U?`+QK~Sloh`Q(o5ElN@m1H$>E$9YADQYgNM|p*zRP__)9?I>Sz%=zF z8uD_xCJ?7Haj{Fqax_!rD@~bN%dBF+P>7uJb=N`85;kHSXuYAJSyHpXEU5{pTQE6P zewU$$EJ-WB+Ys(N?giOKLtKQ$gb3!tQ8s6$8pqRBQ}AP*Co06P$4~E#P%pPDl(x}? zue9QlnNIn3v%JDfxS?dWQ@&%f$b#@<44#6A@N>b7$P++WdM=*|Lqupki$86+(gG{P z@EBo5F!ho?!SpZq6VD3ahOEh_0Gz>%SYQPiDlgt6FbOtB_Oq3?3+Upw=rdFoA8O0` zOR|;?-C~oKYw*j48S<&f-Jn9-+9gaJ@04BFOcaB%%(-lY`YZgv0!@CIEgKmXil|wY zpwXR#l2s23dCIQ8S|~*|LI#$NG4(c8O~gCBY;2Lp(xjaz8)tGjLn=_&c+>D^N)0J1 zW(_fG78#}BxA@`80FzS@hDJ6~gt(+O#43Rlpi(@8=87>)!hm=N&zP8%QuG$GrZA2$ zuooPHX?NOSFs%(HCX5HeByl5tl1m1vhj-!Ro@>nB5_5W3$)Mc#7+x;{7gv=GHYbo_ zi!eHnuVA#QsLXj!gORQ9^=j+$V1>nM#&U4WGRfN#!5^QYI@0yl=EceqLH9!X4$D< zy&ncmH<9sFCkCO??7R%B*XZR8yAM+}?GKu1GCM`hN7*c?GUYB+?Pn6r;$c+?xsyi6 z>yvm$?$Joe^_u6Mm$<$+M8nZMj;+M=eJ6+wWA_0AzItbAKd5;iTZ!_u6%5G@c_npy z0|g_pFS8`xS1g#US*}Y$7E?6OswfHjc-Rxulqav1M0_hnIZgBEwUQ*?gMt~FXRnns zw9-t?!`Dh0TWOZ&>1!ny`Q8`hZ2cj!w4|9Y@gut2QEs^_N%wUZ%+Wkb{=ZgZ(?T67XT7-KHKJWW)0KZPm9Ur} z8O~b&%c=R`|F0&?8Qfe;O;!x!lboj|!IdF6r(&V>7?oIE{!gV^;jj*WOgpSo7ouP; zbCPtZJ;&P+N)c9>TAFO|;PDkOO=8JBhj&qG3A$M2*P}U?^@uD#Ea(%PnsV+bmh*{e zbf1IPkvl=@eNhhi((H=K(uplb3q@4saZpS1VoX-tRXVZN6p^uGGK#*k0<4KgmX-YE zs@=1&rnA2B$5DGLKuPvZt=6W1^fs~0KF8~@9ZUl*Lm{wh3R8!oCBVp!#t{aoR#Z7S zkG(9jAc|)o&E}5Su)aTy89p~=G9D0Ij2{lE#1kLpKd2$ed!f|Xu?AJ+MttlzZXc!bgWJ@YL2=X538HW34G|G-r5D!+)%Q59J#nU-B5=5@=_2t zydvTq)j)W?x`o+x)LAX3n=Or-Icg256%&vLR_tyB$~2lim0JvIZ3aPkYElTqAV4!; z^{xc9HPm1Iz8Z9?@ox|=68Qud{~`!akLxad*Sf7^i?O*SU;m`UIuFZf8Sn)g3p2x^P^^OLUf2gK`Yz zt3^#f-OTdxu?gcRPjKpXSAVBwu`CR)n`^c}onlkZyiMW;53dvckKgJudqB4N%%p*% z=U(DC<9AqebsP%t_?;GgntKe!@3QE3lDIcyauGU<Tq*JnzmqnFMH9<_)M z(A$B>EC%)JJAub7hV)f^fF~?QoFqozbyRt8{3BR9g3KL%$_i0H^N~XjpzkrfZb&_k zenj1{$w5c8o&&Pi5qN6iQBXoGciR_$B8EaLZvrUMP(CNX{S{x2>RchHfuRhgQ6%d&G?bZ8Ic}m;H^oqv>T@|{QA61(2hpv|af8F^ z@$JQ+#)fj#4;w(KhH};Ctw0wU>Zz`-2eR!l?!(RlH8rw))di)au5Fk5t3Z2DGb0RWhpk) zQawV=5_8H)E0kSkdupFVw7yvDjfxl^ixzb0)s65N>53oID9a04KBkUC#+hD3xK0?OPe%=84-*M) z!BM~BjS@pQn`Cv==$k=Xc-1&li+#AETiJy}&rF{%1T_7fbZa4@$ z_KF~mU+Ojmc>E2)2XSH=O6$-Q25}nGle>W@SUDq4<*m=R%T=m^H;Nx}0qtmWBg33Jfi8Mh>J`IBxL!UH=$)~zj50QT{J=23x?1dF z(+7`DANtyQL2UY1d=c>V&4SqU@ihwH&^JudVbjMx^sI)y`J_m(>7z*n@NKUD#_Cd^ zlQb7O&78?7IPO^&A#9)?)Sq$mo&A`XKL82VdFCPIubK&&VQ}=?O^%xS#Iz#a)4KKPm8w`ci@hs3?hQhdpX9;j) zX9Otm8~g<498mj5!05oTf0+=Cm`_?Q1!3V+@9@-j;hiH)a8#r#+SoJwZ+{?xpKOMDiD#*U_T=iG9Aj|A4&!>7( z)4uZjs&hk7iLvLYkBUGO3HwC!VN+bH*Cg5#WnykAsV#};FMgQXvaJiMH>Q@-_+pRQBuR=q&V1<=t z=ujnarIlvtd+E_CE6viy=#(s2ZKc`zrIWxrthA$^LFt`Vn&UJYN?zk0WVFv9+64>N z+h}jFN{;?yJaq1InJUbLizWi^c6s0>X1kn5pW>~#V57SO;%NRisHqEnarH+NVEC(? z0>w7AO#|S6q>n=<-eU}Yv!{;*^?z;w{%)~O^0bnP&H~4`MT&V{%{@;GT%WB2PNU&h zfPKDm^zYX1Fy*+w^XYq-Qvs{w=$|nXTM*|%nUf&@z5p1s(x5J_2G+6CkoGkO##?Db z-+dGqw$fzHi&PhAE5+H`9f1ujMs*w1-31LTHqr-g1*TYRtbfEfWkDnBRI1**4A|IW zn%>UxlWH+Tx1I!SV(n(?4#cJwTk9UgG>aGOZ_utRXm020vh+3Wff?4RY#lxhY~eGz zojd9=J%KGP7U*Y?EDJKNa;1Ki*xKSO{WkGpi*xl^;w6GI*Z0u%;5L>q*Y_uKTg#a1 zdx?Ch<=b7&n+O(UTgFzDj!f+K5)XdE)6ee$cl5D}`Ej6(p31V`S*GMe0o={UE;M_Gy5Gg%?vgMv*Z9f}U^DG0$KW>F!yLQJSAde5cpAkg zvhWHOg(nMpwUN@|r~xRB3ws;#6dhccXDFy{LrGfL#}KY-IfjC~u+r1VD6RYpIe?pp}D+E8-Bgz?jzh5ZessET2b4KS3d9-0IiXv%yVj&!^S zc+H3OXFdE$UN~6YOrvW}%jl>hc%3gCV%te|)n-tEp`hxE7%v=ZD5OqDK*J10obcO2 zfQ47W(ZsLu6I^(MdKVRJVTB2aqdE=;O)~AXr|P3}ESzj8pw3JuueGni@dyaH3g|hpM}w)?5iY-CZ(D4eme112bPbMDb3e zYkNVS>(aewuYWsE&+5xuy$%g;_2srvb>w)A>MPt2V2y2T3sk)7URD~^3wi_dEQWMz zKd`UGh<*=6r20yW$y!o3-(rfcKNQk_7E|?&cmY&jWid^+Mi-^}YKs~A7e*y^IA*41 zN2EG-IA)d}j`u?KK&zasdohs*TkNRsybpM-#TB&8!=CNE~m^xRg!QPzVLy@N$%w8f}i zMd|ex8|kZV1dg>Xr|K1G$g0O#Ow%_a*{h2zW@z@ts>fT*)cGu~#TK)4ee`duODtyV zv-^M(EOvAny*C|P>JCIkXAeg_dsg4%wwo|(ic>wuW$xp7x>G&ZWg0lqL--w3UGB=M zoz*v3XB@q(C0wbn=xKjGaFTr^2a~6lO?0YfS!pPFhEsjB+ZisQ=j1eMkq6y*F8z*n z{RtBn)eBtBZfbS4J-p7*?3q?CvZ>=~c1^1n$DG&fn^rHm&^2Rn+-iM`m_o7CVzRvO zt8cUCi>Am6zj|3L-O)8;(OvF7fY3Df7NL2kCvN9c)hlqeXelHstvgQgq$$N{B3$aQ z2J9IL>76d;Ztz(uK~F|oT)oES+BSTaN{|PPAT?v}6rs{2$?@EwYQ}uQUH+E6tzFFVT_*R8bOD%5bG@85~7IwOQ z5Wese_c+e-7OdmZo1x|||JrT*cND4R-?;V2JetjE-0UKld}~c`Hk;G<5XL#nzq2Md zoXu(c|8e%-@lh4s|M)Gtxi^&sav_9(fl!5n&_NO)5LyTkNPy7ONq~@$Ld`;e&_pl@ zC_G9Lv4EhUsHijxh#ecEf?~n;v5SvgfA9CqY_jn9{pXh#yUhEXGiT1soS8Xy?%lax zwFc#iqTqBkt@)o1f%3DYxX={X6skd8*8Nv+2G#Koi1L2H@m&bC*8L*ny5?I+6kE{82cYt`WOV}%pZfpJrgW5bibkq>)vsJvR6@rb@oC~_9=?A z?)qUMJ>Z&wqT+uO-GydY2AJoZP6m1SqAC-u6F>M?fjFi`J}74kp$vXN~`GW z=3_xQswkp0&$8rWiX!@Y(sEFaD~f2}xwQ9$qKG=(76i&kMGueF6-CtPDa`2W zo>3H8r?_q)J?nDA!1z~$mCva9Xrx*6A)`j47ZoVZK zMBVM@^%oun#ZVMcr@!dYrlN>C)vg1@r6{6KR##BmiX!Ut6Gw7@qKG=>kzy%|s8jMG zP;5n!bvns91-cKw%J@oQWsqC?UXYNJbqaE`23ll7D5Qhj=>W|h64Kq>&9f(g*h6U* z{q!)~uBW6}vYa)zGF;coy$qS+FN&PKRXM%=%IWQ|v6}a3 z1mdffU)!y}8L zipi(u3+`x|F~7R36{vsBmlE!ATkmcI{F;*z-o@j#u3HKC4ac(?^SayWK=>_(f*JFM z+v-aA9lgkmdDCspz`9ZMJv-ZsdCP6R)d}z?_JA4lw%e-61N@nl!2^_Tt0$%qAH3kU zKEupZ^NZwOa$EVBa%z5M?eGAlTeHJ-U1Rh0o&i!PT?^F`An@BGY~^N#uGs-K|A+{q zM!t^>jv(Th8dI(AGJvUZ`63Jvz|>fZ8{$mr0DVCUdYo6o0fQ9`cP3+9stHlyNQ9Ha z)(#UZJ)axm>zHdiI_==ISnFY9O(U^of(JT-oqOECjTOEU?40Zc9Io)M!OrK80yovU ztm2u@V5gc*5utP0GGqP<4ll^pYMQG9v#Ud#yZ3|L!WWi=Xm&@G%k~jrg04mWjH#mL zI=vZ4O&$j??hZ|RtG1@2jCX3TSGAJyPED*%8DG3p(_4QY&=vFCUHBRKf1s$3*vE0j zybJ=jHfnAV&ESf86@;JYXvvE38VEsHPHKiK!r8lU6cW|ZLKVc=?;y=?_E|gle&iUg z_XN3ZgsE%8tKV(YaWEdRd5`;iZJzIm0-coz?^Y}ZdR-#iPUr#jhD4?nJPYW}cc2Q5V4d#^^p@n=)?n&< zTk=Az1k5hg=OoW#eF+z>euplKo8k>}3ub85AAEvZ;I^q2dK^tx{UPhq_8oj>RDaSY za34sYa+9phw`-C7j921X!{5Qqtp3P)YYS)}%dxICsMM-IKLQR+(n9ap1J;++V>>Rr z{=%-M7CDN!cId4@_H@IS=v(niNNmpiaSNC`_5NhuNG45J%=i)zqN*RzyH@0D)eq|2 zdFxtMtW`gxGh)}8-44E8eMon>M~(l#2j-}nR4w3t1$1eRNq=$>u1u@%la~f>ptavF6YPyz=Jw1Qn)9JKklcB{`{U+X|SB0E! z`l_Ve@N$5zUD;UusC@LS`Y}CPOy-)ieHjEF7h{hjWE#8th)$2A#c{OwNmbiIC+t4J zqY4%|pJ6qwKBnMICm+MM`nZC#oX)KLi~66UwzHkget<9QbOu+<$=!xC_5cX4>V;q6 z>OW@d-G;Lw4TRTpPSmcLJ3*M~1>sGdP2-9=142wk5Z)FSSQxG#ypIXE`W^i<)Xo)i z7KBxp8LH1K!doD`&=iDs72!Mxd{s~Ndx~%Ygv5~`ysrmX)Nu)f2{inI-bxTY1tG}- z;iBGN5WWCmF5T_}JysCD2I22@Abh9@-`|bLh-gy1tA=cc!-dc}(ckO~4~x5&Pa*KX zCZDB?ipn4TDpm-nhKoZ4KX<`*D_>a zu@Ti`7vDJ*&{WWNO6jsL1w)+ioB`YldYo~s0Rt2acaCF)tG10ULUV+(_CJ7uiW}wp zvH~zj!Dwd_7TW4y<3=Ie##zkSAwZXN{~rZmSpft(2&7&ArQ9^pmh zWm>gIar-!T-34w#<0ipPaK2(6H!|)KaG+B#2C%VlQov;AJdF%jd51fzngKR3-WS|d zr!O5o!q9@*R->ICS^!2GO$5Y7@FBn`C7kJ8Li}5OozY8hr#L&O1GX~82$<#k`~YB# zF+;#SCu|L1TccdSLg&I_!1l%_0cSfqy8w1H9uctA8C(R|Nx=$d8}^i|V^tLvI8}(o zs=FBHg>aQ~PiMfc#;<^4$NBCc;O<652r+h?Z>Nj*6g3u4m&TO>_cri&Bv_00a+x&MzxZN%b{R6!~;QKfao3 z63C)MidosGZ~_RXTmf9gl%P{yli4>}EhL{_>cBkrKV!eG9K0zV6 zYrPqQ<>P-qKHc|PC8`>KlTY{c(!Ek(0|*v{9Zu;I<=oFVTDq#hkQDvNz+u0kAGJ<1pW-)+`7l(ENH z!}(}8h#6|6YfgG1;5Z`|Yz9UiCj8V1%lQSJR1x`0f5=ZT{tx;a{RTn`hWZhGNqcMc zPEA|VftFzjus*#LsG~$K>r0~RCBkoys)0I5gx?+!shwVJl78I`h5w_z<>6)CN8SzRK5noDF`;p2f? zNQ4s_X9Bg9$YcHP0lH42@CK#XrP``iQfGv9It{$m5;e1)!o0UCh87qxk=9FCl2)~m zXp+?yR;+60#v06bHd(D%plEI$&t?_g1K3ekAJ0jJV}f4Qg+=l?Db4;3D#;XA2m`dx zv(eyp4F@%#Ujtq1KM#Vd8(J4I&#rDPt-%l5W&?#wq+44a0&*lW@WYoHz@{!_4!F^y zYdf0ax_@O`s}U~LR<=_b8qCWr(pI+L4m0q>mj?4nfjUU!vaVn)TY0^d46xS0xRsqG zvaEQl+$%dvWLxVJfnp^Jv<6}=Ss5o$kX5@3sEb6w;;EdKU1bR&*4aStx=UV|6^58< zWe>^oSTo@tE7ilXjjX>}LNCb+x4M@D^^y6SSe*|5^_8fp)fUs>${Qq#uy#KJ)K8*j zTIk4efQduVCY}hl(s0p0OC4FTCK_mI6R8eOd>3xaENxl| z@kTux>Dv6Bc>Y*l+T8jp6Z95ROlvS6ZM;;z)Dmqx9&NnzI;qfQZ3%&-@Cv@`;(Qp; z^^#{>U)%`PNunU@IL7$WScyWcpP4UCqA;sJhSpN`EHoZ%MRcp@14+b12xzAwk7y>2iLot>xccjAwmyXyAO5<~2?P`T- z-mBq+L%5$;S63&RL;v#{>W&I7HQ<0=Q*m7mJ<#h?+yI9z=nYU@+o2D7Ed>J|I-%EA zFvy`7dIJ^2oykWMfP?hWFsAXu#=7?QC|tpLLv`opfnYRHg=o%?Fx=~@v#7(ZfDM%z zmvaS?sJD^2w`4mhBLRIcRSI#w9SrDusglPr`vCghq7<%0UKa%%p?^#hcEN;rOo$=g zDBWp{cJ#JTS~aJAW5AXQ;vtl&fWFrS+IWVRHH+5sp`me+qieU{p=nv(b~x?wb}-u4 zsrlw0V23(2Td1a^g0{1*HQ@CMhBzlN9eX<|=y3+3d%c|%3=gm9s(E7-iU_ahrg`HO ziVCmjp?SL~6dgVXym*D$I7Jw&-mVIEaKhP`-4yKXGU?W1{nDVX4F-vn-N1qV7^G1GhdD46X0!j|r<;BY4l>xuUU1yh~Na7J%G1xGtN zmO*cV>f#KiC0im=aDsDo31E`)mQ3d{j27=81t&QZ+W`(% z!c!cs#@=KFr{V#jO5h>-es<*7=*S^hpAx*ob*Fh>Fh(c?HD_8lV2Xk+=lOqSJk=nY!(hqldu^oh`vS$ar3o{9TE&|ny@d*T92fneNC}5K z)=)s-TO=K4S}CCKEs{+f1O4Qkt%RF8pOgU>D;VKihXuP3W=G_cDU!RJ`Yiu{uwFhwtxxl+vcTzB6daIOynp0>4dKGjznYi%uE>X~S-rfwj zRKXDEOjp2a1wGF1jR2P^81B5^0&uy45zZW}6JFo_?kFeWKEN8qjdo0W%Sr{?IDcXp z@vc&^gL8%>a) zTD4xmWT!iQVuOOi!{=Z^xkaH=F=^B)G&;NjKmYe`R4@ZDU-RCoV5U>T&f28l6sH5$ zfA3}mvz#;c0&Y<-&zZFn@HPbtor@0O?F!Cze&k@-s$i*eGrf45f)!fi&Rc;0qu&6J zZF~hiTa0zQkN0lnw)ZF((40rvO82UKF6TPVv-c@zJ4JDTdld|Eylnq{3VNL99tC_r zL2T?403J{m~qnt141TQMs(z#~?;7bZdJGYhqzN|X4wHBGf!SyPx z>Ch4{H`lcf0ytT{j`7T@zoDwGIRm+Byjj;0@H@@>meOiFnGFEnRxrr9gUiG@1w))- zR{b3X!<=8T0naPwapvC$_^yJDob9aodkTg-4Y+Q0E!3gL0dccbcMrx7m zaAE5GKo3Gi8Xt+$wW$cOdU!AEP6gZOv%1=}3kLkWt~N0&CDX9X9LFBJ@N)+7La zrJ%=IKL+ss6byITX8?Y!V1)BGJ?$F>qnr=g0Dh}rw6nZ9;CBkPao%Aoey?B$XF8qs z2L(Gjzug6hH<0RF+TtCPL+K|4yK0e>=s{QX^Q`Oq7P?k6Ps5M?f7hKyILZA{H(s~Q z0Q^%y-MNVa1|>Ty=v`I|#fS1`ok1*X?f(Bt%` zW>dj%=UEO1mv|x+w{GMd?^fI>Ez;qH8DKnzUTR#`5_cYV;eM4j)DXc}n3B_+TXsOK zfr2g(i+L2Xoz`@$h6;v=d9{&39;c)|n2i-gOxGQ;szQkA5XCtPMak)*iGtDMmDJv* z3bqk|025r>C)|zv=6<}Kh4QKfXz;+6{9KJ5q+g`x{XZu#b z4hq`Nx{iPy6~y4A=Ia#f*vNUiGhm#8;Z8TUe-{Ot zI9G7R?u}P4!Z}B)x+;iBVmx3s1*4pmT-drR*wX34)u)Go(N5I@z@7@Wc0Q{H?4@8E z$K({(TfuhDSq4&l6vQ6?J%D``yxwWVD%_x8XXlCQ0sAQ!=d8*BOi(aBJcD6(qJrI= zFWH;@73|@ByA*JMg1wwEsel6&>=T}cJAU3IRCa-O|reg`Xk6+c}#CewuJYK49Sd zrw8zjqI5nqARTe6%Kx@odSbf5Kf9fg?2d5?Zwb)s4ltCqizfr{P;BJ)v|xg<24l7H z<6tg>??!kh8croPalDgNMYZq@#5z;dc)*XkaDg;cAv-(+gK(NcAuf;zSPbZ3bz)XEvQpe7l0(ohlB^ ztx8RyWYUCYaRBT6uMB@l6u!{JSX@l?bqTJV;^h$3PuSM;|HZkcq=t|&%iU~rG5Yj!~e z!UBWWVG&0;X3rbksfY-90O@xP#-Li0eyH#XbV9i4y%#TG-wxJ&brl=h3h;gfU5>%| zXP<($^SJ@|fcS|6FAXaP0Pa^@Pk2$;T*RIRmTNRhcz9lMHeyc&Bb=`pCOu^E#ZP<^ zWdb|!pvoKV{KzHskRey*HclV5FAv_1~pYuMVU}w2r99A&iIaUtgM-}W5UQsa{ zk*RXPKH&x2dU#yHzRqa+@)1?g4NluGfKMpc&k5#+%aaNwIQ*%i_bCMvopbjA9#ycv zT-lE)H~{4?L}aVrK7JE!RF&l;~F zw&B@0{0*V^IR*2a%{hS2tGpHB{myYoc65kMInkG`nsIC zdx1Yt7{|-=F#+!-gO3S_GPIeu(#^y4=rZYRVI{E5MFi{tFwPF@G#PYv!hUdV}U;xjg32&0Zu=zeP1ZNHo!SG3iwM^{>=f-`CQAe z&EV*1Tn=xT4FSVD&UC71`FK;#{W!p83E%_;G4%d}xyn1y9EL27@5I-6c)aeNVmh-q zgr@rPX_1fK3q0Li3YosW+UtxB-ZteRddK9JyBx3QP0rR49WhS4@0yIJy5`~K=-&5C zPSj%TzHf@LE5_LcliP7}{9QD;MIp!B2PVgy9QGfYyj>v2`X?sGdc?Lzp#HMSdj(pP zOPzFWF^1n}w>RIE}f?44?x!Af;C@(w*>u-rdh0c4kk+VXzdXoUoUdR-cro-YFwyETX@N6>OU*)M@Ivuens<@VWX5dM#rxR3 zixvKl9?qLP-YSvXjJZR1czeg|RTww2d4tDWWAdJk8M7TXx|4xdDtu9Qc$3Gw+LU*B zwi_~@U!(NnEi59SU#svjLq_yBDSTXo^y?HpVaOoGf`D?B#BD1N=dcx#IY<2NXL z#*lIREegMkfSglQt$pxIV^W6{E^`_=m~t6 z!XM-5x-G!F75>C!FZ8Ve*m&KmBt#(Yt|9s{DA%hzK>GQFt#x)f>Qn zR>|+fTTAW+eopb9#G^nAs!u8YQ!eM=WZ>sbPM~JYOL(gZ`~Qr|iP4OC#pSF+py_?V zl+!le8ggkG@GD9m-V)NZ2KY6F-*s_K`OLguTFi1k;dF+Yd zqNw4zAGr({i)uRv1Xsu(ZDt^Z3i-1TsLge_KnwY61(KR)3cjT|Q&F7|!jK$t3>V)b zfw$9(Z))){hm@^54;=z?Ky7pZUwj#O9$vlBpcKbUh5R<7yXcPw1pvRxP|bz+`)VP7 z$3Pg*3W|eTL;m>ykpW}8*AM}OX!-+~QTT%?&kuE_i94`!(7mh^^SVYaWt!g6cvPIO z{kaP@sS4Je%P_nO&m{jJb>P{EY`{lVSBC}qQWMru`rE)SaG5oJ_r zxR|B!IedLui+jjb&E=z)_+OQwHTxS(yK15;e4_qv55K}E>PG~0X-!B^y+hM3xDYmo zb-e02wF8A07-qqkX!X>l%c;h|uWF^9+O)+gU)5R(T3-%Ym;VtK0Ssx)_Y z7GNY-`EI(!iwL@^yV^DDA=av@9t!pp5p-2g1$&8^s;ZZQy+uG>)myF}kh5&E4yIe&ht zi_FRgKj{dr=?W zipK|v;aPM)@m9QlqJbyrPY7INIM=rTo~-OyV>seKl_|n8_+Db?W2|pg({+wnoF0t_ zU8z4y;mw9Kco{H$qbbVUYB(cU9)6@LFs^Rf zIW7wfr`dzRMGEi7Y>wHe3ctq``48ePa5n?b*1PngJ%{nE{TSe4eVC~K5xf=eR^U1M zG=UL+eKQ%jM9CwbI*jvxmRYjylo-*g_sEMK)w`3K(e zc8cwNv(BekP(M>#?pCcAgB6!yrt{2l@N0D*Y=!!nPW%wyjrsyvKfDER0`Mk%lfZb( zTh2n@&H94^<1KHUaCKR=MSoFXyyfi*Hg2o#(I>%;;LoP>?F!)g^bbQ=KHlnfPXpll z_3oj>ce))r4|t#YA;%uKQ_1nLUyTo37T$%ewyFaP?{_<|(cd3bzaKs5c2;7|sXD0h zaZqvDcy1{0!}?dko+IEl27W|$_a^_S+j$r9VAWy$7t!A*-A;#Az>li@xXes?1o&}P z-Wj)ZpbYqk!Y{j>lUR7Fp3sAZK5W&sS_k~3vj1$L^D3f{s;5-@z7^<1IKW5senS3y zAf|s#?uLs~ceAeW%BZSJJXDbksd>U{xybNm4^{Jp)AI4_{~HLnKwk`LK4E{j4d6lr zL!1>HA&V6BIP*3DE>t-`jsqB4U#3ohJjvWRZpHa2Fq|YK%C^^0QQseZ;QTQc{l*BDL}q| zK&hHYA&v?uBn;#i^e-Wc14OL+A);LrYa6J+94mS~S;laN>oBv?Z^dLFy9mxy*F|T^ zrypO#M~UBqWj6HGejosgnt~<>6DFUQUk7k zTvaDjOme~(dT5OggSjV~Vb(LcI6=DVSz!qMb^I_WIiI})tAD}{eFn}?Qh z3&;16*Jc}smj#d#x*`lon?7fch7=`*R3j~53(^l^im)eIRy4-hM4M%xj@CDrxF!Zl zgd@Pwm=l8}a#_Q1T`)0Nq5#dqBif{uCT1hw%jl^(m?z!oA^zlppm=!VonMY+u8* zKe0+nhm0+zOo>?G{Sj?Qka@i4#YcmVwkC9yB0L089$+N|&hM6-Z3K3@wW|pu? zcswPK8q6$ZlkvP(9@CdOSE2}Uc3@`Nk0_H5CR2B2Mbmyn(c(JT$JJDtlBs;Qt&XA@nPSX!Er~!nKr8 z3-CQOSA=)1|t8*D{6sn&nGAYYo@9omuOLlvly}S z`djsxg6nZKs@kN732wM^Q-8qCN;txaY7e+YsfyA(EJBVu9`i0=|G?v^(PlKz!!jjb ztX+zA16eH4FRNmW12uRVS@q!ql$C;FxOig`OEVTg!^M3W&m(m@gnHpM>p=s58~$q? z-(S~uj)vFlA0``V|A@Lq8r=%VO^?(kA7(S)**XMA`&0E4lLtUBv4c=8lE|x_`VrQ{;`%JXGRWYyVY*7I`RmEnh8AqrnPD8i1c%7vnzv z1AQ%a?F0SjcXX}mcK{8@0v|S8KeYxL*a*QSoqgUOph3$7FT^^8+5LgR5_zmc>w%IR zin@kd4bY1Z43Q|pS{e;BRH7&=b{EjFJB5~Lt1lMW2S&|9RM10 zR7iHVq9*~3eMg{pt94(X^lt^~p?PSqUxh_K`F9p8>{)!Z5Fz@J4?Y;K0t(P5KP~h) zuvU{rEBsi(8&*q4*iAm|^5ZjHL)K?N4W^O0^xRD{$3;*AS`5^27y;Jk122g_IPkKU z_Mi`<5X>BSMfr^u@GS&SV`l2JAwmdlXy)szDrDHu+)k36b;tsW>L8G9J+cm{#bAL# zEE5;d8?KuskjJWA3=}OkaK?z6fhHt`s(OkX;aE)nJC-(22u^Ye;k{P-ltS zSTCjk#qpAiYsmIApe~Zv*}AV0P*?fG%XljdPPL)CltgFIVA)pUwXh6`#ft^eV63Z$ zrbxbUY|)P@Y7PU-!%AJlN7gv9SSLRgy9uljpoads5k~Z6s|S1l{61#Zs6~;YMHe+! zE!u#`-YjZi43aI{?IulI)Kc1wv(l1)qFYg8Oh^O%Fmq8WSwoLlGZ(d%lHnGACb%f3 zwa|jmN_FDWO3pa^9eDkZzX%qHSfP#30gKv}K(ycLL7HYw(VrfU zE7XJ;U_Oe-&h@j%Z6?ks(_B|#VQPQg>2h7602-ng|HYQ!OPqW^U;|P!@6|N-Y~4(p zr@3eGWg=R_vmgiFfitQ%={zvoOymw=(5-yc(ZEfIK;KMq(!gAFa?ou|YubSKkm(*c zu6w%FHBIOm@Hfay(bT~ey4jz*M8V}G4IDiY$x0P%6=Cff)O9d=<`y)KOV^n;2R{P+ zA*RmP@g^k?!YUHt7JxNb3#S=09%92Gr0)%sm##x-seXT;==X$5u!qLr?2kt!SJWfm zFquP#Y6&~RK0OcYW2(`ZIp8SS{fnYOKg#x}*B>5JmfKzO0N;XK= zwQdih&02~bOSAuX0RS!N!inW&xkz%;dl;T@GR67k!}7Y;rMjt9F&Ua7&^KMlCGN~n) zL$J5K2EMUawI6(K5&dIWuI9!z6D`ky%xqYw=NQuR!K}2NB_4+uQCd-^>AB*TeM%A} zlScM}aY?ED@r}Qfbkb6n0Hv-Kq@<+OGemDnfl+wqU$e(T;dVnehX{3d2zA<^?O@%# zRMT?qG^BaLi*oKT=S0Q@B+48`(*{xoN(cEPESW&u4UF}Fgcgs&8`dxfuv)WE(? zkV#xFXoG5?&7&Qj>cXoCMeN_9Z{xH;ToN%>HpX?Rv)b;+y$Y-t)S;)=}CzdC7SsW%j!R@ zH^?9HW!;H$kf75J%P%j|%uk+#reXPczGTv{{M-eaDQ@^+c6$yg12Zv`w#Dqm$+Zn@ zD<{`BWMWFO8hgvv@$A? z&M4y7bbO7A26?;}DRi$kehm`vU~Sw$d`;L4q>n)=lhs9UXy{VS_{z#S0-W(6z5rbv zVAO!+D5eMv>l&`CA69SuFk$_~$7y$$X2|lLrPE%jM$2YS2ZMMt@%L87Jm8Gk_<~5o z5y(`4iP30g3lC-{%+p#vK9jP`W@tu)&34}iJof%H2ul1AaOOammVv}Xe2hptV>0m= ze1SBBny(xZ@HBe1F~nla{Q;c*K1}2S z1h1f6#tfvV_r@32Xf5Eej1frUS7N_Ij5R$2K#PrGmS0V?n!zNp-v;YFvPbx{(}#e~ zWo!*uW2}sgNN23Vmndl$r~$`SN!eV_j!df>@ELh4qayfqMGuuEz(K0&)Ob^;11Vo@(lThD^X z(2A;pc4wTG_00Ml*}0x)fLwr&an4oH2y5Fun2=#3G1V1wEnBgV zOVdU|K#toHE{@wrfMv^$5H0&U`7dro#u1`rJ+^Ngj}$l#IO_=di9ynfQ2Gi!#u!(| zEx=*~`-nN)4Zq1tn{f`AzJ~Dc_{f=IiqJR#8nvwN!DU$Iz{W^?j3QS?DX^BwkgF3Y z-AJu;WjsKtHsztwy7tqZApIyKF;?yn+@uofWCedPSiyyXz$L>W_=CY)HM@bQ8l!-J zGWhht)4*~;xFRB$skP4=1|Oy8;*gQ5opRr%Nh(SW6_3aktX;UEzE+`z$=(7eG#|}N3ngb8PR6OM@VP$ zq6~CRe={iKbEL-=0*q()d7CUNYqKhspdqu7(_onOG zeb<9LT^_;5KH3Z?I|{b!r)ehpDI?g|Pt#0Z!1H+5WYJGqCi_YDOSa%01#g;IgL6!- z!Iz1}nwx8KI!Fl7w8CaHQRt)QER>aXc#Q0%H&HmYZ#ARPl%3=w$WEFEF?Lclo8f;u z=_i%@UpmRh5}mXP#fwhbh6MkzK80e&-UCtgFqXg2%(xX;L?1q4&Krh`KGI!d@tb_` zcd>((nHeu4opGFB593SAiUFT-_Cn}dL47ODj33CpEZDojrcaW!hwRm=x;}!eZa&0V z-6Q{A-K{G3zf{-964l+0T27!(8Wpm(N1>MWASU1pUjvHXCP%XI%TSn2v)7= zz!OlB6$mC9={*R1!ED?78p%hjZ=|gDkf)DZP!@uZu}k{+7i{%x`uABj-`#%x{RM04 z^Kbk}MEdt1zHX|7MjAc|+NM+EA>VkqMR9my`*L!Q`COmV6DjLReZo}JQ_-u)Fgke% z9(L2^lOl45!j?M}NvSc2x9~S8Cj&hhj;y!JX-pq1f~t*T?iwuSt&L(XN-nqyQk%qe zXtJ22HVgU);rCm_e3UX3+LA=)ru1X-nk(N?g8l!#^2N3UHYNt$2eD3E0tU$;t87XV z<8<)3x!@$36iQB=fb?LK@7=+rs-I#6Y$OiK8K-NX<1UEt(p9Qnl&X4Uf%Brt2ty9_ zm&H(*)A1|9Gm?ua^Qw3lTUPZoF~n1vLGx8brgS6af3IJ)lo3Ldt8FS*+ElKxh*Cy_ zJX9N+k|p!03vJZDU_6#uhPIh9=2i8dAOc<4Clf5rQL-Nn~Z zMO+)m3QQFNaq_FTp#+(p8Qu)(XRVYLC|UL2AGGS4{tFdszh=H>=K_^!3z4B(N@w|B z5B>+3p#D!*|EH?|Gt~c6)c<+%e}vVyAvFV+E7;-Tg|C^2-G-xe`%yf3MUy)VCz#X* zJq`IcdZ8A}WW1r;tXc#a$;Y>Wvs^6q+L&*rB2MW%2$XQ?^IQ&^dvGvgD3$#kK5WddHI0CF?t;y6ij^djTP{d-fGWr@BUjt`c z!q==AaB(1>HvU(j!_YL|g#qys5~&^}GCBS3Le7);7>I;KNZ=#L>Gx9<&FMD_YW`)l zc~s^8m+9BX64P(GgTgue79b)1vJzn&=P?cOOE^BpUPHwN6BH*3)EIIe@^R)W4uAK( znw+NqlllRc`|8L$=RgBcmEPqXJ*!7NAlSZbr)7cwvbMaVU2? z<%XEohB!W!sLxZr`n;>^lfG|~t{s4?tm%y72WDIb&Ug=BlYP|j+(?^AecVjLe#Ch0r+Go3;vm$CmkCt5M=9oIg1kiVQN<-f zEwYG9gv(5D^17j^(9s_{xL|&S{9jPVXJ!GTid?WoWZ`4@Et*r1hl^$~);teBhV2r8 z;clu--vllfP9Df+1iR`3LmNSR-NG3SAOgcjg&mskkgibHhYCYg;Epg81Dy*%AIKZi z;T=e4RN!ltcQRH-YPlKc478+fMIv<%zQ!NK*PkREB|3wzlnDI%@GT_X3q!>?vgV?o zT`Vlek|WDUkRz)<)N^E=q1FEz$8A!%|7B$PSi%{~QLY$S`~`ye%eoVqxdrn+R9vC~ zbN#m|vd)6d9*M+E7LSinV~HMl5(-3*_!xdYqD_%`Y9POkdA3^hv7wLXC*K9~+)JYD zPRjpB?kDAQKZ(SR_|)$yOr*3yB>vrVf4iV+sGtXYX zT_TZ(oMz19+bPO=NtKfb>L}(pcx^f43}znRE>!v-s+>!7kVDs&K`rT&uPdVq9Ex>$ z7}V4F7)P%ygPbGG<0~U87kR|p8&K&##<6S5p{AFa$5)QHti0Of4u;LS497Vyk_Xm8s!C1Lz`ms*YmXW@_fse&=eF?zR za_3ZN#;0OWVKVU44+cZgWufO5;PfYCqsAyHUD$9=Kk5x zY}^foCAVRz^=5p|)oBh8HwO$nn;AbQz1}wu)JkySijvs)t0+E}`|7m18Pwltp8THG*k1CdbR}0J~yl!dD1egDwNI*vn zbZ{yE6Zr#Bu(4Cm;2w{b$tC=HP`Z(NmoAp^Oz!Xah`yzKvX3B^^JzjaCZr!(Hy(Rv z-0c>1W4(&-nG1=r!|nlNx0^!Sfz!_+!5dQ%9PxYH*WQ@o#+~=u#ZclXiyD4=V;W!?ZG(arjXGRMomM4MwQa2 z6aQn>8lO=PgoRNZkU-P%2H89)T}nGnUSkKJ79P_e4|bet3wAF#3TVS_eELDd*z5^l z^t326gLeF+?AS#+djHQ|yOTaU7WwR0kHol3AYaosn^D4c8rA2TyLNd=Fe)q`Mt#d` zjas>LPJ=GvvkU6v{_ZVefA@P}xpRJtxEu?+4*a50IG}iuac98fWy_%FRu^@qRV+Yy zldEbi{@a);H`z9eoGB0;QBbZKTU_a(sOc-HGPg2+Wlgubu8Hx-d9ZmlftRlOnEK5k z5k?<{na{Ci+gyHOw2vyn=&2}cJj3WxCKyMrKmvb;>!;<2H~PWUf&|Rl@pU)QyNDa; zgESw4Cz)XgfUFM&q(RtI#8(bRoyZw&`o#K4`PRK&pjk-(J7+fIed z6XVW$5IWeTZWz-XALBZA#^=Bp@AK<5d}*2Flh>8}=>OqsgIdhcwFRu}^)4|z>Y~ex zjxKgtvbbFDBsLL-rZj|TQtGw)I7#&nNoZrd8 zW)qFk3qC?R9jtL%*`VJ56#!*(+CE5;Slrk_8h=?)Fr7=n6DaH@7TCq*w|u_NKo5o) z#wq_CIw%47h#Xx-j`W_$!KLjId+3Z_zup$`L6Bq!jr$d>R6Y!n$_GK1_v_o3l`SobAJPgC;z2Q1yLoIeOu)WKl*ikDlx)sIL z9s<>EW`ce;MD@5q9f>O2eB|1EA6;()KLXZ_Fn%|gS9l?ZimEEBG3B(vD=VL zTZUE#IYwms6&bmogeX#}!g{OOSNv6lYH5kPg+#z?+V=`oeM(j55lSMXRP{Yo?RW^3 zwMtb5RSiI%x;|^HrOjR=B*q9;Pf%4CB-2V|Mycuxs`_;*1aDHRxXjr%`KxlYw7<)Q z#GOJFUgx64E~2WyI6;=GE>YDS4=C%Ds@YWa_BE>PRzl))p=v!e;;SJhHW>&DjHXrB?P5~=E5s=E0> zL6)jcQq?(b#5AEwqpAcX)4rZ4$Wqlos(NZaD7Pt98B}$i6CNGA znyLyP7G$aFeyVaW0p)h3YBW`Se2uC-%yYYaMW{MSRc}yLO@SawRlBHa6GALwt5TIp zRk0<0ZPh?ayZd$_F#u$@d624FAer_AMj0|nRa>d5XCF|uDOJO%YJtD1hFaQ&)k5MX zp=t+J6;jnRm~W9$s)9#pX`hV(Wv^0&PSNaV{Z+Nl(hkrU_u6j@Rn=7W2vzlx8KtT< zRCNbuwtY&~K&lEW^{XIyu#!RHK06v@Ot)0^H&xZ#DacY)HB~)25|sT)RRUE_^j8(8 zrPbajBxVU!qp4~Hl4&KJWcI5HqTSGgS)d$Hs?ctly~ke_CYk7YLgF!@3Kwr$>}INp zUvZ!ivC@6=Ns?Jok(q9$4J$90ixLv5? zS{7SLRex}p98y+gQq{=4pd41JI#AVFe^r=dN_fS1*#20kx(tcflT>x@B0-i`ahRk% z+YyvUl`420e*aqLS3&sIiee!V3$ojMo~nY8Oe;kDAfr?@oT|F9Pmd^7(NtC7uL_e) z$8|ztfl#%Ns>V~*iFSf4RSg6=ZP8dzo=~cwRYM?7^#|=fW=|BVFdnto-bkherwFpNiv5+=j?>O@rOHE9xB9Dsw|~SH=eWH` zsKPMQVwY1@+;Tyds-mgt!WvLcC{<_`&A#Zb3QOt^UT2@MzZ0t9u3GFXR28~GkfkcN zOxoQv|D;l7Q&oowzY0QCRi%))0c5v%9aTjjnI?W(byBqztCKckHw2$ns$5i6?ym|n z!`ZDuVx>^UJh8b{bzhhuORH!@S}on<8KnvY%|7n03KMcGSOST&LKP)qAEc`Ntp!=C z5*dF4IToo3t#UHf&gA&dLD2QeQ*e@vHpUD=#{Iadk;B`e0Drdy_#X2Dz`Q51DP(0z zkWrZfxt5a?n+dtD5Wn>-btBXJD*@hqQi65;0M04!d=9|-3QWnv_4ZgkwT(PCqu!g# zm4XGk04fz&-XCC|0@V!x<}2`dx~6S8CV~BCCGHHuKoMLH&?;kxf_eM1phEk(M1aF8 zTi0c{Y1&wUZxPUKOaWozZykihfI6bW2)rB>)yMwi`t7yQG zo6!?#9fWM<5qNmpvR}YKVPozBC|95fs()ux3wRc?mqEG~MWOxMLHV6MXUOdP(Eshn zKMf_wz6R|Ud6+*ZMUK4?2!{WNS~bur-HtBYp0Q3;VEzM`E1Ym6URXMRwFNZL;9+4X%QIhw=dkX|CQaMX$PEJM zvG}hs@(CNh)ha`iun#gYoGOr;QVs{pqJtd1<1a+Yy~;?)5=z1 z(?8n${ceyW>_gJ1pMgRqez2aR^ID^J#xs1`BW?hpZMAtlf{A3s)!#-H6u4)rms+m@09B zq0s#^fY$lYZ(D$F_MypbfNFi{>olN^J`@V)L%giCG{fLQ$g5Bl8|F42GHB=RJ~Vm^ z&{iL^1_EvKp*u5y_WF=}GSEIB`tUH&ejmCMQwky)Ri38_(1Sj7Y6#FnJ`@YLLujBR z+p@NYeds@_K#%&+i!ASm58VVO!!oJzHChUE)Q4u$mSaA2Bg;GPLto_so$#S!6M;_p zPyr)}r+rA94)lyd+VMs}T1XJP?~kxhd^5b!@X@=Jm6TL;!E=}Svr9^g^XF7_=^od; z%lzy)rA4Lru}H^t?S_9{O0z3+3-imn%*rb(nwMWz-lb?x?(E9E{4TSL=2R}w{(q~% zkK($_$*<@V7so=&N-8Vz%QT(Vk`VIEIORh68cTT)zHGAFK(?EzYGcF~-;TwXYpSCkdanE?idZB9`|Nol!EXIGRI z7v;)yQNi?o(^FAcmY*7II{Ac0QgDKj5(swp>tNg%2wwa z#n}~w)ANg!J$16sR#@iOwzKMe5vNegQheh$FTVgIlZIkK0C&2a@}v+vsu**D@&z2= zt;i6YomW)OSpjxYs;EQ>;TBCvWm(-I_nFVCuG`Rpl zv7ZQD|NcLO=>@FV)k4#=^U7%xsO5RHvmsJ4r($~k96GU&R*}yUSC6{;p|bqqk}^&Y zJ~m!(E|ISeuw*(;um4|SIgZKyUn-ZmtEvCi0@*p3LF*=6U)eo-aoqq~P*{-Ltw(uf zu2KcBC_|Hhi7{2b`dwYl?4r`ES{o~>=whF{qPKBx7Q-53j01X+n&xK~6%-VS!3UY_ z+)}mx3&K=b>RWS*OUp~qofxN*SBy;=n!Kpcd(irI|?YZBT2r zk0zX(0JtYCGq%;p%SBUNZu5oG3Q*34E_dnX=Ps(fmWF1fd z-s>TmNIq1)9O*YhGVM_#SHyOK@C8?#F@(am&M6oP{7u6h0Cx}==K9cc=C4|2bk`YI zkooSi6wofgUYEH`q(2VLe5o?+Df4|TZjHGpbCAn2?GKS3P#hyh^*9d3?bR zSCIME{N-k70cw0=DGj({r=am}o6nkjZQIc!V!_%sKLwKAD`@p$yCThAIc3U}#pa7k zGGjW$jEf!xllLxU+3yD=tgejh(rwp;_fgxERkZdQGxIKhTY}i2e^pkPzf~3VG#AEI z4Bic!w=F&g=DQ~CzppAzq~l=0S=m{}eskfDo}k{nl-Vz8%ZJ#50Cz8Chkc-Biu4Yo zztqm{e6es+A_#Xhuu1s}eH?7QyU3k8KQ`H%vrd!=}XQ2p=i@T&Rb`OfhW*tUd9 zzSr$WDB$gd`&n$jxs7OZy4!7GwIF;mm-Rlk&}gFrJrKZ(zrBza9u8Q(b0*||^|F0# zGBS?={N&|O*lO%Y`e-m)`BX)%`DRsZ+m2Iv&zfl8>IyNx^|IL8jD!cxpeHxlh4W_^ ztsQ%k`5}G;tZ#(*e=k0R?EkNBysYoHz4mP`{Uw)SC%JUI*sAIkJ89mC%JVjdMG;Gl ztguf`L_IDierB(+*FxGHCi-#9(h8$(W4jv~`mZHMTUKhVdFH24Me9e_pepuq!8KQ! zAzYzT0H6@xED5?=?Rd74}Z^R6qqP{dk%34gXG){y-~nTcwCTAjy39Uvhdsr-&1L^MbEo;$;sX1pov+!W>=x!_!-&<* zCoH?x{Ic>#^U{)YGh!1GkA1n@USYItI%(oGd%i0a{Y52zS0#)9SYf7^B`IC{CGLb7 zTg3SMV?k{q8t)`5H_R`BYG(p$uH;PoPY|c@Wg`7cXs!9E&N+Np8K;DQLNi;X?zCh2 zgYv7G)z_+7eKIKD3ChN>%vK|Jt{ecuXLC6a?+D8rxpThxLs|5wPB91RHSc?=>>dLX zpc!g6;`Fe!5eL`T7^lJJJ6<`s4j9X0XDl>-x7h3F=h3+P1G)OVCDQvv`ux25)u%eR zc9z+g5>E(;=L0jjaGjbL*Sd9U*t2~Jb=(_vk{ZeF;-TeL6G2gkzZI z{g}xubBC9!!P9}u&4QH56=jtx%;pvI66YPhXl`6k5YuTg1b5PZ&&!t!={~3n4idD@>&&255){@$IZ(h zNy<4;Hlp-BOMV2ppcjaALZU0oykjXRvuBJ1q>p>qVy6u|#a?5W*j{qEe8I&Tjir91 z+tG%b48zCxR@d7YF^(BzGdOs-5lwx)ct=g=_%7(dXP1bEc!l{~$fse4TKflo*rKem zLtL&k2u-ouTla_EFAckf;*V)O5~(GH*+auZR++02=lEoYfsTE!I$7)(YLtiUDkCK< zWCdb5pX?&g8{mVTL-Ds3-{0Z`*};@tWsC^(42*N7goO_Yix?6XH89Qt6-H8=Htt^- z(F5bcQ^MK|3F|NdR;)G$hk261!dJLgxrT>L$qCCE7M6#c!@{Pdhh?RNd>$#6f!g{0$K*Da`;pBPwL7^Vi~e9v@m+uxH&9(m`~a8u&A^+&1|g;4Vv~n^6`(q zeO!$zQ&~TM9V5aH>nq&D!j9-kVMp~LVJGoPUz6lsK(SLF6Bc41*P%h%~sv{e+E40E3k^P)6~Aaau{e0-pgx z6v>Ctb}3iqWi3*rnM05)7a0!gMx{#B5jH4Q$~>Pv6Od^ry5~YY`$mvP#A&JZlyOM1 zJ=hp*#UwPsV6@_purn|`oEdx#JoxGcUczx%Us<-KLB)QxA5I!Pgmt`zOuwlGnKhHm zdl>zlA-i1s*7Y3H=yUkz|Hs;!Kv|Ym1==@?LQ*Ztf-akb-<%w{`WkyrD!GQ{<*B= zag?;{1y?|Ep7((1tFL(q@O~4x2jTE{m2SH9V>d0V_guX3A9lQF(gv4Xd;#~26!6bg z6VfZb34ZgL=Uo{@xW3Dk2hu(6xAeK*a{<63^PXe@>M&`aLHWDsdZnMn#vje!?Hd1M zS08@f1DiXzSN~o>g>N4VDtoLF?_*c*eclx@DTPGG9NqZLtM`BoCn`mzN&Ga&)b|;< z{SEm(`U)+59^~wbue-W`4O< zeCpNL&O-s6JO7Mm{U~LQnY`zUUk$?Fa-KV5E}g%}a9q)hue6lrQr}}K@1yRN$DhyQ zU&6|BA}=(NN6cYlIbywJ#KKeJ(%E|HB$a6nKVtdJtnaauX?8#2vpA~!h{c7dwlDYY zC@xJC+7Lg^BxjuD={Hh#8YmBb5r?0)#BpkUkLCAf{VK~>Wc?b;S7-fN%hzT7I?Ib$ zzuxk5m=l|Ad2QCOv3x|<-KD$v!mM9sd1KbEw>*&by_UFMea{V+21!xB(UP!y>yNWM zpY?Vg?9)p)=%xiB15}AE$iFvIyoG~tc`L;~W|erUcu!}v{+TE!QoTLHI3LFnQmLxkme6M)C5j-v92j z5BUVWvv^BXr!C%*S1sO|S1o=yuUh!cPG7&9(|ps3OH}WTyC){UX#v{b{R)SDwS0Hh z_gMZ$)~~Ys&8%Nz`QEHwYx#dT9?*>Mi^>#&Bq#4 zfvEgto_x5mf`Z^WsZwKOyEt&B1Pv8*HEx#h`dn~^y>sMKt0*z;`vHY2=!&>sscbw$l`xeiQ>PZWq zr1#wiZ;eaS7XLGd3-x}e=A;d_Kzvv7u6FMPl(sFsPZ>l+7p*f z_?kmmtv&FqPvmfsMKRb=I%3Jeu`uEnkuK>n&fG^}UvF%=!(M7qfo7 zmJ zi#}dwsiH`|#U00Bj)PgW@Tbh;D=FTP)$U-OhzF-F@;xu<*V`ZGT11mgB!Foy*}bXe zjKyz7^_0bH;?-v?d{0MecoKKNAs#&Y|4_U!tN)YYC*r|&X1|F`FNnJ>RQNl81kU+8 ze?-;qJurWJE5*~Z`b>&`R%;I)!m0V`7>Rnx>~c@sdFe+u&E~gH*@d6t5R5F}l=VH9 z7qfnqn)FGeXr%|tlwby%&gyN`R(ZGK5zM5S-;Lw{k=Q2 zw(GqdbjafCxy{sCm?Vs=7B9)Gwa5PEo$;G#i^uahX2-;J`I}Sb7W?k_O-m%N&Nk>V{;Jz)n>@KVW#u38mg^lW8}*Kr%{;kx%8K#Fy!vfZR=zh+E>2nbZ+UWQ%8I$Jq6Jp& z%ae;!R{k_kE=^ha>pZ!4%F5s6$;Bxv|ClG2rmUF7D&A)0QF(H4%F1K&4 zl$96d$;Bxv-;pPmrmVa)Pwt(v@~S*}+mw~x$&-syR@l4Fk6xOx^5=QNz*G59y<_F0 zd2(^e%3szyRz8&{_fA>S)DmyAa&?|uoU-zeddJG==gGZOR!qCaZ{9X#<<300IAvuz zPcBVad49cP#bjFX9V?%zcdT4VEOFei@`OCOIA!HY^^TQat#_>aM!jRjd{VsN-YF{| z$&-syRz995m!_;d5N$Ocv+|)lxj1Fzqj_>^%8F?h<1s7OJUC7+PFZm4gk$rJ2=RBo$xtUNVO?wzvov^;s+l$8^C@{TDhy*zo>l$C`%xj1EIF;6Z{ zS-B@q?wzu-o+odcvhvM&@{TDhznv!+r>wjuPcBVa`GY*Ucgo6rdGfX?D>q(Ux^3mL zc>*X?*_S7PGL^%5^0p}}FUgaOQ&wJ*CT$i#LJDFhldm zy#O$w`WlKiWwpW=SDyhqJea|u`e+KLnyLwz{)%Q%eK0M%j)SU&4ejuSckn6O_kiXl z@BXIG;+qc+O2Wx=shG|$?wBnjsSkHP4+Kpb!%2^mexNQVKSU)-1Sh}F$#2#>AEfe; zdh#z+J~xn!$G(J$y^Qbt0{#0HjySoGN@5X@X_&RIapyazd^o0zJ1?Z4-xYJg$s4J> zrJnp8m7lLC@1*jsdh#1oeyg6mm&za1lRu^M{(ADyRB~o*LHTnk|Am9;bg-`Dpej@N z%By=Z-TgZb zuAZV*XE><7nBqIK`V$oPo~yM1KgJhdpI^0b$dQ$5dP1sy%nKbys)EVG12$T*>DTGb z?_`&*;O7s@H+><6*%0~8ofO%@>E}}Yw!HdwitOw3jeOC$ zFe5v5P!VP-{84=?SAIXQ3WPEUu3pi;{OqJ3XYI!$q93i$WFo~J=93mb6AfxV>0MJY z@XK^Op)HX7u_M(Kgj8);?h~E{k~|(*_wXu z@~`<^9!d^z!lG~pe|k86-a=W;%ExPJTg}|JH)g3j-zCQXszS8mw zvcAXi3$uQe)~~nxA6egP`Qur?!SXFxztQreS-;LwZ(&!HwXcUcfISNz0d(sqdiP0j zY1$%xJOPL=;o5C+`;^69QJsD{#ed7{C5n$_wZ8HWPV>Q&-%B+gJn4hJy#q1&DL z^~~}Mv%bf2U)Ha(yd~?`SUxf9*IIr>xo)W+llK6B`RBXMeMhe?zB;OHuf2OXE=@m) z!XJ0+XOp`pCwEWQH~a9DIc&A%9a-OFsmHY23ZFGk9<8t#M73>&cjw~L^gM+>?zF%*qax9DKmyZ=*V0bK%j>BmBT0 zb(;JOJoMza)CvS|=aT960B!T|9gVx~2zd9_xYUvlFa7WM!HJJid@`$kcPbt{Q5$IT zy+b=M*_@|v*jLLtvcAVsXLfgLe0G6@{?#{{A8#=(wGBMU=~7&38|aJf;qW7t8(H6D zsaL%F5ubf7N9Q9WPM;H(+K;Sr`nzBuc9EPpubElT<9D>ynIF`3;D z#-;Wn?p627xYT~c7ySr_AF+H@*7sPxI_pxb+3`M%e2&=8Av zM73>zcYiG|P5&aCoTRosx1`#DyQ#@OYLO&_CJeD?H62H`Tn@ncG0K& zF-`KLzn9h8U`zZtF#whryR7fAM4GUEm8D2Q{Tj=MWu1LsS(=^o>ny)0>(^U8I_rBa zZ_4@&mIt$bqot$9J0E9xI_vu^`&r*(Imr4|mg`x+#&V-vw|qg?k#X~n#jVZPa?oRo z=SQ_2NJst8Ir#FGmLJLb9?QSX`c;<4|D9^n_>gzoHtGwh7z9m}M z-u2tx#^L-}en-~#Se^x8xPF!8)3bh!<=1BYTFcq2UuU_V_3JH7ALnmtEBwyOIG7WQ z4Q_W}$-BQ8cc)De_o=L!`|XB!aQbeF#jMu1cPNoRH;Ejh?$6B*N7bJn$?D|iCnrB| z!S+6WW3D;ccADpXnCc2eHnSZpzu^Zuv+K9~Q0J0OJ{p(WDSZb1KU~lJJ?q)*5k&$z zcFJX;@%+%`&n(6oEU;{|aihV_waeaegTcB)iRWF<+PHrp*LtjOW;ItXqeJ>czUi#-!PkYp&;FG4ssYs4-3U^xWgc-ET>Fe^qWN~NI-Kj( zL2Aqd-MKz_O=E86&Yf7Q*qa*Hc_f=WBPiFtkga~bD=R^X!rfK z;pT#z{Cs|mwZfy#6@Jt_iWsS~5RvuYtZfFK25UfLb05J?rSGl*?YU^V`S{L@5&hH| zfQJ$U70c<`xw?TXuA^%&+`4jcvrnh z*}Z;m=lT=^%$IOHg@aut+Q05~u(ti{K5JZB{p(%_=G(s-Ve@1L=hhscxc7Ao(<;Y0 z$GORnH7}w5a*nri=&m+aK<{<^do(`C$8zlF&?Q~}KGW;J!*BnH<0Bj&G{<&4xOF3S~@x7hv`!FXS;5f{o2ebZtrq{KDYpv9rtv&N+D1U)NtLmFM zUdy4eRYSP;Z!N!fb7(z%8fE>{z4sFwZ{&CrNBz_L^hS=~=Fk?YiSnHs^-oWe7Px9? z>t5G_SPf$z|2%@_IW&cx;?SJ_*BqLY-^#JXp$nn@eF@KeDaT_uw3XGr&-A)&)8wUb zPUBGh^SV~7di^_#y-QQui#asAeGA7YF+`0h|2O5wINrsf$4BejFLBIq{3ORSIc7Mt zW1ZpnY!1y^8uYH9tbgus@*Ixma=5`<{j0lVXreRmv1Yih;i!MwPkxr;?Hq2VQ2(BS zMEf+3QyeOm>Y!?q_3tyiUw?NG?@(bJa+pZH{(ZXZ&*zyJalDj6wNMRGU9kRrruXab zR0dzi@e>^860d)s?z-B>hdKV1Lup@)Equ4|9AaNBw&x^&jPUEr%(Y z>)*fSx^i~?yB1OG5gcY;eiBFhQviDm$Cq=M)VKb9y6ZLZufn3jU;Rq~fRq6wvY91O zL}MzF-U8cwtg!ff1);5(KS=(YH6*w(Tz3U#ytKa3@3|nK%n}Xha+aI9QE$#%FB@cx zSQ*U0#QVMBcoy+!VZ1U}^?ZJ-M~aSSyv>ut;Q*cR|&TNw7V|~NaBJl-; zoZjmE>fFW!bNQHbWS-nTGsAJy>yd0n(Qzz)q62C{1f>mC!JU5&h&&s~kppCAG~djU<;m7K!)qfy zHMcr*Pj6vm%-c+m(^Fa^pG~&TF&dA^I@BAj^#d5l&OuTV#4MA9%#XK)sm{nu#I%mI zedo;ft?TF4rj^*3O)?lYUp z>v7zE>h!VcW4AhEDiXuIlfKL>wDVQehw-y}tE8$L&yUWd zX*g=aiYf#kxW2Fula_G0lpx&!E1KRLulMYMGd8z02qft@=SRKmjluRj__R8sC_3I` zXlbS02=Ti@=EkCL*jQ{xHng_6Y6E7;5EV@yEi=LB5@nG2L=5kF@~_PIMw<*w%;y3C z<}5K{px4^^Wye2Y6jTNYgt7TyC}x|Z`QFX@4=gV|8z7ilCxaKb60-5!<^UYnoCOWW z^Q+Cw)=F<_o*XaZW}8u=t24uZ20lE15-h9_NwE_mHaSP69gIvf0xlN^bIle*&>Nj2 z=?U4NHd0ofU-PQiILW2c%&iT!=0@k6F=I48$L$k22=l)A5 z6SIsF)3;5=p+Hpi-$MlP*vC6hP207jjgi;t})JPp83 zK;#RnB6208JB$sgd9$NAfMPW#Rue*V4k`(T#QdQ!1_>XG#~``0Il8b$--VJSwTsk& zCkf@K0SaJQvwhz-CJWrCNeo<=w*irD%?b~$k<6+eb2GnYo*(GCoN{4%)H7w=3{0q5 zf=88pp9glp;n9XRl9jow${ho>w+19-6GIr*WEzr!_@eZr;9X^R$5s{&9_T%FW~ERf z0D7?4kVyyLuwoWJdb2S{M{NSQRn01r_T^3JzT9>NHru-$Z0kdI20eCDq!aQ$Nxe;x zikW~$GtFQwNCk|k<-@(+;%KP>R~8p$Hen%vBh1?DL^QL3%+eugTqeqccC9g`g30{3 zW^RruqzB+3BPTF32hY3=fHJM~K%o9>#4y2!VdH45N?V21+kKC zXX?KSN;Frg7FsJo0Bw8n=P;igB{6(@(IA=AD(>>7`hM0@AK^!4-2nh4Ir z)7wYqS5}S&y)uU)?PpqMNWJHz#+aKAO+pg9%@cYoN-A6hhP4UPVnUc(J{>eE$c=Ap z%tF|38Cq&0xaJ;GtdZ@LB;1OIb)>1C*2S=6cFkY3c6Gez`1u|oR-6yEvKgbtt40S8Gl(~Q=VOvWUr}guGSzRGx1biG z1i;BMwI4G+HxEH(gjNU2xwY-RUT=P8J4EP0Mim+mg)zQUn?+n-R?<69hO^Ycq;4{V z`sUFRQUkJmz|P8gz>Y&kH^C`M2947AJf2gg6U)fuhPcGsAy^`uDOWlw5N-wbNgij_L>in>v;gC#iWtV=!=UVlSXC|6HfV0UIrikEw<6|YkzNl? zE!Yeg1>5VYAD2Ox9oAt;6BGgRy|z9cEL(_0Ab^CcopVC zy@LwVsb#*NjJrs^fh|ccgQ_sjF@ zurNSialo*fU<;Zxmvs~TrZ=;-7$Pw31U6uBmQAFH_!v1Q+Nms`f%}IHSOf zdKY3}BoXc<^^!hqlRbA$YX;(3w1^KvT>-ZM_GY;1M9LAmw4u^!nim!#n*%sP2uHo8 zQ1jDes(BBF9AXSjM^bQfmZ2R1mPuad7T{qfW6^dNc{*gDRqPDR@;W-6ybS)5Do}T{ zHY49}NT;a{E{rrtq-jfX)4Tn|?VvX@kV5XlU|~JLG1&{P9s?)Pz0K9NW_8$GJg3)q z&2dLm64(<~5KIW@;b%g0a*=u9R_Zc1X^MaUMHD{}+-L(mWXKZJ+*`E8~WixuCO zGE}upBL|J8-Lt(}6N9ECJ>hIJ*j_P3fnvj%{Y?}H5~|h^Vj(|C|G;pjQkz3+^{vuki3;ToO_f!Sov&d7^(?=PD#U6QZ83Kh+a2^H^4Oev0l%Y_85RzO$ z$_IvR1ozfT1sTvsh`EiG ze#*;0>H7H={!#*2nNdO$X|_YYI>*?{AiylG)MfGuYYvE1xS3c9nb?$J7KSo5?Uh@E zc3^3vIplIro!kb8YK5glG^p?dO$;G5y#o^@V3LN|p0{~Nf4v!>2Z(qZGKX1jdy)G* ztzj*k&yWL{V1WxUL~4jtY-$GQizq7{O*J*Nsdx+gVtsBE02RzaC+MoXT5I_z^pRkT(;vlhhkl)J{h{ZU^hI zBCZC2k4YB4LKVF;Rc*)>xZVs79)1ED;Ac?bi;51Zn=qhyaj>x^vG4{XS>&Xx)fm&c zkgNjm*lp#OutFaO6IR!?8gF3Q0a>xEAZQQPj`Z)@MEH@{Fx?@qfTuozct1oYV_dYq zgk>pQIB1@mP#jc}Clt!GD^xWzCF6J701g9Kr>`N&iMxlj?39L-)krQ;$ z05P{RGr;f_?OK^lETV*)hJQg>A=Qk6PNA7;bRGqNK#Z9m4Vvv0EcGLVX31r!6l=qz z9kdj+;6ReqAgH58OS)#-Kv~7s4X{t{L&9@yH)&g-e;2|xG)~`85F`Z7nIZsbh7I2i zK&=A7XPUvN4~4-x*9VpPz;=j)DZjNm7+HO*2!5;mrogCkA@f_reqUs(Vy?tQsWez2 z#2Hmbtp?Qic9r3)fY7pwuCAZ{f&htee-&|25=O&!>v4iLh`*avBrwGCIQR12w5TsDd?a^B`g-U4^ zbPq|i^wk84C!0eBpKX>C3tL-#iYFR}HH^dNHlflEA-zj;WR73zm?5xD^h^;EUOK1a zpnzZT-eG`2s?r4)6Rbl6V7Yv7lk~aB-GVui8p;FWRm%ntc;HnM8y*yHFkWg6U{KNy zAz7VBo&qeI!^kmK=2*p;OB>a6aCYkI+Zb%EkKH1sId${?L)d7rOrsMeX@Z!{tqf=| zmvl-%%{>CTTfCL_Lp4!U!%cu0Qdw}~+PmY}kyCg{uwX|HdKJ*1ey2|Ljvl}3u46|} z-+tF^unr`&_3;?2lzj-qfwcYMwyJ%wzmQQ;B8#j{H)PJ>{MwutxwrsEN+xWu7>(Ui zKuTBPZYHMdV6e8tMl$J(fY<36m(-;uD35mbRn+8=yt`;3p^^dD(ETwVrsKU;p$=<` zMsF+`!%aoV)FS&jfjVyIuGxL(NCux~>x*bSv#S3sMz-QJ{2c@E3XOv1$=SCMZ)ipO zY9%UM@52$0NYEK+Q`p5&_WD2C$`z`3Dp4e zLg60>$Pmk7N(qIbBK6K`zKmree1q&5pwr2)zi4wSTS}j><}sGu3sTAu=*=B%L0MuK zjly>5pPT?#pj)Mp4m!G~u9-Q#oRfWSqCZsvY+zM$5OL&!Y5+o2A*P{udM6OE#q_QH zy#X8-wa7*V3Dx&9*ti8V&GzA2Qe~nQ4nm=@7y(Zn*jra3=`EJTvfI+vA)aL2<3atnaFhU{4z;!qQ+BiG)_M z2}`PH={Tde4E+2&Qs2TNO5z5g9{9Mz84^ED`ER=`0G`*P(MKo0^Z2c2?l{&vb^6HZ zW4+ssOFC1v)p`iT$_e0pN_sFHOol^z8%&h)yatjw_5%1sHw43#g=R6Yo_ExP(R~_i zBEF*`a#76z@}S7NvFPPyeaXh)4+<5_Y1J=GTk+x(Ecvnpo9aU7;Oiai=w`q+cs+cudjiD$a}HA;bY> zd0|M>8!3y;QuCJ{ia1gpQ3Uv5YXQ-v|*tLT)Vf<%w7ug;w87O2soU*W9cxCVmsYV?43y*`lh$>iT}47$Ro)Y|bx zUom0@dN5bSUMR3^N&m3suL(cG$WvP&q*nweRwHDCpk@ubRN-t#X^@Mi`v#h);gaD5 zvhf$Y`<*-iYfZCuAZ5ew;0+|s`(>Z4C={0trfm#dO#MSaV;(y~ih!vn+30E`*Rq}w zU3L>e6@g_PUqOgmY?+i1MEb0tCJg%O%-j(Ltc+RN$+J4Nf=K(4 z-Gqfw?{E*}m$;8yh8D9I%8ekRsWObH>7NYG zV3!njU00!!j~cpWpo#OALROdF^S-tC0yxRE1^;5GO2l8-{v67JGCQYbw~?V$DG>n% z8%u%fepzZCg0Uu@YRqxNJM3~QM#eH2b0yhvwuU{ee)LL5T1)MbO@bBf3~)Mg*VFDg ze)g^op7NI6)}@wG1+0a>83bsEG&-B&hTl#oD<+xdG#cD#G`I~`duRqP!alRGio^>I zP8rh9Ww3%*5RG{=!r>yg1NBO5wnWVk5xi33YaZA zCc&aNtuAXs$5hVp8#JWy;|Q(8Uy8gFYC))wuu~Ppl=##Rwo!tEBoP0jfYq?)C1!&N z`+)d3JHoAq1T6DzV4-Nc;fG6UPAi5)d<1z$F38BFFb5{$#pG!e)-;)HHz$-HjKCeu zh5olm(9ijq<$3MgME%vkSpDUEnpp?`9ZX`oAlm6TP(YFG)9#2h-Rh5uACIHko3AucpL1v9Kt zu?ZoMDj!Wa=}szAi93)G@SpyMh&5Kr!+wFJCM9iViB{yL#&lz!>}%exEhjLkBDrMJ zc(gD)>j(pwR*3PUVIp}uJW@^UgM;}M#ymyaqRXM5sBGbz`79F6EVk0 zdP5h?4hXHSRp!(3lT|5R$X5mqp;iY16d5$^Tu?zRiYSMgqv3Wv06A0-sfn9gR-4rb zfeX61uE=YsjH*z;+w7+5naVFlbmmBl$i#Dv#R0Zz%hN9@N6E&_=W zW+IdVL<1(ntj~jlfF0QO2$EO0rxH%(TidS?@*ggGrR@)WV=_qEy^krow)VW17dPG@4%tn z{wL@$bbWxxZroWcYS?XtyBa zUa-LpQEA-#SMxyF2CIsLvc;~Wgl-3%?Bce7UnnaXwK8^*7BU}0UgB$oBP}>ulOv2E zyaK^FpgnHqDt$pAw_mz}XntyBYRH%dTE{E3SRjB+M*$eS|IWcjwk;lqjM5ASyf9#; zPB1>iX_Z5#TagOA3o0AJuB5W)J_xze3?haNNC+Q%5_%Oay2v^NsWRNpebwn20%6Ea z*z{(Wmp3C$FlB3pwx|lR>LLQzu&3wqlWwJ|*D@)8hG%1WMBf8!k8Q&)5KE5fDA(4( z?S6CXokx17&Kx~@?9?e;$f>JgFoS}sYCxXxr6$N1BR^k;mS6~gvohUq2Q(1lp)-WG z_=*mr9F*yeq~b2EBxrK*K9j)gc56s6?Gg>52X8)m5L0}oYbOveN) z$PYtlg7T#^0v*e>IU(>Gu^qliHz|#CMf#wnt4aaX7n<>P=+CLhBy^`b9(>2-t>Weq4gJ(tdJH<|1?>J zzYL35M(8`YF*7kQyd7aFsdjL-5Oe^objGq^AUt@OC`4QgMq}0tl}K_|bulXrH)Ofj zpN&Ns7mWLv-<}Jpp(qZh>Q#pbN1||99X1GjF6|0}C4!(r^w=(5i&ndmk{KL2SK9mq z(@!rXh6WtkIl~hwH)G{0O08)jRxzr+r?=Qw;X@6c@QwYq^qvSBDbB=Nw~Wi2Cn_4; z3WUYM>fqCeR4QQ1pnbYeQy(ZY_h7<65mt#NV3g6JQu!t5N14C1Cl?6lr3I!3K83e9 z1Y<%~(p+W8F-v%nahL;?)MhydtyU3G5Yh>ZwxNH954eAKnCc|^5sX(^3)}S>!sL+BHQWN1)g?xYLr&1$E0{0MuP}GUHqeR~!@9|RnGS!f#x-#dj*(%cAz?mX zMUk=A5b0Jds#2qR8zSz`MUx>D6^4hdABIKU6UogAiBE+nXnLAHNBB273zX8D7Y-uV z|4RO_88e`a6k~X<8mU-tg$V*{@XRa$os2h-9#g*4=63up6j>m{HNmVptSo|uMfmsu z(VH-aTrISODJmfnA{on8ck+JYM;x{8Iy#0uV#pM%VJQ{QlNoKy7);6#)ELQ$HpK6U zIl4tAgmjP!c|`rQmXu$F%}vWw)7wVxPLAyY=nUJkl0s>7+g)e&9^HHBru{b^*n42# zz9;P8f8fyG8>g{IJ#}WB*T4MGfkzvMOjtosPMGxeI&SYp-3)agR0Qs|$cQ?+p>OD$2xi?ghPMzxP`+J* znM#m#0BO*{^cWV&q^G6}@d!6aMd1Mc;%*@h-OzmCm9|3EgA9wRSa)5oP$K<{OUIVR zQe}lFTt>n+%21uMq-K~HW2wHn2?|!AwEZk5AR1XLR>2r05(tchDiY@5gcCzNT-+yH zMXHK!rI*E_(9xCzrVm$9w9)4f5LW}9%eon*CY&>@5M1r=3mK}O?S~>3*<6Yo-Yw4~ z0IC5-4edm0>kk$ge=VjZ{Y4@9EJ6v^Z}@$=R1Fe-Gz3WPMFo?RDl)a5c*JTYQGSXH z03mp_tF^kY>qjPnSH81Z?XQNNJy<{9uqs}Mb#PJ&TZB2uDjt;{{+NgXqUGwWlW!#F7{2kFSe0CvoEy8vvOt7%Y0ZeKSe`d0%O^ z9n_uXg`Hn*tqy8M3!6IjwUgtyV0n+MH>2Mm{g8E>dD@u;UL^T#tXu&4czv05bl5l4 z(+old?6)z2At|M-qIo69uXpeX2xrX%w{4iJ>K^-c9B$BrBQ4AeY^_x~acD z0H*46cErF5n`FqDbQ~V7>OnLQmL2h!lxj*v+9| z&{ZgWCk7H=C)rDYkm_KfN!aHhH^g3`(J`1w42}6QjCPi>jg$n1fp^5zfMC3>a)e^} zUA6lW1qL~UwV=@HKh;nPxEz%botFA&A__8uLWB1Q#>r#-yLVD(|5-&w z6eou)%yeKAE28FO`5K`sg!mNuU~7S!CN5)|xC~lWv>W-VxQzicq{Pr1U9zY6waHR3 z5|yZu8|F6|BL+t2?&N}?xPvXD4f>H9T?9EG#tNy+lnfzrD$(Iz#EY*o)^->ITUO4G zw{AHk5*ac+TbK1R56F)bWT>BYhyfhKAUk&}e{WmoW9>wR=L`mtBBdjZkJHRhB@!VP z+u~b`#492G$^L+|j2F*W&X@m7W}hPI;h4jF}4i;5k2FX)BpPY(@^ zU?<{Bp4`cYK(t(rx+AGp6w+ogHKRvbgT%y>O0qAr{Ui)4CPTnB^kC~L5HB=cg5QIY z3HweQz1=XXSP8<^7uK$vV(vXjZ9=LallT|gdYF451NWN^fxiXaqBCmqQ<)zu3ZY^@ zoIWUhaNjW5lF~0SE`XFQ#vue!GhZ_13DeD?K<{lT}%;r6oQ@#J?Szu#{2G;aF;GJ5fhs9uXJnj zV0{s|nG`kodWmdL374;BpnHLE))~ZNma0)lvH|kCMQTDI$x!2+4QS<^lBQ7xlE%H@ zFV*sAgrvM6;D!jA5PXDFhS{__X;cA9itUTntSikypjhW6$TCl2j-fE}*oX<7m`B3i z)`?KirzH(x-OemfiquvlC1^>>YXprygjE4&ZcqoE!X*TKvaZVq{7JOEW=_2&BiT!N)TNj!99{HZUTw5Se%YgoEq2N+SeA84_wQ`y>$= zZ?%1bSLzDbj6zqqpY*DfFYzjZm@v-#gh8gYXa~hk*B4ArOoh-^1sWuUT{DHSXy6Ix zocJX$vZ+?CFGs$f29|{6sPp*tyLy=GZ=2SEj7n#ABG;PrNkkOo!BQTI;n^v<;3Y2t z9BNjHSpvKp5VokVuq% z6J8}^v5Q~(%qmwz3 zp|7+n9iiwUafPJ`6v$K|$<L(2wk<)?I-5a2jGk$l z6fH~qMD{KQdxR-Ujb4I;ND^@3(pDIA$IQ9J;=fj1Hc-u66zEjWGJ3!Y02YixVZ~i zu9FrIS{G~24FttkKn4La+i@Econ< zd5E+{>2`n#Vux{YfgSDc~H~4=}Z9CR$-5*y~QNXu1O4N#BT}&ld`Otp)KiGVsJQ>*z$N+a&ry(QE>} zmqDSexxp47EPZ5#jUB=4fDJ<-6dlhLF~FA=MbqF3dk`EY$nl{LAHYUhO)rA-Ch?=Bw=vRz!70YC zA`1cc+8YuEwHV~YPSg+JCM-OyMo*7gzgbBpRik%hdnFcwh!CN`=o82L0%_3-;KlIA z$cM0#Y#^%A@Y`W~M4>xY8g+Ic!DXGXtJH;fGf*TgS8CYB zys(n%hBKBD>9h=t8ci!#l28hn$H*FHhj-99kxNo0h>3HqhzZw3BMn4BU(2jsH6CM=%#Z=2%xAc=3|u>+Ps_@aYvpK=pF000 zSz`{66VQVq*;&|{PaSz$@H3ht>eGTsLc_hVbtv-`XD@`tr2$+D2|1Pt?}+;zt3;)> zH5rhZPbKlOnkh&WMm-||$R!@g18A4UL>ZY=7O@Yo{Bdluq)BQPF>G?>3HVMx?|x{$ zgHrk2ZbGkCrjZCsjXbxTXubmsbs&6Qg+{R>*rgt+g%#HDr^t`SHyrN;wvhVXEA!ou_T+GXiXbk}Qb#BZ#+r?xZ)DMzs>a>`wwa5dGg)Rvw z(uvL#;!9Qrvl%Y{LE!5Fs|1w6Risa}zdwjt>h(ZE0GTOeQ-`TURBl$om|_39OMo2M*xMfGzv z`XmBQg_C7Ddft>WT#Q<5uE4ed%~jKjKz^)goRY7q!YzDhr8 z4CssuEhLR`JiXmJ^)+`fxFjwriB=gZCr00wGdc*xl`9#i%y1RD2a#_#TvDtHOCILS zEmiil`QMl~V>n}vvm#2b>x0~*-UyScj32@#4Ex$Gk6bF;ZZ7R1IJ-MnCsI(k@L zOK4q&RH(n9xE((;ee@WWJCEOuWmAxdkOL)9&{g?y1Y9$+hG-1i!21v!yBTfn7j5q9 zT8yJwUXb&`@`9sH10BOfU`rvPzzO`0wTvBze)^({?1VqaxOhXVf?;{mLYQuZJ^>8` zL&Pi8Hl@zMpoKFi!8QlXBr$a6=GDE5)TVe3?~>oAHIybY4?s1nAn-pHtWng>dVmi5rI?Hhs0<G%_FXa5xrs1?!3CkrJ+DHnE6g!prcxmG!;C#SEk_R!&8rox@YeM-rOsu&tNa z*l{sNO*%5_Olb84U4k7J;bkIh%kj7q89R}eiaBf;J;tZm6a3)horEL=0 zlw`IeCBex+M4Y%@lFn|&_ijn;?3<7wmJP6~hBp2n?RSYq& ztfwt8p%Y6A@yBE0kBd-`%F{^@+F@5<9U;AFV`V^{v{)%o^b3H~2ts6FvB!QrTH_Fg3hnmm47!d$(G%(lOheSNw&Lz5^Mzro|>_M$2 zQ(lKg!9waD0USz3uB#fE2*D<}R+fpMWsix?NU0Rd(4lZz>I5PQ1p>o>!p{-J+X(HULop^I$pq|Lv8y|fP*0NpCM70n-;_v<8m621@ZF|V1q>Xr zRib}5WLd3la9hj+K~t;-rYAAaK`_?gcxdf%o7FIfrp4}x0B?)2+4SKGsYf-CcEaxyFF5*1o*aWK0Vf!3} zQ8FObs0^bq5aKq6xjZBwH4T6E#XRxgCESTa4y<)K+Edaf2)Ph}x7!vGLI#kQ* zn&1GVGywwsaBkGg)J~YY-2Z_nsl#RP%WTFJGWRp2yN{qU{AP#4vR*=tLjr~Xq&;5B zs)zyh%|$>WRHx{g5kH^W{=`~@B$F9I+nBE%MD5g>Qzwqy1zAfbB(fwCE4Xp{iKmH`*g|G?c%91P9@w=BR26=3Yq0pIbiY2MCu?7_D3LdgNz3dg6>kuDU}@d{9WH3GfU|6HTOZJy$ap*~KWR~Lw6OvbzsGqV-Y*8O3(<~G1W4#SAzQqUh zV{D5qd8*3-WoZ0jdit>PX5?B9S*Zw4jk2)1mSIz=bvlD8t?3!SNX&(aXFw;0j;5;m z*QgqxEImrn*YfY;({U( zew;KwjDj^r;sch`&upu#G3`aP>{yC`QG1b&8D*gaU9Mpm7K0}C%w8mLFYtl_5n^8K zWM_61Jg0h-2ms{&vO;7MHGokORmCJOh~z*z8oE3K3a}r#95#gXWDxO9QuZ|O+e1_n zP5sOb(appxWb)i37G|DS0c-@q6~a>)c`_$RhcBa~?UYItEe*~yKU;c9GrpJQz6MM{ z0@y$%blg-biZutndRRXLCZ!?-X988mcrcRKT#|BxX4if~DWxD3SV(>>B+J+VEb!Ur zRrLMS*p%=-Xz~q*O62`$*jOpPr=6G%xqL9a8XXm*k<1{gu3C?`q&>joUic)2u9tv@%LfODD)A?zxQ0V)p~ zDWEx62;WwSJV18%%p|ggsz7ZKdyrR#BsL+0J0!`^kytX3}G-9 zHqXq?^$C7Dw$?Ybjwm9)V0s8DuS&hFINN0K`ow7lNoF>*&Si2%kj|N`dUtVI_1L_C z5SKN=4q6F74@mIYSZ63X6wf7N!BTQhiHMQe!T*9+N(iypP&a#;a3Ki(3%rlhrVeUpqI zsWhNNh9h6qMaBnV1&tWR9;+AJE|L}ntBBN4F*8L9)Pi83R8fK=iYHKDDZ=sDvq{O^ zjWk#0+5bSKMDTaHeM%Y$(Isqq;XGTg!L;Zd@|VIwn}TKk&eH=RokYB;#%#eT21-I1 zT5d_7QWD(-aTk|K^1%l(r%G#Rv`y+Z!C%o64|Pn}yJHPkBVioOi>$LF@@OmBr&Qkt zXxEK%^by5i9X)#c>C=~``;0|cX_ENHegKh=1^LeLw~GR1>*G-3Z-ebZ%MSR497}xA zq(em|v9=O8+CRFHOUcp;6^@pY)fgbdlYqRKEBXk2ZY(I@dBM^DInGcF(+@4L$IXik5D{5$a+69tZ;A3A;4LsOesCDEB z-jy4k0Mh9@j-LwosYJQN%JnosV7ZLNP`!g_Hw!YZ$(6&gj68X@8&QdNKvMt)$$Yd8 zu8MLY8pgexT=*S~KkT7J@rv)NyKb)OK%1x{fHi(f*BQq`8}|0qS7$uZ7LN6lH0xw{ z#jxE9(kfaI7y{LCAwp&nnZqmqgGH1Gc{~|#4AS_3#J#!W$cZN>{fZ=~Z1;+R1nGs0 z9?zz&>Eofbp$+jKBBZp-X=^~BL+FW(2#uHpUStI5BnIOo3Ij2YLOm%dP*SLFcPvD} zGncQBp&yqO!A2T~+<`421i-SYSdfW$cO*!#Q=OG@$|xTY&UVH6TWqnA6^RxzwlbUU z{mAr1m|Q3m#!A&t>}VpURLIN)9r(_EaGms#u-#Q??9OnB(`^IuR+dnu$@CHdFZ%yu z^b&K@fk_|?i+XiaM~nf&c?g0H}C+4dBVP(W~Qcb=|)=cGDOGGXL& zC-Gk}{M?L5lQ&Zp(u@NZ`_sxD0s-|nFiE*)==5>mOJs=+)&&vjn({-Yl_yT}S!iJv zgXNGVKQ<=OofJo~fsa-pLrW>+h^a%Vt}OQmgOaG35hTSTFrGml=4ELL3CLwO!c&C( zDO?k&^1?{mYPLb}g%g6GJDqw!5u(R597G0{G)gaEyVF1kr0-)vS{xxT;%-gAhkh@d zSRS8J(vSU5TGX3_!?kPS&8HrMn7}A`u*+2{Eof5BURxFx&7vs;@JFDnmVUZ4WlTnhjBIW2Px1{fLz*G4F*MU4HY6 z68NE7fj=(C49iBy!AaYg+F)_O*2=8u9Wl~^7Md0zg{*lo9lhv`jzTO=MA{#iR0$W( z$Tl`*%yp@LzO&(*26|DrU7!V@i2MiP1`z|$hY=VmNQ9A$`DZHBljTDjiNXNO4xy`R zEEQGQ^8A8sEZU0y7|s+CYXo1cY2WV``m<_LYwSmu06Ezz0_7(+ zfh(fC(H0W8KwjArZA?Q&>Wm415qX-?5-WTWs^_-tjBG5gWmDT2hVqNHLEr;6!s@}w zLjAx*z|ooL1~5=Lkp30?_>Qc7V~k(3GjrG@GgjJRfpNZditj=}*xZ zj%irP-K|aXdtibf8)Q1)P^|2!AJ$bvtB_fsUx5RPEe7ZQjfV8YJb~jh@1ysE)BDBs z*v=$feyN6}%W_aM>liZ|Ngive%aZewZ0&i4n0ajpx@p0Sv;rx$X4Fs6rXEc$>!T$2 zSRHw`(9ue$BHbaDoe(hkns*%3ATGK!4Kt3Zt?U;r7l15kYEF#zg?BllVG3dd0Tz}d zkI|%N`t&Ky(}|n~!^+4KJ#7$MwI#T;NdyLdStpaNp1ADp-tYKPZI;Gv%?g zIf2L#cM^eDV!c}V*rg0J_qfO(CK=FqO(Dm+`zOy$wk1jgjJ7qmsS!95&i3@3Q>{bxGJXjetBE8eeu^2EV4s8=f z_EQVRL6QX5==KtBD#AoU09+6yQpp9Hj!z~mo)CbRlGu-gS*A$2Yv@kWTANJj!tz&m?=*;Hd(Sr)R*KQ z3WSW{;sac=M5UYubNWN_GQ{$Zvf!jp{TM)_WHM8vPGHy!gB6&YGDEVlAiYq@9FtsK zTA5BERI$EETBbS^@k6TC*w=YO%~FaUP;KAd>U*orr+9EuJ=8k2ingqMEmuC+$gqF9 zh)jLNe8%uc&3G=+jRo#t4B=O0Z>$QT0Z%kmU@F|J-U99us=5Fwprqwv0Xm0RRoqE3 zrL?$5qFR8Imxc}?3KYK?;A{FKbUaw8i%8O~8v`53K!VCn*nDD3gQiEzWfz2-44CHX zvIj7O&;-eq17U#A5W^A}Xy2i!pgf(zHIiNqXd|-_;ek;9VD*vNBHo3Me{M5;J#Z$& zU1ws=BhqSEyX;LWEDNp?j-WlS?UYFAC_bmd`wr~i-#ZUMg}$V{FXd?ElxiRjqX>3- z=b%_mQ@I}Xw($9-fu)dvbZTac5o=q$zy-)?G@Voh&;=AyG=jjFkd`K^9|9p0Kn(!Y z0MLfJGccifRpSc76t;RDE)d*gZV|Kry4w$ZYZ@h@9}a5WHKF)%ij$k)7MjU>>N+rl zOrByXT=;rZ7LE09YBy{mTtv*GeAL__@dEfXQYYeWH3c&%`aUz>gN46~d*iuZ)D+SB+yh4WU3DOz5j~f=Y z+3AiVyEuTlZT9cmw{J{#X1E;Dp*h}$0qk5U8PQ16?V7ALWbGmd*ClTO`(dSGMds1o z?HDV`f?u4f87yWt9=SKU3~s&sRA;xrPw%ok5bN*|R!}KoT~f)!Jw!*r@!mx^MM(SA zXlz23!h{pnK2)@bA2V8T67a>Kq5&fQ;nnm@w-m<2%sUJ`L^EaojkKRghigPL$}Bhn3byuNb1T*+5BOK$um}amsNm} z3CsszxZbqLaD+!Dr>%bh0tgGjKxL236I0DAsLbP3-C{>17Jif<@CX49(VP?z_M+XnFkwK1c>_QT#8!+IJU$!TmP7*x`1tDh6q zJzi0S$qt&7F@hhqk??YQxH7vCK~*Qtntjb?tcXLm2(OPB#d0R@FQ}*nbu}Zb&gAQa z^w?7Zp|bHAU6>#g)^(R-%U@deg~k&jqVBg7N-`1Kr;ZmE?=gF&p}`S0099tCVbf;( zgoKg1U_HbP=&Hk{-3|{pdRJMZtL_rAtv=i)mU$uutu5k%iI@xA1g7C*UGe&G|Di)T zqXT8Naq>+qjJXOTSQyb{D@5Q#90%U-l9!>R7%qX5eH^=i^dVMb&9_+*5={Qy$c7T~ zKxm4F|a>MqU4?hBMxEm?tD>ViUP^0JKO^W`8)s`?w-F`tALJr1al4sCX zvs4knu@B2dvz%q+ScFK*vfTYupT+ktk-jlJA7Dp5Zdm z@JJGjvjZ7Hi*Glw-cC;+0WLFU zs*pg9X285Q!IqcbKkDaBq&B6V(<0PUSbpdVhY1zU4Tg%{3~GU(g>$ADTA&B;Jxu$e zP}*<9_nO|g2;RuFk23v?;X^3JDwBMpIAT(gXVgpnOO$7ZA@EyKJ_7gCQW7cBE2(BG zK`uH6#4?~LUT}0{%rb^UJ*#A{W;{Z^5mFeVH1!u*x3h#|7cV>Sb|6T+IDoWtg}Av> z?#NMX-#8g|F@gTnsKHR4VVg|4TVxosxdg3t|1~I0QJD1`Fp?9^!`JQfbYo81ra>dZ zbm0tTec$57Vkk_kIfeY>CT`)rEJ?RqiV6u+)eN(5i2A09lwXyhs78G~`h*kd(VuiC zY(fa7D9tG!GstC~PO{AKSY=*;ARDMpxza$W!1hRvMirv$4~w$Xa8!bDg2$?!mH3Mq zT~tjK#TtYQiFizPOxGEaOx}$EcMet+VFx2aLM9HKxZc&;6d*H=Q)^>~;yE(`Gw?B> zjVvn>#Sgg;Ve8wD;Kcs z%!87Kj;Rwdps`5mXxI>L(>*&`6V#cR4^Te6vZ(JL~34B-tc_XG}yFCe)=w>K+6>L_BG|DsC7EGLWp@9yPva(ybs~ zj%F4A$hOcykh*vI88Ud>e){$!cijFA*n{9+mcTg>SnOah>BE(2I}I4jf;ao9{4EqB zmeSyTGZw)h3CSRf6xw`s{KTMxbi#GDCT1}s26a>y!8#%z7)}?WmT;bglGSrXT@GL| zNkuI8NHa6)#U@K>ZB5Xd0LH*{{r+g-@~>F`!nn9@!7$#&45q>SgK!7`Y%Mfva3WVU z7Qv^=(-Y%dYh07LRhO&XwSXU$e9cUQt zeVu8Vq^Mt=A@L*B*yu9f4pYk@hL8pvqRmmel$$vD(zdM(C0I0=pPx_5j6n`k#u$mr1X8<>U8F9v zPQfj)KedYJ4f!V12C)!y6jF%p-*;!Lc_d026)5g)9&2TI%|k^_H4`Ys%1UKVLe=tR4;kE8yQBpaLmTTi=~%3mrWZv~Eg}CgATkS^ z3EvN0nc+gwG+-m_nJ~cINTiLQDAX6IC|L`VxfKFK>WLKXLS9z}qZbjHpmy!XhNxWO z3#~?Pc?c%Dq;Nsz0@h>XoCZ47zdI5Dl?gKHLB%ri6>6?XN6lE`=%Z z%)3FfCc!1v^o9}BjT%97M(ZvWhbp_tDj8i;mr@f4n+SSwje1&6b&BaX0^86ML!FG( zqS`Q-Msv2Uug{v|IegoEqT0lF4vRg}6BCgJ^l8~A@9&CHEK_0D?G&BB5^biH5T=Sy zlG<2qP}Rz2sLgEVgjyK%14u_?3KWN2VOB7dFL|U;h(srzt7&N4yt_Vcs4ssU)9x%v0H|0WX zm*@M;0>}b$*5&JofncY|LXH>`OoZczAuSnUf@-twnSmA9)y^z&wkb!L(m&>Ix`w^8 zo;TPBR<_6;2oXAX_zB7onNa~DAEuYakQROoAq-(slN0Jrfn?U)@(pwB#w#-k$PO!V zZc>Bh6_z+7DbQU@;5<$W7eNQ15qv{Yb*zC9Sb8VH5;Bbzd4xN=W*h-7%UGh94hc8G zRtqobWE1Jbq^*HD*;@qd!X&`yV%@LrG9WQXOG{A0Nd*Jfy#)Bga7Kow1T390Nl!2j z4lxg!*~E<9#MO{NT-;U)fIlM1Iy1%(EEl$V*U4q}J5im{Ut?d#aV$|{=Q>cDRM|?S&Bh|jRZ=ny z*L?0UkmL~z2*;7egv!K>*^^oXRSrxD4j(#_o;eNsknZi~oKJyv)qxQ{j|_Tqv?DX^ z#NDuCe?}HzHi!xR{p|l)Vq;R8Q#NwN8>17kFQEYN&T1A6-2~Gs0}=CM>=PgxKL&{E z-Zm+ngrK;IgF$02v~IP2_COErl+XeXX9?4A@gTfO0ZqGOZm$rsig!823D1BGSyfHsQ`509=VckqfJw5nF3ZgJ;ql9z6Vx9XzZk5RO z%78VydvQQR?%fylMb4%;7t_vc3ZnylV`k4#^iEFtPcLh{}`Fmc;~687K}|UQsANUUNsu z0dteG=JA9pJRWBJ_zcb(J^sK=x7@V<@RuKEcdq?6-!#8+^Op~9VLL-;uD%#}K}zV1 zWvleZzH2e9A;mAD){yAhaF#ZQVk@O?obOA;gz+4hg+8er&CaCEP;~W>^A{J~A%?Zf z3|%mYlv!(@P#mJn5VnalM>Os|9)XB>KyW8OR0aD5PvKfv0~>EnXl#F6gPOHv_?T zlgI|~>rk}6CG9(nQ|$A|{m%uHl$M-@#mR-hzjyj>I9 zE{6aavP!HnR*VP25gA>&#J8YBOi+m=Ni~FcVaN zR%Y4}_G4Y=WPI$bed%vc@ zYYmyRL(-6C;ueYe=m5g(deCIPUPX@BmzM!!@6@4=l#MX?Wjc>AnXJG>Ay?Rcod83t zkjwBmrAaqMCFu-=tB6avkRzuBukG36)3++A#QMN+hB+QCToJ|$jwL+>$bwKHSyb(g z?0Z{S2`9l_IKiZ`Vk~oN$hS8-)e+b6ZY&S;E_60ca}Ynx_~*O`qsTX3qus z6RTobcM~~ABCs}QgeDp$a!`6vfUe6V3Qy+ltUJi5TSf}@35Z|rX~()HJ3*dpnXz4y ziIGsj-6MgG+XI@744Tiz-Akw&?kF~Jmk|B)WxxB#?&}K>qQY;*Vx(XsB?&_qtm3mk zj|~^~A{tgEnH#8-7z!lM;+qQ`(uxgxiuF^BECDZQY9Zu=cOtx7I7Cu!cjNQei=~@U zBXze(2ZM|xwZ(}X>$Eyfo1Icd8o+Wtoh7sn94vi!pwgK0pV2&c4>an7bAbfGD`GOx z`?Z%bk&IJ>6apLtD*XIBTk;s`zKJ7*4aJd1P~>oDwE-F0J2-1|1d;hrO4aVX6MkGGO8vq6MX~ZIat@K1x5*?=n$Q0Pa2IiE+ zzT&9S1>yjBE@Jtb<(uJ0`uRF=e;Hy;ppSVvwaX1#|ER{XP0bha+ct1qI@l%jkzd_! zBg14+GLiCWia{tqSBo@yB@q*gFKCYunn^6Bco7>oNjhEEd1$eVXQhOKd+2yYqM zdvBV^@Q-PpAU~{H#(oe2S&S)n%W6S_H|c#ZNv>!K9$_GcCxrY?tWR<*rZ-f!cKhOD zAsBVT4oYVD(`Qcsd6|?UxtrFn8d8~_)UtJCv8v@$nd8><7%{9gdq<|M=C-3pzhdu= zY_eU=G#iQVsJV%ph|nhAha$l# zzs*ZgZvnNQrGc@ziOz)7(mqfInK#C?-ZTrU-4p^T<}l(pw({M1C4L&;%5!;f_kINC zbuZA^?kQo_isCk(_Li>@z#-A;T&h>{0lL`Sq@fJ$wYdqdJAV_y{^dc4n}6%y7xCZ} z$7huv9HJaPtej9>S*nku{Orl)=4C&2Mf2VVHO-fC&ENan9*#$s^ZLFYcm?>6fG z<_Zq~ZvFhGIg!=)zxMYiXWjSRaB=d!2XU{yZ<@OAJHX-J%Xr_m50pRedCZrxe)p;` zY?_7gj79zK4E64J-@$kP3)k$&=alCh=W`ssx4v)8`{DwHfAxK<)VuGyj761F3u;Je;zNBf6d7=F6E#>Pd{eFE;Kzr3?p8E-&>0Azg++TsV zbMF^Ab*jz&$2QHgo;~?xt^FMLc8trVE1KV=(T)~spc0SYAyfj zz5m5&_kGuY?E_l;5TEM%{*-$Cjc+)8X{x#LLDurm=luI4j_&&o@xD*+L)-TVj{3g8 zqTYSqH~jombM^)iZtH>wWt_G}Y|me*LT8dI*(n``*p__VSSLljha;-MH(0GraG{ z%fP`6yWaOv-uDRr&G&tA=Y6-7_tiGN@MBZWBj3UU<&WDj9!JV^_4=!RvM!m_sTD9!H;l7tLE}z#lH*#J4bX>0CaO}G8`=?hv zp!tOkU#Rcf&vR41-!xxU%BPj`Oetqe8F&sM{yxsHcvsWB((9c6XeocJT>ll%f3|6U zuaqAsveJ-W%33%ZA-(4Fc-&W4Q$8)~_ zgQa{;Dc@SkKd^jH)BK$!aPrTVeCG-V)%HA`((7Mr$@NE->jymlaML`=^EWrmZJzVo zNlTu)+w1)PS)TL$rE-0%l;2p&=a%x@DX(CVUQy0pSI&RFoc~HW|FGwL=VRsiUwNJH zJdnw~;`PvM%U3qdBPo4uuO;pIQm^yeH(CB}(|oF2zY+lP`sZ8nyDzi+{-(Lf@|{i7 zqqLs`&*|rjE&nU?>~-GzW1jQ-pDE`*U(VlY$@_l0T>pQ|^*<@+A1LP!J#x_UAV&8IM2mI?w-^=kIEoPnPq4D(4S?AlR=jD&?0^`uy|C`FED{|LQrvf3@XD zo8~Q+y#II0{ogP5KUU8Fs+>RYb9n9#o93aEzW3pt^PYp2^!rJcuV!A#`M8|_y5%o5 z%?Hc%kC*FT@VWWBM_KZ_z9sE=4&@Yr&#zhXo!|62-}#Gj{{NNpt9ZuwJY-3~hm?-n zH+astz0s2Q-RE`a#fL3<-^aYp`yTjU$`1l>lwSXQ&$)g_IX_v>pKi%>%jNn;x&HH> zO9#vK50&$OEal@6wtVk?O5gi@&w2iP%Jm;8*WXaC|B2`HY_~G>mttTqGFBDfA9PaPU(Qv=+h|6CIuZuBl7F-IHeg%o*zovIvW_WHj9ARF=0q zZQfzKw9lu(8kW~)UDl6=*Up9v{J)=H=$|&f;Q#IX(&q7l{S=-v)ArM=$!Ee$A*b!9 zIVmY=`zhqK{j|=03b{zUAFIRTGa7Q*etOe9LQb2L zPuow=*iT`7lem0g_&j5Mi|DwNl-6?F=#=ohE_aQ-l#Bl`4Pq&67yH#`O5m? z(M93)T^=0`Z%)U`CT>k=I5;)Ae!~IwjNZ;dN8q5)Fg=An%BNo|5vDyf^w`O3HruP;^^(es;m#F^>pyV(XF2{89skg*WL$s1@&D5CpW*m# z^f-Cm@&DEF4|l3=-0stql={&(9RIM>n#BB+&-^DQp3-NlUJs*YTX?=oyEFaCM z8SZl0_Olu8Qd$mAQE7&!v^2w^OEc_(G`BPCnzVe3@q=5OPyDbZsJZJ;u+=&uVHb!LQG{}?&4uy7~U(z`sX-@Z*vVdGe>wLjP(!j2~Oc$ zF5zbG<`L!$^o_<1K1Se~`ngl*ZE!#SQa`384# zAOGT6;k6;&k9>@uk7BOL25iYL9LUj}z?poVAMkVjz~A^cbL2_-7T}ev!g_4R4(!LY z&u3xY^D}PcZ#>C!>sov(2@ zKj)7;z|%Z0d~i(b&oZpZM!cK7IE>>sov(2@Kj)7;z|%Z0zy2)4nry^g9L8~cnIG|U zZsk#)X5R3II^N$)Sc>&{C%bbP$MOX(h;$fa(w(x_BxL+=0NtS0V zHe?5m9L7iaG+*Z1T+NN#&Lcd@ zbHXnN<9@lAC3y{RPgJ>J1i9L~{vmM?P=SMUq| zz+ZWsXBSQ8aRH05JZrHb?_yUD;z&;9OfKXye#$M}!=ubx%=y8>Ol5V}XLELDzT(OD zm$DSwu@8rF3Kw$~w{kZR^9;``k@P9WrfkdJ9LHz)65r&9+`=6^$WzRHMba-nORy5J zXJg*Y9=wl_aRC=|6*q7x;5N}31D zvlbh&ABXcv&gNTO$uIdMkMi77Nx$;EmN&9ByRaW8aw_NY9j@WG+|GkM&74;y{V(NJ ztj79m&dwaj8Jxq#{DfcfNB+hWys&iA|8mCbVB+)Sb!^JJ*p-7gk`pa5Q@*@F*o1SfDNU*+3e&d<1wXO~Ilk&6X+6|1rV+p!O4@m0RdPxv)= z^DyJZA#s1_W?`0L4L0Ci?8YH{jL&j57jrc?aVHP)40DxB=2M8Nyp|2vigWlnKj4?# z!Nbg4J{dnBi?cFsWOH`qNRH#T+`)r9#q%p9eXik6Y|OjagAZ~PCvg_v=W1@`DQ2yh z^gEwLSe7+-3tO-=2k;S&=M28bwcN+7mGtEeY`}hen2&Q7=W{7P=6Br5-)Duhvj@j=CKvF1uI5H==K&V1oXn#*!@m`i_Bg7|TiKf3IfSD)iL>|#zvPen zjVG9`O49E_R%add;%6W+s~yq}}_EMMlu z)syjyvK(u&0b6naAK|Nfn``(LckwV&u1)&oW?`0L4c^6W9Ky%=EN62uS9240@(|B3 zSB+#Ig_z1~c?(;z8}H-eoWglr$M3k0CzzvV()VJPVhuKAYxd+&j^#8i;4*&2-TaLw zn5|aQ|3Y5Q3cQYu*oxgan2+*lzR1^E;<}_yIo4t$_TvM5f>St`OZYLr=05(x%(at# zd0B+zSc{F=nmu?wALnGg!;iR`yLp6}u21^sVG)*R6Siev4(E8zFNgCPzQEV`KG*SE{>(p^>4sz;xmlQHSc46C7klzSj^`{c=EwY+Kk*Od zt(){O!g8#|Mr_RpQ&-gv}@i?>9 zPv&tci?b5z@HV#N^L&}}`3B$NT5jP^{?5}p_vU0C7xPNq!|t5H`Fw|~xQSc2kALy3 zTarHcSd`^hmrdB7y*ZL&IhAwyF~8)G{Ea7=y+JaM0xZd@tj`wg${`%h$(+ljT+1!o z%j3-6P=A(WRn}(e$*Qc+7VOF)9L>p`%hmjh-|-)w zeQVP10v2O=)?!26#jYI0$2oy7@GqWWuEt5fLQLhgyoD{kf(S~ zlcfLUEX``Xi9x*WAs+Ji`KaCjE-AEE}^q`|}yjw7{xPb3*Ex+MUJi?T=$$WCL5KFNFuVW*& zWmgX3NKWKTF61(P%AMTLQ_R{fnb-L&!m_NvR_wrje3;`opNqJHU+@S1%Huq{eKL;= zSd8Uaiw$`fdvPE~Z~|Z8YkZ&Un6E?9_fnSPHLS0vB>Q*K;d>}ueghcnbIX0KQ{}r3~R6f z?_&5L$)@e6A$*LBcuv=3eLfar1=eO`-osuT$}ybEd0fg*_zi#NQU2O3na3Z@)IG_a z*qg&Rmd|rO-{o3<%RM~CtUcUs7Gnk0W@FyNUL3)v_%h$%GJei)_!HwFG{oQg6=Y@B zVk5R@58ltmIhn8U9e%{k+|47*)GO(qhnKM|YqB9*u{%d{9H;SBzQ=Xk!e96&&+47b z;{smJioBjp*oM71jAQvc=kr~z<+t3!W6ave`M_eVz$R?Tt{lu!e1tViJ6Nb+ z()S8hW?kOS_Pm$Fxq(}_hew&EzvIbEc@?i?1GZ)-hX3_x+T(KsCvquQas#*XAWt*r zfMlFYc@?YicD7~@-p|K5nXm92e#Fh(%_Gb-FzKI%m$58svLRcsJMZIYF60t^%&++q z|6t}pN&f=8ir@1P&#=(oq`nNRvD=VjdH6qer5%@jLlYYeOKi`+e2`-~m22|wi)?%`2pek|!6@Qd@HP(TD30YsPUZ_-$R+%U zJNY}$c`E5!fTdZ9*RwJ2W)I%S$M_6i;+y=CpK~ks@h_e=KABHG7G*isWCM0%KMv;v z&f;5K$uIdMf8z;en~==oLSD`aypE07irqMbkMUW~=3=hqChp`Ro?)(u$$SbimDlnX zwq#ch<|sbHm-!Y~aU*x|cmBiko=)abkfm9jH?sx1a4;X^b9{wMxbK-{{1eRlY?AY` z2+Oe+8?iNea5SIeE8Nct&n4qm;~nh4d-)K@aSj)98Bg=9$;r6+Sd`^>E1RoO_f8ehyJT>WmC2!zuY{OoB zfKPA==W+=@=DO#T@i%fi5AY;&OtT+YnRR(P+w)#N%5i+2^SFwiatrsc)bylp1zyKS zY{hOI%%}MxU*~du#_zaiM$+d`{==*SA_m?GjHE&>3wqsvD z#3#9c@AFfB$Gtqx?6Z^p1z3_*S)VP~l|wk1lR1}5xt3eFm&ciXj{Ypks;tiz?8+e= z&B>h0rCiG`+{@$4{)+xA$*Qc+7VOF)9L>p`%cWe)E!@lF%sy9tmSk1dXA5@a5RT?# z&gD|B3<^lCV%3uJj6eFiq+mq`qtrXY|B1; zo(s5?+qr6SGR~*m!}$OBjK6ow!@^8ub=K#d?8ttc%DH@pYq*1T-%0wt$R+%UU-5UI z=DACf?Jnk(tjrsD8{4oKAK>GBjGrFgsJ?UXMK>Y&&Q%H$2x4tR_xCEIGWFK4&UY)e#Kop%#;t4dE{nc zmSGJx;9cy-A$*L_ayA!pH8*i55Ah6htw`omh^ef>hHTBA9Llkr#syr)_56YRd5Sq# zCjARCl{MIqt=W@9IhND7fXld^KX5-!G3P4%naUb$$ky!1p&ZL;T)<^q&mXv-rJHe_q|~G%nyWuICTj&r{5~Mt`QV1{<<9dvYkpavB$K8Q1d%?&m4y{78SM zvIZNnHG6U>$8s7Ma2eP02kz%7=KNTHrm_YbvNd~hD93Ud7jPNZ^9SzdDdzk{f2Ohq z8?rTfawx}g8W(UG*YgMN=PBk~t3Oj&gAF-hQ&KmDZ*w&_ayt+3By)U~Y+sxexrkS8 zPS&4cwy%?1oAud|qxdAJaXy!_^Eb&jeK?F`IEAn9ZLa1(oM-P&w!eVISc?tWgZ=q1pW<}B%6It*zvgZp<{6&%Q!9)(z%)p;{punPzAQBLAZ zT*Q^!!0kN9)6Ds6GLK7n6|1p6o3k?qawMPTEWXJV{F2*vfTwuwZ^=9^V@XzFT{dM~ z_U6N!!ns_+kNGu!=1FGRpY+em%UFgtvpGAlKOg2(oX%JIE-ZfH z@-%ZEPWoTUYP^~Euos7N45xA)m+}*S!=HJSS&k%q&u3AV=XJc5ce5uS;1is}xm?0e z_$`0oU(EJLGLQVclGpGiHfI+O=4ejid@kk3{F;0DC$k<+`WInY)?^dj!=AjKqxl@? zb16UOX71u)rW{N9XXiyM&WfzfTiKf3IfSD)iL>|yKj3^F%WKRjkfi*o^)72q$tD7jYFgaTl}vo%G4g%UPK>u_b%( zK`!7*e#M{p7jvAnzgU*7c`rxs8NR}Ixt@PB_o-yuqO8PvY|d_cfa5rmUvM{%G27{6 z{EJzdHQAW$IDoUbgzLDK2Y7~g|4I5>&dRLMK^(*Be1qHg2hTc_jF+ERu?4%bFCXMs zPUSpq;T|4k=I{^sWV$f^yGn_Lnab+CnJw6bgZL;X@g*+eN^anG9%SxJN&m}Pk=L^g zdvh4a@_EkZd;FB&^H=7`ob$!s`c~RD+ZzbNx(VWKFT+G$n#GO3#cI5nE!mCt@o`S!Jig0y{Eqv$BWKe07_*+2 zGK-{MMs$shR}PcZ-a$$YNhjl6^Ruos7N45xA)m+}*S%U^hi zXP7Hr(!UT>c`a|@UF^>Oe1sGDBH!eDT*oc^g@5v_3zB&>WGi;(eH_g>e4A_d6?gG4 z<3Dg7pRaSXFw3w88}Kf6=lvYPiF}c7@I!vVA9;YMd3N{*2;+Pzu@0NEJ$vweKF)Xe z5jS%;k1$jIq)#4R#&W!l_1T=AIglgyG-vTmuHcv4#sfUXa|8Mf%wnv-+HA~w*o#9shEq9@OZf@E;mNGTe2$$ za}=N9%Y2KgxRE>fJI^rprOA8>@Jd!;JvL(p_T$4G&lk9m%lSEf9`@o;j^R|!0e1K1I3g>bu*K#9w@OS>hT*Z=pg?S~b zupXPSBL{F8$MSi;&(FA-yLo~YFHid4!aLcXqd1W-@ii{vXZ)V~cv10W{1UvHH?S|K za{=Gyr~Hn4d3K3p+zVNpl~{+ju`T;>44>z#e4n3jD}Uojo_j^o|5BD_4L0N*?8pHe z$#I;{&v=k$UzzkN%&T}U>#-R-upb}hc)q~zxR-zN?2<{p%UO|i*q;6P2q$tD7jYFg zaTkv;bE%}?`K-t~?8iqqk+ZmntGJ1~c!Zg+(uc)Zk#*RV?b(lya3W`M5m#{&cku`_ zm)4)fSdn$ulPXFwag+`d!H4ti(FJjcwV74{{u*a~^+WwlYbdR9?d; z`8l(fP3rQp2+Oe+Z)FGe<0wAG5BLdp@ONe@m-IW21zDQac{5wE3m0(%xAP!RGiUjv z&!xPI)mWd+*_i`5l23CM7jYFgaTkv;bA_b;`7FkYtiz^k&whM_6FG~ExQd&&i$|Eb zqW&z#imbz?Y|nmtgcCW7i@1uLxQj=axsv`Y#)_=NrfkoCe1sD@i;K95o4AWdnE7h` zS&S7~hfUd@{rCtcau(O}Tkhd8X04p`&BtP_b4{|mDO<4*hww2z%h@blHQBxj@8I3+ z!Tb0aw^d8F+ry*GQ$1N;n5nGJ`n;1J*^k5dB&Tscm-1t7=ICpazT-KA3-}(_@*Dod zBfO+WGEOm;XDv45UF^z1oWfarlPmZoxA6c^@!Xn8{}1>Hzv0h3$}F{#`twWRB~Se)(B~m3V@gYA1EMS&Ub)DsN;nwr5{H$g!NtxqOFfxQRR1 z>H1_I12~kEIftvbfu-ss+g;6iY|Wv3ny+#R*K#}e@(<>?!G2_M)?h2%&xw4Q%lHMi z@`Ad_xJ8-DYj`U=vmc-5a{k2Z^^)-}Vi!KbSzOLfxP`lTiWP25#=D;V_)s)wO3LH% zY`(=0`2&wI%T396WmzSfDJ7*kZ@0WV=kQ%_;1AKT-46Z~&6|?4&-$Zsrut#|1>xUm zXVGY=yNcy3uM-X9-N=s7@N>Pv9L@38PvT6z%;nLr-8%VmZj6S$JGmzs>JH0)M??RA znE&Qv{bkXx{Bl-_hHSoGsaCtQBw=eipG|Xc! zv)q#8Y%CTH^;LNb+p>Q&^m!;6#u>rKqG3K`t$$8_g-f_58n#=@?cB{w4U+LMU{R*> z8rI?MY!eORc3_uim`_jZ2g^g{$KT+Y%k>6>dpOUt)#C-+-_h?#Cp=64qJ@wXpEVp4t%lpU=acnf~m+^d&v$>orxiK2%v0dKHV?4o}jgxs6h=%bC zvPd*+U&8wGa%H);Tu*Kyx08FyL;0}flcS-}G|uB|{4g5M&u`@Kd6>uePc+OgTa&~B z(Xd_FXc)gDYgymW`n%bk{jDDn4ck4&DV)xE(a>*kG#u9zmapMj>p!=Ci~OU!S3V%0 zVAk7`aW7zTmWqZx<)dLp5!*<=}-h7mgb7C~i=T-T2uH;AjG#d8D*U?bF%kn+^izj*h?V&F0 zw~JUT8n#P~hI!TGExg_Oj?u7PS3bx`IEj<_ZZyp6EAHe0p5R%{lDaM&$cH(Oi@1X8 zxrK+=<&I>$fqa0MZ^B8E?+0#A~%nQKCO5!2Xag_9KT7?(0@8#wf=Q3;|gwyhVAyr2bi@*(l0yn zM#H$5FxB$%ypgxCEjw}$@8<+Q!&jnV9`DM_xtUwIGaBacD^Etlc6nPSUJ?!Kt3<>8 zs?OVZ2k(i7x*(m5)Jhynf0zD=Zl8<<>%#=r^@Ad z6C1F3G>q3N8t(TXj^J49Cr88h)A*M4>$oWz#`&3l@KiKxcUG&!9K48^Ff|(b-yq+_ zd)S^mqM^?Kjmt<#(!R(8x8wwbu^6g3Ab?< zf9D@Ot4%V_dC|<_anGVG!5Xa1meJ6^T{QIT#CtiAPew!Cv+`8V;e4)+hPuz>FS(W5 zc|02GvbIh7W@pZ5*k5_0VSPclsGKTSkZZ`-%T3rJ8tzXQ4!3-)Jf4%Hq2J4#7Y%(E z%gdu-oR$3E`aSZmJQxk*{KG8ml5uiH!}5G`Vfo5v7`HU*Mnm5wax->`hVA>x12`@k z>Zi!l`C>HG&$0eZ`5k$s{6#eM-^8D|mxrTaoWGf+eUi_QhV3q5Nv5(Uujj37%2v@Z zZntQd|3J&{<1p(Vv3{I9H5wilZ}L6MS97i9Tccrq+xbs4^f{+PvOE{hkA`{VkB0Td zS6 zwP=p;{y_dpJ|Lfv^YuvTFN>a=l5(|NTdpVH77ag7zf*2650*#BqvdC!*~5O3mqgDA zuaoi@(QM&!uDl}}>W|5pdnWZcqv8Hs91Zn_<j-#>d(kIdnNTnqhY>fqoKa4TrV2xZ;_iv!}vYr z`=X(KggibP>YtHkMMM1(c}+Cbe<5#;hWZ`yfoQ1D+&dWNlRFyfFP5)}hWgTS)o7@1 zB;OSc^&RDVqoIC~JR%zEC(E;=q5gGwSv1tIl)s3E`rY!OXsG{N&ekWX&l!!!I~wZC z%GX9ieLcBpG>qR|?idaA_sOH8p?a?)ZZm{iH7=nc5b;MnnA} z`E)eYXS+8T=669f)L$%L5e@a%%Jrk6zNy?M8tOaB_eMkgDEaAVsGly+kB0i!-O zzfs;64fT8FW6@Cmx16nCQeQ9{=36Qn>MO~$qoKZ@+%y`-?;;O~hWZEPG0{*zUY;He z^^4>WqoIDC{7p2}ZAu1<^3SqR~))gg&sQM8o)PPyL0qM^RF+$b8xZz{Km zhWY{W!_iPbMxGoE_0#3~(NO=PygnN0zma!GL;W9e%D|Aryw2k#ypok!hmF~q-8hIN zIG)ovpG&xzJ9&^NnSD?)uS{mHy8VM$hDT{h*#;jt6n#|=6^7=9k}R5X14 zDUcG(6JB4UVSPzCRjw=7mz&8gtiM1mAQzWQ%2&%(<+gH1d8j;G zo-9w3=gJG@weouTCwZ@&5`Lx^?_btvm|sD;h+J2$9}UNEl04b^HS${dl$;WtE8}?a z77e>2&F~gG&CoK;$ZPsT)He(C6W!m#Vn8N^h2p{4IPUN$k&KH^X{1L`UfBtyO@+JI$tGJGz zb2GQ_7yia0{FA2{AG`59%fky;kVROMsl1w1S(|m)kWJWSDVAXsR_6`8iA~syce5S4 zvo{Cx0gmKoPT(_~!C8EjuX8Dv@guI|CVs>1+|B(w#1lNtTwZ6+=fy0y8yq0x% zBky2KroBFf;2uV5KgU{%&&12$%Jwqgf%VITJA1AK^&aSWg4b9{j>@hvXl z2VBLC{F*;-2Y=yjJiGpUv5d?b(?Fc^@CDFz&Z(JeTM5A{Js%mSP#!U~S&S25ibZc{kg!D|@m(2Xhpk;1o{h0=~fy zxtgEy3x3V-xR?8Rl4p4KdC7h{hZnODORy9xurh1%dfv=Nyn`*-o}Jl;{W+Aw`8db% zSx)6ke1>F_&{CKjjzvmRtD~_wq20@gHW+mF%~3nVSVzkR@1(68CGC**5XZUz-Da0cI?F7?8gWA5Jz(?pWzhF;vBxtx44WexQ?Im z8-CB-{Dp^jl&2Z54M^K>%*Fh?l*L(+6a4|jyqQhdj2+m8z1ffVaTrH(G@s(roW(hOo9}Wh*YhiW%Wd4neLTQZjK8>!kI(GP z$$ZSu%Xm4jVp&#Ub>6~Tc?VmvEjzM52Xhpk-~>LyX`IPd_$uGy2mFZZxPhCwo4@c+ z{>@AmC;RCv=42jT#>-ieRalF4cnfdkoxF?f*_plBkN5LIj^Y!X$Y(i&vpAm%`3~RX zDt^o_xQX9$8~5;69^s$-hnX+&xMVICW-*px8P;HJ-oyrM#Ww8B?!1=+Ih4cs6rbi) z&fsj$<5Di;8m{FAZsrf%!M)tiqdd-(OOySSl^3u8FXQE`$SSPK>)C|O*otk~oBen{ zALJ-L!Ks|V*__9vT*lS>gx~Oc?&2OEb45#x&&f{xb&Xrut_56z8avOK?Fpn{7p=AGLXKv2kzh@9_2}%VXn)P{c%1oW+A4sJg?!k zyoI;&Znk4z4&Vqr#wR(EFGj<)2ebJa-{iYo&X2f`8~HVVl(VIJdYX1YAt4>@=qFXY86$`UNY3arMOtjC+#l6SKsyK*oe;3FKx zah$-(oW_^<3g6*-T*;5Po*Vcrw{jQv@EA`prFgR6vhrN!W?>d%1y*KV)@Qg3B_&h% zT}Qg%$IofcC*k8v+V#8PVV(AT97tQ9mErP%v>bjdmuC8Q7sy2z+N7;7$yAo-)vV3B ztj~sQ!Paccj_k_;9KxX-&9NNMNu0@-IhPB#l*_n+Yq)`%xrIM)FZc5hk1{2b{mbmk z$pS3MA}r35Ol4KpU~SfA6E`dT*eh#!wuZb zE&PFdxu1u4l=sh0oyy4tFi|NHvdx|aX@I@>0eH{-vr zv+ZhmPY&Tw4(CXY=2%YVG|uG9e1nU*l*_n+Yq*x{xq+Lxg+Fiyf8rq?<#C>3_AJS9 z$;p3Tr(4AG;w;HjR%H#=W?iOVpW94s!Paccj_k^w?8^Zh!l4|_ksQsj9M4Id%xRp- zmpPXU_y!kqDVK3A*K-3ma|eIoUhd~19%cN4h4{WQE3-2v3-I69{}#8rBvV9od%yID|u)em(G5c|0d^CST@UF5nwn%oSY2wOr2)+{_*PiF>)9$9ak= zu7}OaJWTt0nQ$D^|6Zn`<>`Mf^Y812)Bb)Y)TjUbObzw**^o`xj4jxjUD=a;Ie_VZ ze=|}Z&9O|so;dyQa%NioGT-20F6A<=<$7-5X71om+{^tu&QnbLJD+$yyY4m*FJJ+t z{ryj<`#;^Xr2Nlhh!=z$TBfbv7%UQUiL`uv%J;!|%O1Wmh2tOJ7sgxCKW|E|P#bT__PJ6@h8%0t z>#q+v)`rV&!uEMn?g}~9rq_o*D^6RVUjKB+aUX_XgQeBK6>?mcUjJ3d1wu}*|0Cqe z8S3+e*X?+grq@>rxk!fk+d^&-ay--GeENhO=a*hTF65FK>KBIGCggbL#riKpj@zc! z$M+BAGt}n}J9<#a@yw0&WkZhhO|Neha@7p=gF+q?a=g#6{)LbWW~h&^pS43yzrVkS zJU`@kX2<%A!oWqs_vz!;4BylbIlaD9$e)B9eyo;OKQ83r8S38-xk-llts(y$a-2gP zKT|mO;{FJWL(Y|QWymeU_vz!;4LQCZ$47FkZx?cEhWZCXZkwTgO33kiOU~E4De-wW z?!WZ$zYMu+hWbMxmk9Og`#=62Mtn@A*H;X=Z-)9NA;-@a>BqNs$Z>zC*N+W(NQU~^ zAvX#2>F4JMar+GQ--bLqLw)?ah_<1=NLUu{Z|RV0hwszJza!+)A*b)3VIdC>_38V6 zcF1)z)PElG_zd;?LY@)oljn!LDQAU&>Sw4g8uH`}_1A{{MySsdmc{wp5pu%}^?gE~ znW27c$SXp9`tgd__czH<|8dB3Gt}=6IX>pn>*GsAvkdj|I{Y^>)ZY|xc;ZSa5{UD; zH{^J}r0<{SLtYwk7&ffWnX)S6BB4J0eBKvw>kRdI&I$9)P+u+NnxQ`Z@zOrzwi)Wj zguFIG{hJ}T4)y8h^S2>)%us(i<8|OeLVfz<_u7!VW~jd_O z)(me^Vtu}lH)i=DZE0LzE_`=5tcdI4_KiZG@crv)Z#2^87xKt(f8ygeu8-IMrr+W= zFa0aW>weR3as9@SADQ{kk+>|5_nY;x!TBj!QvUu|{l#HNY|6W0etLcRxMRXCz5Y5m zE{o&e@vqz}RG6mFx!*ZJZ7X0edtwV3ho9mk8;&!*qvx7YtG-xYGb zu)m9kb+LZXzt%q+@{Tos_KIV~{kbsYo5J_uVVqX~QOM_pe(CvV+o#VbUe9{Y$V)n< zZ+}jFA##hQ@%q*DTg;dLE0+s-RCqA%59{Lm>V>@Lw@ZLQJcFDdaQ#s{NUsmxtV-M&bDMmbQLN$nC<>jIV*Q-~Ny%Tyw#y^z~ovpt($A+)!}=>;Dq1cX@9>#JAs-K+VEBsr`_#X-&ljJ# z-D3ZE{pD@J^!-)pU+ZiBD>n#vQm7A4Z)xMl>n)3f@8ehO7q7Sc?ehvxg_w5#<8_wl zx7hEIkT;)O`S!Rh9*-IST0ie!`Q4C9&$+sPdi~arCv30(dwTx;U-hTt^z$uyc;Rf( z`TnWt^@T!S8}@DZ-)*HGk8<&a)h*8Nnvg5j%Kmp;6zA76Sc3p;k|*(Pidm$qrsd0_7jZQ7KrRHgFOl~cl+P6Og7 z13LBV+^$2Xj9c~ZI&eV8K7)H_T-LkO;4o6gQOZ}Tn9{9t?{>X9m91E(u$NF~b z+o?^b4sH7O>De>%=+S>bzyGqPL%$CHWzBz%)~$cP|NUTA{O4HdTl~kwIt}X7dqA5G z1N!}!>HW|3|2gpgT>qa_O*?ws`iFz@zn}5{T>qcr|IhXRIes`d{tu&PT>GD6XIyLK z|J5!Yy>Q^VrJY0n>&X500^|Sp0xiP#1229N65C)LX6tvQSZhXOzrhUFMU~Zv@ge$AFIxUluOv`y$AZ0WTMyCo zrL3e;$_VCgxu}m}H;>`TZ$(uSf>%ihnlrnCy8wmFI9CBmA;FYF0{ig_RtgEM6c*T! zMbA2D-tpqiM_GFNp?3$?agq4qN5M%}a{riyLDF^N>MZ5lmf zT6uV@vqH7nMg>-#;r$7d;=T<_#m8uhi-ip?7U7sh57r$sR1jx-M6cumzLH0L-j0Br zIIk1@t~}y*BEx-Y-#O-Sp&pC#h$hY{PRJpN+iRCoijhxYdw}gl zo5h*8_kZv)9>CkKx6$sfXuQEH6Ap)CzpdNb`}>K;Bxa(oKYuA%!6@B7aQ=sSkwZeI z7x$ESs;YKZRUG4Vk&Ua~anwYRmoDqoKGk(w@9J=VKfo{Aq~NDMcs3i{`a2fNJCmBB)l@K!@XgiEPoX&_L$#9vtwPup*Hau*#5M8BZM3v%--|k zeDV1%i#d`BM90cW-iqUGscL{I>WQhRhh=on zky09=TQ#F;)s!ZTcBv$%gdTEr@G0GAQi@b9-qPUU6ai*f?-itF%Jm4gGC=wP|A2%w z>s!jchK7RGkOYuqeYcQPh>t;)JM6VAmbYvW+{;1FgFTn#TM)4WizLv5%TXj2Ba5Yy;~P6P%nI_S?z%WL-}@9uGrnwpHKR z7A=LGE@B7Y;n*KfpT2t~PeI#1M(KCFh15|Kso@2M=lkNwT1ARII7X|;*H>Z$&mWj8 zal(ITw~!*wI$)KruJcpHKkxAlnSIHj61#W>-p6||?Z*Gc`G+_%yHr3<8C(y($~B9M?le`s>OT*G!?H3 literal 242651 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[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 z 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�}r*Sq>_`nbWh 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 l^w*Z(l;_F|ulSerialObjHndl = (UINT32)pSemInf; + f_pCreate->ulSerialObjHndl = (tOCT6100_USER_SERIAL_OBJECT)pSemInf; } } else @@ -409,7 +409,7 @@ UINT32 Oct6100UserCreateSerializeObject( wan_spin_lock_init(pLockInf, "wan_ecapi_lock"); /* Keep pointer to semaphore information. */ - f_pCreate->ulSerialObjHndl = (PVOID)pLockInf; + f_pCreate->ulSerialObjHndl = (tOCT6100_USER_SERIAL_OBJECT)pLockInf; return cOCT6100_ERR_OK; #endif diff --git a/patches/kdrivers/wanec/wanec.mod.c b/patches/kdrivers/wanec/wanec.mod.c index 4d8e8fd..f2900f0 100644 --- a/patches/kdrivers/wanec/wanec.mod.c +++ b/patches/kdrivers/wanec/wanec.mod.c @@ -31,11 +31,13 @@ __attribute__((section("__versions"))) = { { 0x2fd1d81c, "vfree" }, { 0x1d26aa98, "sprintf" }, { 0x7d11c268, "jiffies" }, + { 0x1f1e3c4b, "register_wanec_iface" }, { 0x1b7d4074, "printk" }, { 0x5152e605, "memcmp" }, { 0x2da418b5, "copy_to_user" }, { 0x2e1de6c1, "class_create" }, { 0x19070091, "kmem_cache_alloc" }, + { 0x4df932b, "unregister_wanec_iface" }, { 0x4086729e, "register_chrdev" }, { 0xd0b91f9b, "init_timer" }, { 0xf6ebc03b, "net_ratelimit" }, @@ -50,7 +52,7 @@ __attribute__((section("__versions"))) = { static const char __module_depends[] __attribute_used__ __attribute__((section(".modinfo"))) = -"depends="; +"depends=wanrouter"; -MODULE_INFO(srcversion, "86B10641B83578F21469DCA"); +MODULE_INFO(srcversion, "DDE02E055B9871AC6D3BAB6"); diff --git a/patches/kdrivers/wanec/wanec_cmd.c b/patches/kdrivers/wanec/wanec_cmd.c index 5641f9e..c68ae2b 100644 --- a/patches/kdrivers/wanec/wanec_cmd.c +++ b/patches/kdrivers/wanec/wanec_cmd.c @@ -107,6 +107,7 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *conf 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_ChipImage(wan_ec_dev_t *ec_dev, wanec_chip_image_t *chip_image, int verbose); int wanec_ChannelOpen(wan_ec_dev_t*, int); int wanec_ChannelClose(wan_ec_dev_t*, int); @@ -219,10 +220,6 @@ static int wanec_ec2fe_channel(wan_ec_t *ec, int ec_chan, wan_ec_dev_t **ec_dev) ** ** *******************************************************************/ -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; @@ -254,7 +251,27 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int re sizeof(tOCT6100_CHIP_STATS)); } - if (chip_stats){ + return 0; +} + +/****************************************************************** +** +** +*******************************************************************/ +tOCT6100_CHIP_IMAGE_INFO f_ChipImageInfo; +#if 0 +tOCT6100_GET_HW_REVISION f_Revision; +#endif +int wanec_ChipImage(wan_ec_dev_t *ec_dev, wanec_chip_image_t *chip_image, int verbose) +{ + wan_ec_t *ec; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (chip_image){ PRINT2(verbose, "%s: Reading chip image info...\n", ec->name); } @@ -269,12 +286,12 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int re ec->name, ulResult); return -EINVAL; } - if (chip_stats){ - if (chip_stats->f_ChipImageInfo){ + if (chip_image){ + if (chip_image->f_ChipImageInfo){ int err; err = WAN_COPY_TO_USER( &f_ChipImageInfo, - chip_stats->f_ChipImageInfo, + chip_image->f_ChipImageInfo, sizeof(tOCT6100_CHIP_IMAGE_INFO)); if (err){ DEBUG_EVENT( @@ -527,7 +544,7 @@ int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) return -EINVAL; } - if (wanec_ChipStats(ec_dev, NULL, TRUE, verbose)){ + if (wanec_ChipImage(ec_dev, NULL, verbose)){ DEBUG_EVENT( "ERROR: %s: Failed to read EC chip statistics!\n", ec->name); diff --git a/patches/kdrivers/wanec/wanec_iface.c b/patches/kdrivers/wanec/wanec_iface.c index 79f6f20..edcadd0 100644 --- a/patches/kdrivers/wanec/wanec_iface.c +++ b/patches/kdrivers/wanec/wanec_iface.c @@ -102,6 +102,7 @@ extern int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_ extern int wanec_ChipOpen(wan_ec_dev_t*, int verbose); extern int wanec_ChipClose(wan_ec_dev_t*, int verbose); extern int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); +extern int wanec_ChipImage(wan_ec_dev_t *ec_dev, wanec_chip_image_t *chip_image, int verbose); extern int wanec_ChannelOpen(wan_ec_dev_t*, int); extern int wanec_ChannelClose(wan_ec_dev_t*, int); @@ -141,6 +142,7 @@ 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_stats_image(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); @@ -167,6 +169,152 @@ int wanec_ready_unload(void*); #endif /*****************************************************************************/ +# if defined(WAN_DEBUG_MEM) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +# define EXPORT_SYMBOL(symbol) +#endif +static int wan_debug_mem; + +static wan_spinlock_t 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; + +static int wanec_memdbg_init(void); +static int wanec_memdbg_free(void); + +static int wanec_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, const char *func_name, const int line, int len) +{ + sdla_memdbg_el_t *sdla_mem_el = NULL; + wan_smp_flag_t flags; + +#if defined(__LINUX__) + sdla_mem_el = kmalloc(sizeof(sdla_memdbg_el_t),GFP_ATOMIC); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + sdla_mem_el = malloc(sizeof(sdla_memdbg_el_t), M_DEVBUF, M_NOWAIT); +#endif + 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, const char *func_name, const 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); +#if defined(__LINUX__) + kfree(sdla_mem_el); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(sdla_mem_el, M_DEVBUF); +#endif + 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); + +static int wanec_memdbg_free(void) +{ + sdla_memdbg_el_t *sdla_mem_el; + int total=0; + + DEBUG_EVENT("wanec: 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); +#if defined(__LINUX__) + kfree(tmp); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(tmp, M_DEVBUF); +#endif + } + + DEBUG_EVENT("=====================END==================================\n"); + DEBUG_EVENT("wanec: Memory Still Allocated=%i Leaks Found=%i Missing=%i\n", + wan_debug_mem,total,wan_debug_mem-total); + + return 0; +} + +# endif static u32 convert_addr(u32 addr) { @@ -1207,6 +1355,29 @@ static int wanec_api_stats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) return 0; } +static int wanec_api_stats_image(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +{ + wan_ec_t *ec = NULL; + + 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 Image stats ...\n", + ec_dev->devname); + wanec_ChipImage(ec_dev, &ec_api->u_chip_image, ec_api->verbose); + return 0; +} + static int wanec_api_monitor(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; @@ -1483,6 +1654,9 @@ int wanec_ioctl(void *data, void *pcard) case WAN_EC_API_CMD_STATS_FULL: err = wanec_api_stats(ec_dev, ec_api); break; + case WAN_EC_API_CMD_STATS_IMAGE: + err = wanec_api_stats_image(ec_dev, ec_api); + break; case WAN_EC_API_CMD_BUFFER_LOAD: case WAN_EC_API_CMD_BUFFER_UNLOAD: err = wanec_api_buffer(ec_dev, ec_api); @@ -1990,6 +2164,9 @@ int wanec_init(void *arg) } #endif +#if defined(WAN_DEBUG_MEM) + wanec_memdbg_init(); +#endif if (WANPIPE_VERSION_BETA){ DEBUG_EVENT("%s Beta %s.%s %s\n", wpec_fullname, @@ -2033,6 +2210,10 @@ int wanec_exit (void *arg) # endif unregister_wanec_iface(); #endif + +#if defined(WAN_DEBUG_MEM) + wanec_memdbg_free(); +#endif DEBUG_EVENT("WANEC Layer: Unloaded\n"); return 0; } diff --git a/patches/kdrivers/wanec/wanec_iface.h b/patches/kdrivers/wanec/wanec_iface.h index fedb105..0f91198 100644 --- a/patches/kdrivers/wanec/wanec_iface.h +++ b/patches/kdrivers/wanec/wanec_iface.h @@ -98,9 +98,13 @@ 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_chip_image_ +{ + tOCT6100_CHIP_IMAGE_INFO *f_ChipImageInfo; +} wanec_chip_image_t; + typedef struct wanec_chan_opmode_ { UINT32 opmode; diff --git a/patches/kdrivers/wanec/wanec_iface_api.h b/patches/kdrivers/wanec/wanec_iface_api.h index c7d3b06..f724ac9 100644 --- a/patches/kdrivers/wanec/wanec_iface_api.h +++ b/patches/kdrivers/wanec/wanec_iface_api.h @@ -22,12 +22,12 @@ # include #elif defined(__WINDOWS__) -#if defined(__KERNEL__) -# define _DEBUG -# include -#else -# include -#endif +# if defined(__KERNEL__) +# define _DEBUG +# include +# else +# include +# endif # include # include @@ -86,15 +86,16 @@ # 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 +# define WAN_EC_API_CMD_STATS_IMAGE 15 +# define WAN_EC_API_CMD_BUFFER_LOAD 16 +# define WAN_EC_API_CMD_BUFFER_UNLOAD 17 +# define WAN_EC_API_CMD_PLAYOUT_START 18 +# define WAN_EC_API_CMD_PLAYOUT_STOP 19 +# define WAN_EC_API_CMD_MONITOR 20 +# define WAN_EC_API_CMD_RELEASE_ALL 21 +# define WAN_EC_API_CMD_CONFIG_POLL 22 +# define WAN_EC_API_CMD_CHANNEL_MUTE 23 +# define WAN_EC_API_CMD_CHANNEL_UNMUTE 24 #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) @@ -106,20 +107,21 @@ # 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_) +# define WAN_EC_API_CMD_MODIFY_CHANNEL _IOWR('E', 10, struct wan_ec_api_) +# define WAN_EC_API_CMD_DTMF_ENABLE _IOWR('E', 11, struct wan_ec_api_) +# define WAN_EC_API_CMD_DTMF_DISABLE _IOWR('E', 12, struct wan_ec_api_) +# define WAN_EC_API_CMD_STATS _IOWR('E', 13, struct wan_ec_api_) +# define WAN_EC_API_CMD_STATS_FULL _IOWR('E', 14, struct wan_ec_api_) +# define WAN_EC_API_CMD_STATS_IMAGE _IOWR('E', 15, struct wan_ec_api_) +# define WAN_EC_API_CMD_BUFFER_LOAD _IOWR('E', 16, struct wan_ec_api_) +# define WAN_EC_API_CMD_BUFFER_UNLOAD _IOWR('E', 17, struct wan_ec_api_) +# define WAN_EC_API_CMD_PLAYOUT_START _IOWR('E', 18, struct wan_ec_api_) +# define WAN_EC_API_CMD_PLAYOUT_STOP _IOWR('E', 19, struct wan_ec_api_) +# define WAN_EC_API_CMD_MONITOR _IOWR('E', 20, struct wan_ec_api_) +# define WAN_EC_API_CMD_RELEASE_ALL _IOWR('E', 21, struct wan_ec_api_) +# define WAN_EC_API_CMD_CONFIG_POLL _IOWR('E', 22, struct wan_ec_api_) +# define WAN_EC_API_CMD_CHANNEL_MUTE _IOWR('E', 23, struct wan_ec_api_) +# define WAN_EC_API_CMD_CHANNEL_UNMUTE _IOWR('E', 24, struct wan_ec_api_) #endif # define WAN_EC_API_CMD_DECODE(cmd) \ @@ -134,6 +136,7 @@ (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_STATS_IMAGE) ? "Get Image 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" : \ @@ -166,6 +169,7 @@ typedef struct wan_ec_api_ { #define u_config u_ec.config #define u_config_poll u_ec.config_poll #define u_chip_stats u_ec.chip_stats +#define u_chip_image u_ec.chip_image #define u_chan_opmode u_ec.chan_opmode #define u_chan_mute u_ec.chan_mute #define u_chan_custom u_ec.chan_custom @@ -180,6 +184,7 @@ typedef struct wan_ec_api_ { wanec_config_t config; wanec_config_poll_t config_poll; wanec_chip_stats_t chip_stats; + wanec_chip_image_t chip_image; wanec_chan_opmode_t chan_opmode; wanec_chan_mute_t chan_mute; wanec_chan_custom_t chan_custom; @@ -193,5 +198,4 @@ typedef struct wan_ec_api_ { wan_custom_conf_t custom_conf; } wan_ec_api_t; - #endif /* __WANEC_IFACE_API_H */ diff --git a/rpmspec/wanpipe-mod.spec b/rpmspec/wanpipe-mod.spec index 95d37f8..636aec9 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.3.12 +%define version 3.3.14 %define release 0 %define serial 1 %define MODULES_DIR /lib/modules @@ -50,6 +50,51 @@ echo "Wanpipe Modules located in %{MODULES_DIR}/%{KVERSION}" %changelog +* Tue Oct 8 2008 Nenad Corbic - Beta - 3.3.14 +===================================================================== + +- Enabled Zaptel/DAHDI libss7 MTP2 option + +- Updated TDM API for A200 + Fixes FreeSwitch OpenZAP with TDM API for Analog + +- Bug fix in XMTP2 API + The fifo error could cause xmtp2 buffering to fail + +- wanpipemon utility + Updated T1/E1 Loopback comands + Bug fix on 2.6.25 kernels + +- Driver compile update for Latest + 2.6.26 kernels + +- Update AFT driver to implement new loopback commands + +- Updated for 56K driver + +- Added Asterisk DAHDI Support + +- A200/A400 Analog driver update + Bug fix possible race condition due to front end interrupt. + +- AFT Core Update + Disabled fifo overrun handling in transparent mode. + It does not provide any improvemnt. + XMTP2 API mode could run out of buffers due to overrun errors. + This has now been fixed. + +- Fixed A301 E3 Support + New firmware V11 is needed. + Please upgrade firmware before starting up the card. + To check firmware run: wanrouter hwprobe + + +* Fri Sep 1 2008 Nenad Corbic - Beta - 3.3.13 +===================================================================== + +- This release was never released. + + * Fri Aug 1 2008 Nenad Corbic - Beta - 3.3.12 ===================================================================== diff --git a/rpmspec/wanpipe-util.spec b/rpmspec/wanpipe-util.spec index 1849232..4201d85 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.3.12 +%define version 3.3.14 %define release 0 %define serial 1 %define ETC_DIR /etc @@ -327,6 +327,51 @@ enable_smg_log; %changelog +* Tue Oct 8 2008 Nenad Corbic - Beta - 3.3.14 +===================================================================== + +- Enabled Zaptel/DAHDI libss7 MTP2 option + +- Updated TDM API for A200 + Fixes FreeSwitch OpenZAP with TDM API for Analog + +- Bug fix in XMTP2 API + The fifo error could cause xmtp2 buffering to fail + +- wanpipemon utility + Updated T1/E1 Loopback comands + Bug fix on 2.6.25 kernels + +- Driver compile update for Latest + 2.6.26 kernels + +- Update AFT driver to implement new loopback commands + +- Updated for 56K driver + +- Added Asterisk DAHDI Support + +- A200/A400 Analog driver update + Bug fix possible race condition due to front end interrupt. + +- AFT Core Update + Disabled fifo overrun handling in transparent mode. + It does not provide any improvemnt. + XMTP2 API mode could run out of buffers due to overrun errors. + This has now been fixed. + +- Fixed A301 E3 Support + New firmware V11 is needed. + Please upgrade firmware before starting up the card. + To check firmware run: wanrouter hwprobe + + +* Fri Sep 1 2008 Nenad Corbic - Beta - 3.3.13 +===================================================================== + +- This release was never released. + + * Fri Aug 1 2008 Nenad Corbic - Beta - 3.3.12 ===================================================================== diff --git a/rpmspec/wanpipe.spec b/rpmspec/wanpipe.spec index 1719164..ea8c2eb 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.3.12 +%define version 3.3.14 %define release 0 %define serial 1 %define UTILS_DIR /usr/sbin @@ -254,6 +254,51 @@ install_init; %changelog +* Tue Oct 8 2008 Nenad Corbic - Beta - 3.3.14 +===================================================================== + +- Enabled Zaptel/DAHDI libss7 MTP2 option + +- Updated TDM API for A200 + Fixes FreeSwitch OpenZAP with TDM API for Analog + +- Bug fix in XMTP2 API + The fifo error could cause xmtp2 buffering to fail + +- wanpipemon utility + Updated T1/E1 Loopback comands + Bug fix on 2.6.25 kernels + +- Driver compile update for Latest + 2.6.26 kernels + +- Update AFT driver to implement new loopback commands + +- Updated for 56K driver + +- Added Asterisk DAHDI Support + +- A200/A400 Analog driver update + Bug fix possible race condition due to front end interrupt. + +- AFT Core Update + Disabled fifo overrun handling in transparent mode. + It does not provide any improvemnt. + XMTP2 API mode could run out of buffers due to overrun errors. + This has now been fixed. + +- Fixed A301 E3 Support + New firmware V11 is needed. + Please upgrade firmware before starting up the card. + To check firmware run: wanrouter hwprobe + + +* Fri Sep 1 2008 Nenad Corbic - Beta - 3.3.13 +===================================================================== + +- This release was never released. + + * Fri Aug 1 2008 Nenad Corbic - Beta - 3.3.12 ===================================================================== diff --git a/samples/diff b/samples/diff deleted file mode 100644 index 7afbbb1..0000000 --- a/samples/diff +++ /dev/null @@ -1,279 +0,0 @@ ---- /usr/sbin/wanrouter 2008-04-09 17:27:26.000000000 -0400 -+++ /common/wantools/scripts/wanrouter 2008-04-09 17:31:12.000000000 -0400 -@@ -106,9 +106,7 @@ - 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 -+ elif [ $OSYSTEM = "FreeBSD" ]; then - eval "type awk 2> /dev/null > /dev/null" - else - eval "awk 2> /dev/null > /dev/null" -@@ -194,6 +192,11 @@ - POINTOPOINT= - GATEWAY= - -+ if [ ! -d "$WAN_INTR_DIR" ]; then -+ error "Directory $WAN_INTR_DIR not found" -+ return 1 -+ fi -+ - if [ $NEW_IF_TYPE = YES ]; then - if [ $LINUX_DISTR = redhat ]; then - if [ $WAN_INTR_DIR = "/etc/sysconfig/network-scripts" ]; then -@@ -552,10 +555,6 @@ - #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" -@@ -595,7 +594,7 @@ - # fi - # fi - -- cd $WAN_INTR_DIR -+# cd $WAN_INTR_DIR - - # if [ -f $WAN_INTERFACE_PROC_FILE ]; then - # INTERFACES=`cat $WAN_INTERFACE_PROC_FILE | grep $device | cut -d' ' -f1` -@@ -617,7 +616,7 @@ - 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` -@@ -720,6 +719,12 @@ - if_file=$int_file; - fi - -+ if [ ! -d "$WAN_INTR_DIR" ]; then -+ error "Directory $WAN_INTR_DIR not found" -+ return 1 -+ fi -+ cd $WAN_INTR_DIR -+ - if [ -s $if_file ]; then - echo -n "$int_file " - interface_up $int_file || { -@@ -751,17 +756,17 @@ - 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%%=*} -- wanrouter_script stop $device $int_file #excutes interface stop script -- echo "Shutting down $device interface: $int_file" -- ifconfig $int_file down -- done -- } -+ #if [ ! -d "$WAN_INTR_DIR" ]; then -+ # return; -+ #} -+ INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -+ for i in $INTERFACES -+ do -+ int_file=${i%%=*} -+ wanrouter_script stop $device $int_file #excutes interface stop script -+ echo "Shutting down $device interface: $int_file" -+ ifconfig $int_file down -+ done - } - - # ---------------------------------------------------------------------------- -@@ -1152,7 +1157,6 @@ - { - 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 -@@ -1166,7 +1170,8 @@ - [ ! -f "$file" ] && { - if [ ! -z $file ]; - then -- echo -e "ERROR: Wanpipe configuration file not found: $file\n" -+ echo -e "ERROR: Wanpipe configuration file not found:" -+ echo -e " $file\n" - else - echo -e "ERROR: Wanpipe configuration file not found in $WAN_CONF_DIR\n" - fi -@@ -1792,6 +1797,56 @@ - fi - } - -+ -+pci_parity_ctrl () -+{ -+ -+ 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 -+ -+ -+ echo "Setting PCI Parity to $parity_cmd"; -+ -+ for dev in $IDS -+ do -+ if [ "$parity_cmd" = "on" ]; then -+ eval "setpci -s $dev 3e.b=0x7" -+ else -+ eval "setpci -s $dev 3e.b=0x4" -+ fi -+ -+ done -+ -+ return -+} -+ - wanrouter_debug () - { - local err=0 -@@ -2120,7 +2175,7 @@ - { - - if [ $OSYSTEM = "Linux" ]; then -- ROUTER_VERSION=3.3.6.1 -+ ROUTER_VERSION=3.3.2.p3 - IFCONFIG_LIST=ifconfig - MODULE_STAT=lsmod - WAN_DRIVERS="wanpipe" -@@ -2224,7 +2279,8 @@ - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - major_ver=${RELEASE%%.*} -- ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` -+ ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {print $1}'` -+ ROUTER_VERSION=${ROUTER_VERSION#wanpipe-} - IFCONFIG_LIST=ifconfig - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 -@@ -2242,12 +2298,17 @@ - - if [ -z ${WAN_MODULE_DIR} ]; then - WAN_MODULE_DIR=${MODULE_DIR} -- else -- if [ "${WAN_MODULE_DIR}" != ${MODULE_DIR} ]; then -- DEPMOD=NO -- fi - fi -- -+ dir=`kldconfig -r |grep $WAN_MODULE_DIR 2>/dev/null` -+ if [ -z $dir ]; then -+ kldconfig -m $WAN_MODULE_DIR 2>/dev/null -+ fi -+ -+ usymbol=`nm $WAN_MODULE_DIR/wanpipe.ko | grep " U zt_register" > /dev/null` -+ if [ -n $usymbol ]; then -+ kldconfig -m /usr/local/lib/zaptel 2>/dev/null -+ fi -+ - MOD9="${WAN_MODULE_DIR}/wanpipe_lip" - WANPIPE_LIP_MOD_DIR=${WAN_MODULE_DIR} - MOD10="${WAN_MODULE_DIR}/wanec" -@@ -2922,6 +2983,12 @@ - else - wanconfig hwprobe verbose - fi -+ elif [ "$2" = "legacy" ]; then -+ if [ $OSYSTEM = "Linux" ]; then -+ cat /proc/net/wanrouter/hwprobe_legacy -+ else -+ wanconfig hwprobe legacy -+ fi - else - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/hwprobe -@@ -2929,6 +2996,7 @@ - wanconfig hwprobe - fi - fi -+ echo - cleanup 0; - ;; - -@@ -2942,43 +3010,7 @@ - ;; - - parity) -- IDS=`lspci | cut -d' ' -f1` -- -- -- if [ -z $2 ]; then -- echo "Displaying System PCI Parity Configuration"; -- echo "==========================================" -- echo -- lspci -vvv | grep Parity -- echo -- echo "==========================================" -- cleanup 0; -- fi -- -- parity_cmd=${2:-"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!" -- cleanup 0; -- fi -- -- -- echo "Setting PCI Parity to $parity_cmd"; -- -- for dev in $IDS -- do -- if [ "$parity_cmd" = "on" ]; then -- eval "setpci -s $dev 3e.b=0x7" -- else -- eval "setpci -s $dev 3e.b=0x4" -- fi -- -- done -+ pci_parity_ctrl $2 - ;; - - wanrc) diff --git a/samples/wanpipe1.serial_lip_hdlc_mark b/samples/wanpipe1.serial_lip_hdlc_mark new file mode 100644 index 0000000..84e735b --- /dev/null +++ b/samples/wanpipe1.serial_lip_hdlc_mark @@ -0,0 +1,58 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Aug 27 11:15:01 EDT 2008 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipe1 = WAN_AFT_SERIAL, Comment + +[interfaces] +w1g1 = wanpipe1, , STACK, Comment +w1g1hdlc = wanpipe1, , API, lip_hdlc, w1g1.lip_hdlc + +[wanpipe1] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = YES #Autodetect PCI Slot for single card +PCISLOT = 0 +PCIBUS = 5 +FE_LINE = 1 + +MTU = 512 #Depending on BaudRate + #The MTU will define how many interrupts + #the board generates. + #For 64000bps use 128 + #For 1Mbps use 512 + +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +CONNECTION = PERMANENT +LINECODING = NRZ + +CLOCKING = EXTERNAL #Clocking: Internal or External +BaudRate = 1000000 #Only valid with CLOCKING=Internal + #9600 to 4000000 + +[w1g1hdlc] +LINEIDLE = MARK #Options: FLAG or MARK +LIP_MTU = 1500 + +[w1g1] +HDLC_STREAMING = NO +ACTIVE_CH = 1 +IDLE_FLAG = 0xFF #Underrun flag: any 8bit character + #HDLC: 0x7E + #Idle Mark: 0xFF diff --git a/samples/wanrouter b/samples/wanrouter index cd7e81f..df3b3c5 100644 --- a/samples/wanrouter +++ b/samples/wanrouter @@ -2195,7 +2195,7 @@ init_global_params() { if [ $OSYSTEM = "Linux" ]; then - ROUTER_VERSION=3.3.12 + ROUTER_VERSION=3.3.14 IFCONFIG_LIST=ifconfig MODULE_STAT=lsmod WAN_DRIVERS="wanpipe" diff --git a/scripts/Compile.sh b/scripts/Compile.sh index c379a88..361c0f0 100644 --- a/scripts/Compile.sh +++ b/scripts/Compile.sh @@ -1,5 +1,5 @@ #!/bin/sh -make CFLAGS=" -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dlinux -D__KERNEL__ -I/lib/modules/2.6.18-8.1.15.el5/build/include -DMODULE -DAF_WANPIPE_2612_FORCE_UPDATE -DWANPIPE_MOD_266_FORCE_UPDATE -m32 -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wstrict-prototypes -Wundef -Werror-implicit-function-declaration -Os -pipe -msoft-float -fno-builtin-sprintf -fno-builtin-log2 -fno-builtin-puts -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -mtune=generic -mregparm=3 -ffreestanding -I/lib/modules/2.6.18-8.1.15.el5/build/include/asm-i386/mach-generic -I/lib/modules/2.6.18-8.1.15.el5/build/include/asm-i386/mach-default -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -D__KERNEL__ -Iinclude -include include/linux/autoconf.h " PROTOCOL_DEFINES="-DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_X25 -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_LIP_ATM -DCONFIG_PRODUCT_WANPIPE_ATM -DCONFIG_PRODUCT_WANPIPE_MULTFR -DCONFIG_PRODUCT_WANPIPE_MULTPROT -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 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DWANPIPE_USE_I_PRIVATE -DCONFIG_WANPIPE_HWEC " +make CFLAGS=" -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dlinux -D__KERNEL__ -I/lib/modules/2.6.18-8.1.15.el5/build/include -DMODULE -DAF_WANPIPE_2612_FORCE_UPDATE -DWANPIPE_MOD_266_FORCE_UPDATE -m32 -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wstrict-prototypes -Wundef -Werror-implicit-function-declaration -Os -pipe -msoft-float -fno-builtin-sprintf -fno-builtin-log2 -fno-builtin-puts -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -mtune=generic -mregparm=3 -ffreestanding -I/lib/modules/2.6.18-8.1.15.el5/build/include/asm-i386/mach-generic -I/lib/modules/2.6.18-8.1.15.el5/build/include/asm-i386/mach-default -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -I/usr/src/zaptel-1.4.9.2" PROTOCOL_DEFINES="-DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL -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 -DWANPIPE_USE_I_PRIVATE -DCONFIG_WANPIPE_HWEC " diff --git a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops index d91e6b3..61d4086 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops @@ -9,11 +9,11 @@ svn:wc:ra_dav:version-url V 52 /svn/sangoma_mgd/!svn/ver/90/branches/bri/sigboost.h END -switch_buffer.h +sound.raw K 25 svn:wc:ra_dav:version-url -V 57 -/svn/sangoma_mgd/!svn/ver/73/branches/bri/switch_buffer.h +V 51 +/svn/sangoma_mgd/!svn/ver/73/branches/bri/sound.raw END sangoma_mgd.conf.sample K 25 @@ -21,11 +21,11 @@ svn:wc:ra_dav:version-url V 65 /svn/sangoma_mgd/!svn/ver/94/branches/bri/sangoma_mgd.conf.sample END -sound.raw +switch_buffer.h K 25 svn:wc:ra_dav:version-url -V 51 -/svn/sangoma_mgd/!svn/ver/73/branches/bri/sound.raw +V 57 +/svn/sangoma_mgd/!svn/ver/73/branches/bri/switch_buffer.h END callgettest.sh K 25 @@ -39,23 +39,17 @@ svn:wc:ra_dav:version-url V 48 /svn/sangoma_mgd/!svn/ver/73/branches/bri/ss7box END -re-sync.sh -K 25 -svn:wc:ra_dav:version-url -V 52 -/svn/sangoma_mgd/!svn/ver/73/branches/bri/re-sync.sh -END call_signal.c K 25 svn:wc:ra_dav:version-url V 56 /svn/sangoma_mgd/!svn/ver/100/branches/bri/call_signal.c END -sangoma_mgd.c +re-sync.sh K 25 svn:wc:ra_dav:version-url -V 56 -/svn/sangoma_mgd/!svn/ver/104/branches/bri/sangoma_mgd.c +V 52 +/svn/sangoma_mgd/!svn/ver/73/branches/bri/re-sync.sh END woomera.conf K 25 @@ -63,24 +57,30 @@ svn:wc:ra_dav:version-url V 54 /svn/sangoma_mgd/!svn/ver/73/branches/bri/woomera.conf END +sangoma_mgd.c +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/sangoma_mgd/!svn/ver/104/branches/bri/sangoma_mgd.c +END call_signal.h K 25 svn:wc:ra_dav:version-url V 55 /svn/sangoma_mgd/!svn/ver/74/branches/bri/call_signal.h END -sangoma_mgd.h -K 25 -svn:wc:ra_dav:version-url -V 56 -/svn/sangoma_mgd/!svn/ver/103/branches/bri/sangoma_mgd.h -END Changelog.sangoma_mgd K 25 svn:wc:ra_dav:version-url V 63 /svn/sangoma_mgd/!svn/ver/96/branches/bri/Changelog.sangoma_mgd END +sangoma_mgd.h +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/sangoma_mgd/!svn/ver/103/branches/bri/sangoma_mgd.h +END q931_cause.h K 25 svn:wc:ra_dav:version-url @@ -126,8 +126,8 @@ END Makefile K 25 svn:wc:ra_dav:version-url -V 50 -/svn/sangoma_mgd/!svn/ver/74/branches/bri/Makefile +V 51 +/svn/sangoma_mgd/!svn/ver/129/branches/bri/Makefile END sangoma_mgd_memdbg.h K 25 diff --git a/ssmg/sangoma_mgd.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/.svn/entries index 1a6479d..eafb56e 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/.svn/entries @@ -38,29 +38,8 @@ file 90 davidy -switch_buffer.h -file - - - - -2008-07-17T20:05:19.000000Z -f4832443a621cbb88e92535898d11b83 -2007-09-21T20:53:51.260136Z -1 -root - -sangoma_mgd.conf.sample -file - - - - -2008-07-18T17:35:42.000000Z -aa37de7bf3ea40901ff4245c34e10d64 -2008-07-18T17:55:36.114048Z -94 -ncorbic +app +dir sound.raw file @@ -75,8 +54,29 @@ da36acc78b83d5047481df0cca63d969 root has-props -app -dir +sangoma_mgd.conf.sample +file + + + + +2008-07-18T17:35:42.000000Z +aa37de7bf3ea40901ff4245c34e10d64 +2008-07-18T17:55:36.114048Z +94 +ncorbic + +switch_buffer.h +file + + + + +2008-07-17T20:05:19.000000Z +f4832443a621cbb88e92535898d11b83 +2007-09-21T20:53:51.260136Z +1 +root conf_bri dir @@ -94,6 +94,9 @@ file root has-props +conf +dir + ss7box file @@ -110,12 +113,21 @@ has-props svn:special -conf -dir - scripts dir +call_signal.c +file + + + + +2008-07-28T16:11:03.000000Z +1998b987f3d4de47366987e1c73a6dd3 +2008-07-21T17:51:24.576468Z +100 +davidy + re-sync.sh file @@ -129,17 +141,17 @@ file ncorbic has-props -call_signal.c +woomera.conf file -2008-07-28T16:11:03.000000Z -1998b987f3d4de47366987e1c73a6dd3 -2008-07-21T17:51:24.576468Z -100 -davidy +2008-07-17T12:23:48.000000Z +356d6fc18e0670efac6de6001e58648e +2007-09-21T20:53:51.260136Z +1 +root sangoma_mgd.c file @@ -153,18 +165,6 @@ file 104 davidy -woomera.conf -file - - - - -2008-07-17T12:23:48.000000Z -356d6fc18e0670efac6de6001e58648e -2007-09-21T20:53:51.260136Z -1 -root - call_signal.h file @@ -292,15 +292,15 @@ ncorbic Makefile file +129 - -2008-07-17T12:23:48.000000Z -d57cadf19c1416f7a50bdafd684299cc -2008-04-04T17:37:44.985328Z -74 -davidy +2008-09-17T21:49:21.000000Z +878683e34398e0ec9f2c0394203a9243 +2008-09-17T21:34:33.931600Z +129 +ncorbic sangoma_mgd_memdbg.h file diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base index da8412b..f9a92b2 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base @@ -82,9 +82,9 @@ sangoma_mgd: sangoma_mgd.o sangoma_mgd_memdbg.o call_signal.o switch_buffer.o si clean: old_cleanup - make -C lib/libteletone clean find . -name '*.o' | xargs rm -f rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + make -C lib/libteletone clean distclean: clean @echo OK diff --git a/ssmg/sangoma_mgd.trunk/Makefile b/ssmg/sangoma_mgd.trunk/Makefile index da8412b..f9a92b2 100644 --- a/ssmg/sangoma_mgd.trunk/Makefile +++ b/ssmg/sangoma_mgd.trunk/Makefile @@ -82,9 +82,9 @@ sangoma_mgd: sangoma_mgd.o sangoma_mgd_memdbg.o call_signal.o switch_buffer.o si clean: old_cleanup - make -C lib/libteletone clean find . -name '*.o' | xargs rm -f rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + make -C lib/libteletone clean distclean: clean @echo OK 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 183c60c..a315c8d 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/64/trunk +/svn/chan_woomera/!svn/ver/68/trunk END chan_woomera.c K 25 svn:wc:ra_dav:version-url V 50 -/svn/chan_woomera/!svn/ver/67/trunk/chan_woomera.c +/svn/chan_woomera/!svn/ver/68/trunk/chan_woomera.c END g711.h K 25 diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries index d61de4d..ed90e9c 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 -64 +69 https://www.sangomapbx.com/svn/chan_woomera/trunk https://www.sangomapbx.com/svn/chan_woomera -2008-07-18T18:22:21.096827Z -64 +2008-08-29T05:46:38.022521Z +68 ncorbic @@ -28,14 +28,14 @@ b26a191e-ab3a-0410-a271-b1e04e243bf1 chan_woomera.c file -67 -2008-07-23T17:19:33.000000Z -9dbcf37637ff5f4d61a14e49d47eb0ef -2008-07-23T17:37:55.239149Z -67 + +2008-09-17T21:49:12.000000Z +083876b45525e4742dfbc91ea74eeb48 +2008-08-29T05:46:38.022521Z +68 ncorbic g711.h @@ -64,7 +64,7 @@ davidy woomera.conf file -65 + 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 71c87d1..ace2887 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 @@ -14,6 +14,10 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= + * v1.35 Nenad Corbic + * Jul 23 2008 + * Bug Fix: Check for cid_name. + * * v1.34 Nenad Corbic * Jul 23 2008 * Added udp tagging and rx/tx sync options for @@ -198,7 +202,7 @@ #include "asterisk/dsp.h" #include "asterisk/musiconhold.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.34 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.35 $") #else @@ -248,7 +252,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.34 $") #define CALLWEAVER_19 1 #endif -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.34 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.35 $") /* CALLWEAVER v1.9 and later */ #if defined (CALLWEAVER_19) @@ -504,7 +508,7 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.34 $") extern int option_verbose; -#define WOOMERA_VERSION "v1.34" +#define WOOMERA_VERSION "v1.35" #ifndef WOOMERA_CHAN_NAME #define WOOMERA_CHAN_NAME "SS7" #endif @@ -4645,9 +4649,13 @@ static int woomera_event_incoming (private_object *tech_pvt) presentation |= atoi(screen_string) & 0x0F; } - cid_name = ast_strdupa(woomera_message_header(&wmsg, "Remote-Name")); + cid_name = woomera_message_header(&wmsg, "Remote-Name"); + if (cid_name) { + char *tmp_cid_name=cid_name; + cid_name = ast_strdupa(tmp_cid_name); + } - if ((cid_num = strchr(cid_name, '!'))) { + if (cid_name && (cid_num = strchr(cid_name, '!'))) { *cid_num = '\0'; cid_num++; } else { diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c index 71c87d1..ace2887 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c @@ -14,6 +14,10 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= + * v1.35 Nenad Corbic + * Jul 23 2008 + * Bug Fix: Check for cid_name. + * * v1.34 Nenad Corbic * Jul 23 2008 * Added udp tagging and rx/tx sync options for @@ -198,7 +202,7 @@ #include "asterisk/dsp.h" #include "asterisk/musiconhold.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.34 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.35 $") #else @@ -248,7 +252,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.34 $") #define CALLWEAVER_19 1 #endif -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.34 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.35 $") /* CALLWEAVER v1.9 and later */ #if defined (CALLWEAVER_19) @@ -504,7 +508,7 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.34 $") extern int option_verbose; -#define WOOMERA_VERSION "v1.34" +#define WOOMERA_VERSION "v1.35" #ifndef WOOMERA_CHAN_NAME #define WOOMERA_CHAN_NAME "SS7" #endif @@ -4645,9 +4649,13 @@ static int woomera_event_incoming (private_object *tech_pvt) presentation |= atoi(screen_string) & 0x0F; } - cid_name = ast_strdupa(woomera_message_header(&wmsg, "Remote-Name")); + cid_name = woomera_message_header(&wmsg, "Remote-Name"); + if (cid_name) { + char *tmp_cid_name=cid_name; + cid_name = ast_strdupa(tmp_cid_name); + } - if ((cid_num = strchr(cid_name, '!'))) { + if (cid_name && (cid_num = strchr(cid_name, '!'))) { *cid_num = '\0'; cid_num++; } else { diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/diff b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/diff deleted file mode 100644 index e44547e..0000000 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/diff +++ /dev/null @@ -1,171 +0,0 @@ -Index: chan_woomera.c -=================================================================== ---- chan_woomera.c (revision 66) -+++ chan_woomera.c (working copy) -@@ -14,6 +14,11 @@ - * This program is free software, distributed under the terms of - * the GNU General Public License - * ============================================= -+ * v1.34 Nenad Corbic -+ * Jul 23 2008 -+ * Added udp tagging and rx/tx sync options for -+ * voice streams debugging. Not for production. -+ * - * v1.33 Nenad Corbic - * Jul 18 2008 - * Added UDP Sequencing to check for dropped frames -@@ -193,7 +198,7 @@ - #include "asterisk/dsp.h" - #include "asterisk/musiconhold.h" - --ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.33 $") -+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.34 $") - - #else - -@@ -243,7 +248,7 @@ - #define CALLWEAVER_19 1 - #endif - --CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.33 $") -+CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.34 $") - - /* CALLWEAVER v1.9 and later */ - #if defined (CALLWEAVER_19) -@@ -499,7 +504,7 @@ - - extern int option_verbose; - --#define WOOMERA_VERSION "v1.33" -+#define WOOMERA_VERSION "v1.34" - #ifndef WOOMERA_CHAN_NAME - #define WOOMERA_CHAN_NAME "SS7" - #endif -@@ -691,6 +696,10 @@ - char language[WOOMERA_STRLEN]; - char* tg_language [WOOMERA_MAX_TRUNKGROUPS+1]; - int udp_seq; -+ int rx_sync_check_opt; -+ int tx_sync_check_opt; -+ int tx_sync_gen_opt; -+ - }; - - -@@ -739,6 +748,11 @@ - struct ast_jb_conf jbconf; - #endif /* AST_JB */ - -+ int sync_r; -+ int sync_w; -+ unsigned char sync_data_w; -+ unsigned char sync_data_r; -+ - }; - - typedef struct private_object private_object; -@@ -3742,7 +3756,7 @@ - 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); -@@ -3760,6 +3774,8 @@ - return NULL; - } - -+ /* Used for adding sequence numbers to udp packets. -+ should only be used for debugging */ - if (tech_pvt->profile->udp_seq){ - char *rxdata=(char*)(tech_pvt->fdata + AST_FRIENDLY_OFFSET); - res-=4; -@@ -3772,12 +3788,39 @@ - } else { - tech_pvt->rx_udp_seq++; - if (tech_pvt->rx_udp_seq != *((unsigned int*)(&rxdata[res]))) { -- ast_log(LOG_NOTICE, "%s: Error: Missing Rx Sequence Expect %i Received %i!\n", self->name,tech_pvt->rx_udp_seq, *((unsigned int*)(&rxdata[res]))); -+ ast_log(LOG_NOTICE, "%s: Error: Missing Rx Sequence Expect %i Received %i!\n", -+ self->name,tech_pvt->rx_udp_seq, *((unsigned int*)(&rxdata[res]))); - tech_pvt->rx_udp_seq = *((unsigned int*)(&rxdata[res])); - } - } - } - -+ /* Used for checking incoming udp stream. Should only be used for debugging. */ -+ if (tech_pvt->profile->rx_sync_check_opt){ -+ int i; -+ unsigned char *data = (unsigned char*)(tech_pvt->fdata + AST_FRIENDLY_OFFSET); -+ for (i=0;isync_r == 0) { -+ if (data[i] == 0x01) { -+ if (globals.debug > 2) { -+ ast_log(LOG_NOTICE, "%s: R Sync Acheived Offset=%i\n", self->name,i); -+ } -+ tech_pvt->sync_r=1; -+ tech_pvt->sync_data_r = data[i]; -+ } -+ } else { -+ tech_pvt->sync_data_r++; -+ if (tech_pvt->sync_data_r != data[i]) { -+ ast_log(LOG_NOTICE, "%s: R Sync Lost: Expected %i Got %i Offset=%i\n", -+ self->name, -+ tech_pvt->sync_data_r, data[i],i); -+ tech_pvt->sync_r=0; -+ } -+ } -+ } -+ } -+ -+ - tech_pvt->frame.frametype = AST_FRAME_VOICE; - tech_pvt->frame.subclass = tech_pvt->coding; - tech_pvt->frame.offset = AST_FRIENDLY_OFFSET; -@@ -3867,6 +3910,45 @@ - return 0; - } - -+ /* Used for debugging only never in production */ -+ if (tech_pvt->profile->tx_sync_check_opt){ -+ unsigned char *data = frame->data; -+ for (i=0;idatalen;i++) { -+ if (tech_pvt->sync_w == 0) { -+ if (data[i] == 0x01 && data[i+1] == 0x02) { -+ ast_log(LOG_NOTICE, "%s: W Sync Acheived Offset=%i\n", self->name,i); -+ tech_pvt->sync_w=1; -+ tech_pvt->sync_data_w = data[i]; -+ } -+ } else if (tech_pvt->sync_w == 1) { -+ tech_pvt->sync_data_w++; -+ if (tech_pvt->sync_data_w != data[i]) { -+ ast_log(LOG_NOTICE, "%s: W Sync Lost: Expected %i Got %i Offset=%i\n", -+ self->name, -+ tech_pvt->sync_data_w, data[i],i); -+ tech_pvt->sync_w=0; -+ if (0){ -+ int x; -+ ast_log(LOG_NOTICE, "%s: PRINTING FRAME Len=%i\n", -+ self->name,frame->datalen); -+ for (x=0;xdatalen;x++) { -+ ast_log(LOG_NOTICE, "%s: Off=%i Data %i\n", -+ self->name,x,data[x]); -+ } -+ } -+ } -+ } -+ } -+ -+ /* Used for debugging only never in production */ -+ } else if (tech_pvt->profile->tx_sync_gen_opt){ -+ unsigned char *data = frame->data; -+ int x; -+ for (x=0;xdatalen;x++) { -+ data[x]=++tech_pvt->sync_data_w; -+ } -+ } -+ - if(ast_test_flag(tech_pvt, TFLAG_MEDIA) && frame->datalen) { - if (frame->frametype == AST_FRAME_VOICE) { - 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/A108dm_0100_V35.BIN b/util/wan_aftup/A108dm_0100_V35.BIN new file mode 100644 index 0000000000000000000000000000000000000000..6b93c5f6adba77c93533d91c2aec11399905810f GIT binary patch literal 402936 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 PLXE_READ_DATA_SHIFT) & 0xFF; - - /* extract read data from EECTL */ + *data = (eeCtl >> PLXE_SHIFT_READ_DATA) & 0xFF; return 0; } @@ -177,22 +177,22 @@ int EE_WriteByte(void *info, unsigned char val) { int eeCtl,i; - eeCtl = EE_WaitIdle(info); /* make sure EEPROM is idle */ + if (EE_WaitIdle(info) & PLXE_MASK_BUSY){ + return -EINVAL; + } /* clear current WRITE value */ - eeCtl = 0; - eeCtl &= ~(0xff << PLXE_WRITE_DATA_SHIFT); - eeCtl |= (PLXE_CS_ENABLE_MASK | PLXE_BYTE_WRITE_START_MASK); - eeCtl |= ((val & 0xff) << PLXE_WRITE_DATA_SHIFT); + eeCtl = (PLXE_MASK_CS_ENABLE | PLXE_MASK_BYTE_WRITE_START); + eeCtl |= ((val & 0xff) << PLXE_SHIFT_WRITE_DATA); PEX_8111Write(info, EECTL, eeCtl); for (i=0;i<1000;i++){ PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & PLXE_BYTE_WRITE_START_MASK) == 0){ + if ((eeCtl & PLXE_MASK_BYTE_WRITE_START) == 0){ break; } } - if ((eeCtl & PLXE_BYTE_WRITE_START_MASK) != 0){ + if (eeCtl & PLXE_MASK_BYTE_WRITE_START){ printf("ERROR: EEPROM is still writting byte (busy)!\n"); return -EBUSY; } @@ -203,29 +203,29 @@ int EE_WriteByte(void *info, unsigned char val) //These are the high level functions -unsigned char wan_plxctrl_status(void *info) +int wan_plxctrl_status(void *info, unsigned char *status) { - unsigned char status = 0; - EE_WriteByte(info, READ_STATUS_EE_OPCODE); /* read status opcode */ - EE_ReadByte(info, &status); /* get EEPROM status */ + EE_WriteByte(info, PLXE_OPCODE_READ_STATUS); /* read status opcode */ + EE_ReadByte(info, status); /* get EEPROM status */ EE_Off(info); /* turn off EEPROM */ - return status; + return 0; } int wan_plxctrl_write8(void *info, unsigned char addr, unsigned char data) { - EE_WriteByte(info, WREN_EE_OPCODE); /* must first write-enable */ + EE_WriteByte(info, PLXE_OPCODE_WREN); /* must first write-enable */ EE_Off(info); /* turn off EEPROM */ - EE_WriteByte(info, WRITE_EE_OPCODE); /* opcode to write bytes */ + EE_WriteByte(info, PLXE_OPCODE_WRITE); /* 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_WriteByte(info, data & 0xFF); /* send data to be written */ EE_Off(info); /* turn off EEPROM */ + usleep(10000); return 0; } @@ -236,7 +236,7 @@ int wan_plxctrl_read8(void *info, unsigned char addr, unsigned char *data) { *data = 0x00; - EE_WriteByte(info, READ_EE_OPCODE); + EE_WriteByte(info, PLXE_OPCODE_READ); EE_WriteByte(info, (unsigned char)(addr & 0xFF)); EE_ReadByte(info, data); diff --git a/util/wancfg/Makefile.Linux b/util/wancfg/Makefile.Linux index 6d51bc2..00a4052 100644 --- a/util/wancfg/Makefile.Linux +++ b/util/wancfg/Makefile.Linux @@ -16,21 +16,20 @@ PROTOCOL_DEFINES = -DCONFIG_PRODUCT_WANPIPE_LIP_ATM -DCONFIG_PRODUCT_WANPIPE_AFT # Project file paths. Initilize to compile in develpment environment. # Changed when Setup script is running. -SYSINC=/lib/modules/$(shell uname -r)/build/include WAN_VIRTUAL= ENABLE_ZAPTEL_PARSER= ZAPINC=/usr/src/zaptel # Tools options. -#CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I. \ +#CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I. \ -D__LINUX__ -DSTATIC_LIBS=$(GD_STATIC) $(OGR_STATIC) $(PROTOCOL_DEFINES) -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I. -D__LINUX__ -I$(SYSINC) $(PROTOCOL_DEFINES) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I. -D__LINUX__ $(PROTOCOL_DEFINES) #uncomment this to compile from CVS, also may change to your zaptel installation directory #CFLAGS += -I/usr/src/zaptel -#CFLAGS += -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I. \ +#CFLAGS += -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I. \ -DSTATIC_LIBS= $(GD_STATIC) $(OGR_STATIC) $(PROTOCOL_DEFINES) CFLAGS += $(EXTRA_FLAGS) @@ -41,6 +40,10 @@ ifeq "${ENABLE_ZAPTEL_PARSER}" "YES" CFLAGS += -DZAPTEL_PARSER -I$(ZAPINC) endif +ifeq "${DAHDI_ISSUES}" "YES" +CFLAGS += -DDAHDI_ISSUES +endif + FILES=cpp_string.cpp\ conf_file_reader.cpp\ text_box_yes_no.cpp\ diff --git a/util/wancfg/conf_file_writer.h b/util/wancfg/conf_file_writer.h index 6f934c2..d49011c 100644 --- a/util/wancfg/conf_file_writer.h +++ b/util/wancfg/conf_file_writer.h @@ -24,7 +24,7 @@ #include "list_element_sangoma_card.h" #if defined(__LINUX__) -# include +# include #else #endif diff --git a/util/wancfg/list_element_sangoma_card.h b/util/wancfg/list_element_sangoma_card.h index 06030ef..661c222 100644 --- a/util/wancfg/list_element_sangoma_card.h +++ b/util/wancfg/list_element_sangoma_card.h @@ -25,7 +25,7 @@ #include "wancfg.h" #if defined(__LINUX__) -# include +# include #else #endif diff --git a/util/wancfg/wancfg.h b/util/wancfg/wancfg.h index 5f1a4ea..8677c66 100644 --- a/util/wancfg/wancfg.h +++ b/util/wancfg/wancfg.h @@ -88,6 +88,7 @@ BSD interface names rules: //#include #if defined(__LINUX__) +# include # include # include # include @@ -97,6 +98,7 @@ BSD interface names rules: #else # include # include +# include # include # include # include diff --git a/util/wancfg/zapcompat_user.h b/util/wancfg/zapcompat_user.h new file mode 100644 index 0000000..c1b8cc8 --- /dev/null +++ b/util/wancfg/zapcompat_user.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * zapcompat.h + * + * Author: Moises Silva + * + * Copyright: (c) 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. + * ============================================================================ + * Sep 06, 2008 Moises Silva Initial Version + ****************************************************************************** + */ + +// Simple compat header to compile with Zaptel or DAHDI +#ifndef __ZAPCOMPAT_H +# define __ZAPCOMPAT_H + +// for DAHDI we need to map values and functions from user ZT_XX to DAHDI_XX +#if defined (DAHDI_ISSUES) +#include +#include + +#define ZT_LAW_MULAW DAHDI_LAW_MULAW +#define ZT_LAW_ALAW DAHDI_LAW_ALAW +#define ZT_LAW_DEFAULT DAHDI_LAW_DEFAULT + +#define ZT_MAX_SPANS DAHDI_MAX_SPANS +#define ZT_MAX_CHANNELS DAHDI_MAX_CHANNELS + +#define ZT_SIG_EM DAHDI_SIG_EM +#define ZT_SIG_EM_E1 DAHDI_SIG_EM_E1 +#define ZT_SIG_FXSLS DAHDI_SIG_FXSLS +#define ZT_SIG_FXSGS DAHDI_SIG_FXSGS +#define ZT_SIG_FXSKS DAHDI_SIG_FXSKS +#define ZT_SIG_FXOLS DAHDI_SIG_FXOLS +#define ZT_SIG_FXOGS DAHDI_SIG_FXOGS +#define ZT_SIG_FXOKS DAHDI_SIG_FXOKS +#define ZT_SIG_CAS DAHDI_SIG_CAS +#define ZT_SIG_DACS DAHDI_SIG_DACS +#define __ZT_SIG_DACS __DAHDI_SIG_DACS +#define ZT_SIG_DACS_RBS DAHDI_SIG_DACS_RBS +#define ZT_SIG_CLEAR DAHDI_SIG_CLEAR +#define ZT_SIG_SLAVE DAHDI_SIG_SLAVE +#define ZT_SIG_HDLCRAW DAHDI_SIG_HDLCRAW +#define ZT_SIG_HDLCFCS DAHDI_SIG_HDLCFCS +#define ZT_SIG_HDLCNET DAHDI_SIG_HDLCNET + +#define ZT_ABIT DAHDI_ABIT +#define ZT_BBIT DAHDI_BBIT +#define ZT_CBIT DAHDI_CBIT +#define ZT_DBIT DAHDI_DBIT + +#define ZT_CONFIG_NOTOPEN DAHDI_CONFIG_NOTOPEN +#define ZT_CONFIG_HDB3 DAHDI_CONFIG_HDB3 +#define ZT_CONFIG_CCS DAHDI_CONFIG_CCS +#define ZT_CONFIG_CRC4 DAHDI_CONFIG_CRC4 +#define ZT_CONFIG_AMI DAHDI_CONFIG_AMI +#define ZT_CONFIG_B8ZS DAHDI_CONFIG_B8ZS +#define ZT_CONFIG_D4 DAHDI_CONFIG_D4 +#define ZT_CONFIG_ESF DAHDI_CONFIG_ESF + +// data types +#define zt_lineconfig dahdi_lineconfig +#define zt_dynamic_span dahdi_dynamic_span +#define zt_chanconfig dahdi_chanconfig + +#else +// zaptel is present +// we will keep the same old names in wanpipe code, I thought of changing them +// to something like WP_XX instead of ZT_XX, but I don't see any benefit on it +// and would make this file bigger +#include +#endif + +#endif /* __ZAPCOMPAT_H */ diff --git a/util/wancfg/zaptel_conf_file_reader.cpp b/util/wancfg/zaptel_conf_file_reader.cpp index 2f52c99..7c56c9b 100644 --- a/util/wancfg/zaptel_conf_file_reader.cpp +++ b/util/wancfg/zaptel_conf_file_reader.cpp @@ -21,7 +21,7 @@ #include "conf_file_writer.h" #if defined(__LINUX__) -# include +# include #else #endif diff --git a/util/wancfg_zaptel/.svn/all-wcprops b/util/wancfg_zaptel/.svn/all-wcprops new file mode 100644 index 0000000..7685faf --- /dev/null +++ b/util/wancfg_zaptel/.svn/all-wcprops @@ -0,0 +1,101 @@ +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel +END +install.sh +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/wanpipe/!svn/ver/6527/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/install.sh +END +A10u.pm +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/wanpipe/!svn/ver/6271/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/A10u.pm +END +uninstall.sh +K 25 +svn:wc:ra_dav:version-url +V 93 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/uninstall.sh +END +setup-sangoma +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/setup-sangoma +END +A10x.pm +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/wanpipe/!svn/ver/6519/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/A10x.pm +END +Card.pm +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/Card.pm +END +wancfg_zaptel +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_zaptel +END +A20x.pm +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/wanpipe/!svn/ver/6273/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/A20x.pm +END +A50x.pm +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/A50x.pm +END +wancfg_hp_tdmapi +K 25 +svn:wc:ra_dav:version-url +V 97 +/svn/wanpipe/!svn/ver/6521/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_hp_tdmapi +END +clean.sh +K 25 +svn:wc:ra_dav:version-url +V 89 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/clean.sh +END +wancfg_zaptel.pl +K 25 +svn:wc:ra_dav:version-url +V 97 +/svn/wanpipe/!svn/ver/6526/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_zaptel.pl +END +wancfg_dahdi +K 25 +svn:wc:ra_dav:version-url +V 93 +/svn/wanpipe/!svn/ver/6528/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_dahdi +END +wancfg_tdmapi +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_tdmapi +END +wancfg_smg +K 25 +svn:wc:ra_dav:version-url +V 91 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/wancfg_smg +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 89 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/Makefile +END diff --git a/util/wancfg_zaptel/.svn/entries b/util/wancfg_zaptel/.svn/entries new file mode 100644 index 0000000..d7c5f4b --- /dev/null +++ b/util/wancfg_zaptel/.svn/entries @@ -0,0 +1,232 @@ +8 + +dir +6523 +http://192.168.1.168/svn/wanpipe/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel +http://192.168.1.168/svn/wanpipe + + + +2008-09-29T21:12:18.983268Z +6522 +jpatel + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +0135086f-934c-0410-bbf7-b457164207c2 + +install.sh +file +6527 + + + +2008-09-30T14:27:51.000000Z +a0138d49c5b8350548bd759ed17d6c33 +2008-09-30T15:41:56.017338Z +6527 +jpatel +has-props + +A10u.pm +file + + + + +2008-09-29T21:41:43.000000Z +f8a66839cf40c36d8ca071b91fa7de0a +2008-08-01T17:27:13.443809Z +6271 +jpatel + +uninstall.sh +file + + + + +2008-09-29T21:41:43.000000Z +2fa7d36d74bc42bf8b7467c7d6b79dda +2007-03-28T20:56:52.000000Z +4261 +sangoma +has-props + +setup-sangoma +file + + + + +2008-09-29T21:41:43.000000Z +c631bf29819aed1b49bcd46369e06b59 +2007-11-29T17:48:57.000000Z +5110 +sangoma +has-props + +wancfg_zaptel +file + + + + +2008-09-29T21:41:43.000000Z +0c2f52a3b64e425d9b18b3d1a29586e8 +2008-01-08T21:32:19.000000Z +5238 +sangoma +has-props + +Card.pm +file + + + + +2008-09-29T21:41:43.000000Z +bdae4730e1307b1d0e2ff57e838214d1 +2007-11-21T22:45:01.000000Z +5065 +sangoma + +A10x.pm +file + + + + +2008-09-29T21:41:43.000000Z +479849314e150bf7870651df3a0f2490 +2008-09-29T21:09:34.159615Z +6519 +jpatel + +A20x.pm +file + + + + +2008-09-29T21:41:43.000000Z +fe8bb63e793fb81b1cb4a6da18041104 +2008-08-01T17:29:14.612073Z +6273 +jpatel + +A50x.pm +file + + + + +2008-09-29T21:41:43.000000Z +78359196ce69ba55e2090dadc0e961b6 +2008-04-28T14:25:43.000000Z +5723 +sangoma + +wancfg_hp_tdmapi +file + + + + +2008-09-29T21:41:43.000000Z +76a2b51ebac398910663a55cd9afa3e5 +2008-09-29T21:12:00.382239Z +6521 +jpatel +has-props + +clean.sh +file + + + + +2008-09-29T21:41:43.000000Z +b4242aa2636177d51d9fc55594429af2 +2007-03-28T20:56:52.000000Z +4261 +sangoma +has-props + +wancfg_dahdi +file +6528 + + + +2008-09-30T14:27:06.000000Z +0c2f52a3b64e425d9b18b3d1a29586e8 +2008-09-30T15:42:34.473797Z +6528 +jpatel +has-props + +wancfg_zaptel.pl +file +6526 + + + +2008-09-30T14:32:28.000000Z +229f1b67f2126efe10f1f18b32111bbb +2008-09-30T15:41:34.764906Z +6526 +jpatel +has-props + +templates +dir + +wancfg_tdmapi +file + + + + +2008-09-29T21:41:43.000000Z +aaab931de1fb3d154b36a90cafe3c188 +2008-01-21T16:09:32.000000Z +5307 +sangoma +has-props + +wancfg_smg +file + + + + +2008-09-29T21:41:43.000000Z +f712c9e2fe532e00de6ed899a37cebbc +2008-01-21T16:08:26.000000Z +5306 +sangoma + +Makefile +file + + + + +2008-09-29T21:41:43.000000Z +2aca39ada2ca1486cd51d20e87dcd30a +2007-11-12T20:34:16.000000Z +4990 +sangoma + diff --git a/util/wancfg_zaptel/.svn/format b/util/wancfg_zaptel/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/util/wancfg_zaptel/.svn/format @@ -0,0 +1 @@ +8 diff --git a/util/wancfg_zaptel/.svn/prop-base/clean.sh.svn-base b/util/wancfg_zaptel/.svn/prop-base/clean.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/clean.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/install.sh.svn-base b/util/wancfg_zaptel/.svn/prop-base/install.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/install.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/setup-sangoma.svn-base b/util/wancfg_zaptel/.svn/prop-base/setup-sangoma.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/setup-sangoma.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/uninstall.sh.svn-base b/util/wancfg_zaptel/.svn/prop-base/uninstall.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/uninstall.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/wancfg_dahdi.svn-base b/util/wancfg_zaptel/.svn/prop-base/wancfg_dahdi.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/wancfg_dahdi.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/wancfg_hp_tdmapi.svn-base b/util/wancfg_zaptel/.svn/prop-base/wancfg_hp_tdmapi.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/wancfg_hp_tdmapi.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/wancfg_tdmapi.svn-base b/util/wancfg_zaptel/.svn/prop-base/wancfg_tdmapi.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/wancfg_tdmapi.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.pl.svn-base b/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.pl.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.pl.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.svn-base b/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/.svn/prop-base/wancfg_zaptel.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/.svn/text-base/A10u.pm.svn-base b/util/wancfg_zaptel/.svn/text-base/A10u.pm.svn-base new file mode 100644 index 0000000..018307e --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/A10u.pm.svn-base @@ -0,0 +1,559 @@ +#class A10u +#for A101/2/u/c series cards + +package A10u; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _card => undef, + _fe_line => undef, + _fe_media => 'T1', + _fe_lcode => 'B8ZS', + _fe_frame => 'ESF', + _fe_clock => 'NORMAL', + _te_sig_mode => undef, + _te_ref_clock => '0', + _signalling => 'PRI_CPE', + _pri_switchtype => 'national', + _hw_dchan => '0', + _frac_chanfirst => '0', + _frac_chanlast => '0', + _ss7_sigchan => undef, + _ss7_option => undef, + _ss7_tdmchan => undef, + _ss7_subinterface => undef, + _ss7_tdminterface => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} +sub 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); + return $self->{_te_ref_clock}; +} +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub hw_dchan { + my ( $self, $hw_dchan ) = @_; + $self->{_hw_dchan} = $hw_dchan if defined($hw_dchan); + return $self->{_hw_dchan}; +} + + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub fe_lcode { + my ( $self, $fe_lcode) = @_; + $self->{_fe_lcode} = $fe_lcode if defined($fe_lcode); + return $self->{_fe_lcode}; +} + +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + + +sub fe_frame { + my ( $self, $fe_frame ) = @_; + $self->{_fe_frame} = $fe_frame if defined($fe_frame); + return $self->{_fe_frame}; +} + +sub fe_clock { + my ( $self, $fe_clock ) = @_; + $self->{_fe_clock} = $fe_clock if defined($fe_clock); + return $self->{_fe_clock}; +} + +sub pri_switchtype { + my ( $self, $pri_switchtype ) = @_; + $self->{_pri_switchtype} = $pri_switchtype if defined($pri_switchtype); + return $self->{_pri_switchtype}; +} + +sub ss7_option { + my ( $self, $ss7_option ) = @_; + $self->{_ss7_option} = $ss7_option if defined($ss7_option); + return $self->{_ss7_option}; +} + +sub ss7_sigchan { + my ( $self, $ss7_sigchan ) = @_; + $self->{_ss7_sigchan} = $ss7_sigchan if defined($ss7_sigchan); + return $self->{_ss7_sigchan}; +} + +sub ss7_tdmchan { + my ( $self, $ss7_tdmchan ) = @_; + $self->{_ss7_tdmchan} = $ss7_tdmchan if defined($ss7_tdmchan); + return $self->{_ss7_tdmchan}; +} + +sub ss7_subinterface { + my ( $self, $ss7_subinterface ) = @_; + $self->{_ss7_subinterface} = $ss7_subinterface if defined($ss7_subinterface); + return $self->{_ss7_subinterface}; +} + +sub ss7_tdminterface { + my ( $self, $ss7_tdminterface ) = @_; + $self->{_ss7_tdminterface} = $ss7_tdminterface if defined($ss7_tdminterface); + return $self->{_ss7_tdminterface}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + printf (" fe_line: %s\n fe_media: %s\n fe_lcode: %s\n fe_frame: %s \n fe_clock:%s\n ", $self->fe_line, $self->fe_media, $self->fe_lcode, $self->fe_frame, $self->fe_clock); + +} + + +sub get_alpha_from_num { + my ($num) = @_; + my $alpha_str=""; + my $alpha_char=""; + my $i; + my @chars = split(//, $num); + for $i (0..$#chars) { + if ( $i == 0 ) { + $alpha_char=chr(ord(@chars[$i])+48); + } else { + $alpha_char=chr(ord(@chars[$i])+49); + } + $alpha_str=$alpha_str."".$alpha_char; + } + return $alpha_str; +} + + +sub gen_wanpipe_ss7_subinterfaces{ + my ($self) = @_; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $ss7_sigchan = $self->ss7_sigchan; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $ss7_subinterface = $self->ss7_subinterface; + my $ss7_tdmchan = $self->ss7_tdmchan; + my $hwec_mode = $self->card->hwec_mode; + my $ss7_tdminterface = $self->ss7_tdminterface; + my $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.ss7.$ss7_subinterface"; + + open(FH, $wanpipe_ss7_interfaces_template) or die "Can't open $wanpipe_ss7_interfaces_template"; + my $wp_file=''; + while () { + if (!(($ss7_tdminterface == ' ') && (($wanpipe_ss7_interfaces_template =~ m/2/) || ($wanpipe_ss7_interfaces_template =~ m/5/)))){ + $wp_file .= $_; + } + } + close (FH); + + open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; + $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; + $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + + + print FH $wp_file; + close (FH); +} + +sub gen_wanpipe_conf{ + my ($self, $is_freebsd) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a10u"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_lcode = $self->fe_lcode; + my $fe_frame = $self->fe_frame; + my $fe_line = $self->fe_line; + my $te_sig_mode = $self->te_sig_mode; + my $fe_clock = $self->fe_clock; + my $ss7_option = $self->ss7_option; + my $dchan = 0; + my $fe_lbo; + my $fe_cpu; + my $tdm_voice_op_mode = "TDM_VOICE"; + + my $device_alpha = &get_alpha_from_num($device_no); + + my $te_sig_mode_line=''; + + + if ($ss7_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.ss7.4"; + } elsif ($ss7_option == 2){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u"; + } + + if ($self->fe_line eq '1'){ + $fe_cpu='A'; + }elsif($self->fe_line eq '2'){ + $fe_cpu='B'; + }else{ + print "Error: Invalid port on A101-2u\n"; + exit 1; + } + + + $dchan = 0; + if(!$is_freebsd){ + if ($self->signalling =~ m/PRI/ | $self->signalling =~ m/SS7/ ){ + if(($self->fe_media eq 'T1')){ + $dchan=24; + }else{ + $dchan=16; + } + } + } + if($self->fe_media eq 'T1'){ + $te_sig_mode_line=''; + $fe_lbo='0DB'; + }else{ + $fe_lbo='120OH'; + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + + if($self->signalling eq 'TDM API'){ + $tdm_voice_op_mode = "TDM_VOICE_API"; + #for tdm_api hw_dchan is set by user + $dchan = $self->hw_dchan; + + } + + + open(FH, $wanpipe_conf_template ) or die "Cannot open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + + $wp_file =~ s/DEVNUM/$device_no/g; + + if ( $is_freebsd ) { + $wp_file =~ s/IFNUM/$device_alpha/g; + } else { + $wp_file =~ s/IFNUM/$device_no/g; + } + $wp_file =~ s/TDM_VOICE_OP_MODE/$tdm_voice_op_mode/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELCODE/$fe_lcode/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; + $wp_file =~ s/FEFRAME/$fe_frame/g; + $wp_file =~ s/FECPU/$fe_cpu/g; + $wp_file =~ s/FECLOCK/$fe_clock/g; + $wp_file =~ s/FELBO/$fe_lbo/g; + $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + + print FH $wp_file; + close (FH); + +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} +sub gen_zaptel_conf{ + my ($self, $dchan_str) = @_; + my $zap_lcode; + my $zap_frame; + my $zap_crc4; + + if ( $self->fe_lcode eq 'B8ZS' ){ + $zap_lcode='b8zs'; + } elsif ( $self->fe_lcode eq 'AMI' ){ + $zap_lcode='ami'; + } elsif ( $self->fe_lcode eq 'HDB3' ){ + $zap_lcode='hdb3'; + } else { + printf("Error: invalid line coding %s\n", $self->fe_lcode); + exit; + } + + if ( $self->fe_frame eq 'ESF' ){ + $zap_frame='esf'; + } elsif ( $self->fe_frame eq 'D4' ){ + $zap_frame='d4'; + } elsif ( $self->fe_frame eq 'CRC4' ){ + $zap_frame='ccs'; + $zap_crc4=',crc4'; + } elsif ( $self->fe_frame eq 'NCRC4' ){ + $zap_frame='ccs'; + } else { + printf("Error: invalid line framing %s\n", $self->fe_frame); + exit; + } + + my $zp_file=''; + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + $zp_file.="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; + +} + + +sub gen_zapata_conf{ + my ($self) = @_; + + my $zp_file=''; + + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + +# $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + $zp_file.="switchtype=".$self->pri_switchtype."\n"; + } + + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $self->signalling eq 'PRI NET' ){ + $zp_file.="signalling=pri_net\n"; + } elsif ( $self->signalling eq 'PRI CPE' ){ + $zp_file.="signalling=pri_cpe\n"; + } elsif ( $self->signalling eq 'E & M' ){ + $zp_file.="signalling=em\n"; + } elsif ($self->signalling eq 'E & M Wink' ){ + $zp_file.="signalling=em_w\n"; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zp_file.="signalling=fxs_ls\n"; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zp_file.="signalling=fxs_gs\n"; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zp_file.="signalling=fxs_ks\n"; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zp_file.="signalling=fxo_ls\n"; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zp_file.="signalling=fxo_gs\n"; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zp_file.="signalling=fxo_ks\n"; + } else { + printf("Error: invalid signalling %s\n", $self->signalling); + } + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + if($self->frac_chan_last == 24){ + $self->frac_chan_last(23); + } + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + } + }else{ + if($self->frac_chan_first() != 0){ + if($self->frac_chan_last() == 16){ + $self->frac_chan_last(15); + } + if($self->frac_chan_first() == 16){ + $self->frac_chan_first(17); + } + if($self->frac_chan_last() > 15){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + my $mid_ch1=$self->card->first_chan + 14; + my $mid_ch2=$self->card->first_chan + 16; + + $zp_file.="channel =>".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } + } + } else { + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + } + return $zp_file; + +} + +1; diff --git a/util/wancfg_zaptel/.svn/text-base/A10x.pm.svn-base b/util/wancfg_zaptel/.svn/text-base/A10x.pm.svn-base new file mode 100644 index 0000000..6c114d7 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/A10x.pm.svn-base @@ -0,0 +1,665 @@ +#class A10x +#for A10x-sh series cards + +package A10x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _card => undef, + _fe_line => undef, + _fe_media => 'T1', + _fe_lcode => 'B8ZS', + _fe_frame => 'ESF', + _fe_clock => 'NORMAL', + _te_sig_mode => undef, + _te_ref_clock => '0', + _signalling => 'PRI_CPE', + _pri_switchtype => 'national', + _hw_dchan => '0', + _frac_chanfirst => '0', + _frac_chanlast => '0', + _ss7_sigchan => undef, + _ss7_option => undef, + _ss7_tdmchan => undef, + _ss7_subinterface => undef, + _ss7_tdminterface => undef, + _hp_option => undef, + _mtu_mru => undef, + _old_a10u => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} + +sub 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); + return $self->{_te_ref_clock}; +} +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub fe_lcode { + my ( $self, $fe_lcode) = @_; + $self->{_fe_lcode} = $fe_lcode if defined($fe_lcode); + return $self->{_fe_lcode}; +} + +sub fe_frame { + my ( $self, $fe_frame ) = @_; + $self->{_fe_frame} = $fe_frame if defined($fe_frame); + return $self->{_fe_frame}; +} + +sub hw_dchan { + my ( $self, $hw_dchan ) = @_; + $self->{_hw_dchan} = $hw_dchan if defined($hw_dchan); + return $self->{_hw_dchan}; +} + +sub fe_clock { + my ( $self, $fe_clock ) = @_; + $self->{_fe_clock} = $fe_clock if defined($fe_clock); + return $self->{_fe_clock}; +} + +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + +sub pri_switchtype { + my ( $self, $pri_switchtype ) = @_; + $self->{_pri_switchtype} = $pri_switchtype if defined($pri_switchtype); + return $self->{_pri_switchtype}; +} + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub ss7_option { + my ( $self, $ss7_option ) = @_; + $self->{_ss7_option} = $ss7_option if defined($ss7_option); + return $self->{_ss7_option}; +} + +sub hp_option { + my ( $self, $hp_option ) = @_; + $self->{_hp_option} = $hp_option if defined($hp_option); + return $self->{_hp_option}; +} + +sub ss7_sigchan { + my ( $self, $ss7_sigchan ) = @_; + $self->{_ss7_sigchan} = $ss7_sigchan if defined($ss7_sigchan); + return $self->{_ss7_sigchan}; +} + +sub ss7_tdmchan { + my ( $self, $ss7_tdmchan ) = @_; + $self->{_ss7_tdmchan} = $ss7_tdmchan if defined($ss7_tdmchan); + return $self->{_ss7_tdmchan}; +} + +sub ss7_subinterface { + my ( $self, $ss7_subinterface ) = @_; + $self->{_ss7_subinterface} = $ss7_subinterface if defined($ss7_subinterface); + return $self->{_ss7_subinterface}; +} + +sub ss7_tdminterface { + my ( $self, $ss7_tdminterface ) = @_; + $self->{_ss7_tdminterface} = $ss7_tdminterface if defined($ss7_tdminterface); + return $self->{_ss7_tdminterface}; +} + +sub mtu_mru { + my ( $self, $mtu_mru ) = @_; + $self->{_mtu_mru} = $mtu_mru if defined($mtu_mru); + return $self->{_mtu_mru}; +} + +sub old_a10u { + my ( $self, $old_a10u ) = @_; + $self->{_old_a10u} = $old_a10u if defined($old_a10u); + return $self->{_old_a10u}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + printf (" fe_line: %s\n fe_media: %s\n fe_lcode: %s\n fe_frame: %s \n fe_clock:%s\n ", $self->fe_line, $self->fe_media, $self->fe_lcode, $self->fe_frame, $self->fe_clock); + +} + +sub get_alpha_from_num { + my ($num) = @_; + my $alpha_str=""; + my $alpha_char=""; + my $i; + my @chars = split(//, $num); + for $i (0..$#chars) { + if ( $i == 0 ) { + $alpha_char=chr(ord(@chars[$i])+48); + } else { + $alpha_char=chr(ord(@chars[$i])+49); + } + $alpha_str=$alpha_str."".$alpha_char; + } + return $alpha_str; +} + + +sub gen_wanpipe_ss7_subinterfaces{ + my ($self) = @_; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $ss7_sigchan = $self->ss7_sigchan; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $ss7_subinterface = $self->ss7_subinterface; + my $ss7_tdmchan = $self->ss7_tdmchan; + my $mtu_mru = $self->mtu_mru; + my $hwec_mode = $self->card->hwec_mode; + my $ss7_tdminterface = $self->ss7_tdminterface; + my $hp_option = $self->hp_option; + my $card_type="WAN_AFT_TE1"; + my $old_a10u = $self->old_a10u; + my $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.$ss7_subinterface"; + if (!($hp_option == ' ')) { + #for hp tdmapi change templates + $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/hp_a100/wanpipe.hp.$ss7_subinterface"; + } + + if(($old_a10u =~ m/YES/)){ + $card_type="WAN_AFT"; + } + + my $hw_dtmf = $self->card->hw_dtmf; + + open(FH, $wanpipe_ss7_interfaces_template) or die "Can't open $wanpipe_ss7_interfaces_template"; + my $wp_file=''; + + while () { + if (!(($ss7_tdminterface == ' ') && (($wanpipe_ss7_interfaces_template =~ m/2/) || ($wanpipe_ss7_interfaces_template =~ m/5/)))){ + $wp_file .= $_; + } + } + close (FH); + + open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; + $wp_file =~ s/WAN_AFT_TYPE/$card_type/g; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; + $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/CHUNKTIME/$mtu_mru/g; + $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + print FH $wp_file; + close (FH); +} + +sub gen_wanpipe_conf{ + my ($self, $is_freebsd) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a100"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_lcode = $self->fe_lcode; + my $fe_frame = $self->fe_frame; + my $fe_line = $self->fe_line; + my $fe_clock = $self->fe_clock; + my $te_ref_clock = $self->te_ref_clock; + my $te_sig_mode = $self->te_sig_mode; + my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; + my $ss7_option = $self->ss7_option; + my $hp_option = $self->hp_option; + my $dchan = $self->hw_dchan; + my $fe_lbo; + my $old_a10u = $self->old_a10u; + my $fe_cpu = "A"; + my $card_type="WAN_AFT_TE1"; + + my $device_alpha = &get_alpha_from_num($device_no); + + my $te_sig_mode_line=''; + + if ($ss7_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.4"; + } elsif ($ss7_option == 2){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.tdmvoiceapi.a100"; + } elsif ($hp_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/hp_a100/wanpipe.hp.4"; + } + + if(($old_a10u =~ m/YES/)){ + #Set card type and CPU for old card in for hpdmapi + $card_type="WAN_AFT"; + if ($self->fe_line eq '1'){ + $fe_cpu='A'; + }elsif($self->fe_line eq '2'){ + $fe_cpu='B'; + }else{ + print "Error: Invalid port on A101-2u\n"; + exit 1; + } + } + $dchan = 0; + if(!$is_freebsd){ + if ($self->signalling =~ m/PRI/ | $self->signalling =~ m/SS7/ ){ + if(($self->fe_media eq 'T1')){ + $dchan=24; + }else{ + $dchan=16; + } + } + } + if($self->fe_media eq 'T1'){ + $te_sig_mode_line=''; + $fe_lbo='0DB'; + }else{ + $fe_lbo='120OH'; + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + + if($self->signalling eq 'TDM API' ){ + $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a100"; + #for tdm_api hw_dchan is set by user + $dchan = $self->hw_dchan; + + } + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + + if ( $is_freebsd ) { + $wp_file =~ s/IFNUM/$device_alpha/g; + } else { + $wp_file =~ s/IFNUM/$device_no/g; + } + + $wp_file =~ s/FECPU/$fe_cpu/g; + $wp_file =~ s/WAN_AFT_TYPE/$card_type/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELCODE/$fe_lcode/g; + $wp_file =~ s/FEFRAME/$fe_frame/g; + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; + $wp_file =~ s/FECLOCK/$fe_clock/g; + $wp_file =~ s/TEREFCLOCK/$te_ref_clock/g; + $wp_file =~ s/FELBO/$fe_lbo/g; + $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + print FH $wp_file; + close (FH); +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} + + +sub gen_zaptel_conf{ + my ($self, $dchan_str) = @_; + my $zap_lcode; + my $zap_frame; + my $zap_crc4; + my $zp_file=""; + + if ( $self->fe_lcode eq 'B8ZS' ){ + $zap_lcode='b8zs'; + } elsif ( $self->fe_lcode eq 'AMI' ){ + $zap_lcode='ami'; + } elsif ( $self->fe_lcode eq 'HDB3' ){ + $zap_lcode='hdb3'; + } else { + printf("Error: invalid line coding %s\n", $self->fe_lcode); + exit; + } + + if ( $self->fe_frame eq 'ESF' ){ + $zap_frame='esf'; + } elsif ( $self->fe_frame eq 'D4' ){ + $zap_frame='d4'; + } elsif ( $self->fe_frame eq 'CRC4' ){ + $zap_frame='ccs'; + $zap_crc4=',crc4'; + } elsif ( $self->fe_frame eq 'NCRC4' ){ + $zap_frame='ccs'; + } else { + printf("Error: invalid line framing %s\n", $self->fe_frame); + exit; + } + + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="bchan=".$first_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + 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_first == $self->frac_chan_last) { + if ($self->frac_chan_first == 16) { + print "Warning: You will not have any b-channels configured for this port"; + print "Would you like to continue?"; + if (&prompt_user_list(("YES","EXIT","")) eq 'EXIT'){ + exit(1); + } + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="bchan=".$first_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + 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){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.=$zap_signal."=".$first_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.=$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){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.=$zap_signal."=".$first_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.=$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; + +} + +sub gen_zapata_conf{ + my ($self) = @_; + + my $zp_file=''; + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + $zp_file.="switchtype=".$self->pri_switchtype."\n"; + } + + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $self->signalling eq 'PRI NET' ){ + $zp_file.="signalling=pri_net\n"; + } elsif ( $self->signalling eq 'PRI CPE' ){ + $zp_file.="signalling=pri_cpe\n"; + } elsif ( $self->signalling eq 'E & M' ){ + $zp_file.="signalling=em\n"; + } elsif ($self->signalling eq 'E & M Wink' ){ + $zp_file.="signalling=em_w\n"; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zp_file.="signalling=fxs_ls\n"; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zp_file.="signalling=fxs_gs\n"; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zp_file.="signalling=fxs_ks\n"; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zp_file.="signalling=fxo_ls\n"; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zp_file.="signalling=fxo_gs\n"; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zp_file.="signalling=fxo_ks\n"; + } else { + printf("Error: invalid signalling %s\n", $self->signalling); + } + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="channel =>".$first_ch."\n"; + } else { + 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_first == $self->frac_chan_last) { + #already sent warning on gen_zaptel_conf + if ($self->frac_chan_first != 16) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="channel =>".$first_ch."\n"; + } + } else { + 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){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="channel =>".$first_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+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + if ($self->frac_chan_first == $self->frac_chan_last) { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + $zp_file.="channel =>".$first_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+30)."\n"; + } + } + } + return $zp_file; + +} + +1; diff --git a/util/wancfg_zaptel/.svn/text-base/A20x.pm.svn-base b/util/wancfg_zaptel/.svn/text-base/A20x.pm.svn-base new file mode 100644 index 0000000..ecfde42 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/A20x.pm.svn-base @@ -0,0 +1,204 @@ +#class A20x +#for A200 series cards + +package A20x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _is_tdm_api => undef, + _card => undef, + _tdm_opermode => 'FCC', + _tdm_law => 'MULAW', + _rm_network_sync => 'NO', + _analog_modules => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} + +sub tdm_opermode { + my ( $self, $tdm_opermode ) = @_; + $self->{_tdm_opermode} = $tdm_opermode if defined($tdm_opermode); + return $self->{_tdm_opermode}; +} + +sub tdm_law { + my ( $self, $tdm_law ) = @_; + $self->{_tdm_law} = $tdm_law if defined($tdm_law); + return $self->{_tdm_law}; +} + +sub rm_network_sync { + my ( $self, $rm_network_sync ) = @_; + $self->{_rm_network_sync} = $rm_network_sync if defined($rm_network_sync); + return $self->{_rm_network_sync}; +} + +sub is_tdm_api { + my ( $self, $is_tdm_api ) = @_; + $self->{_is_tdm_api} = $is_tdm_api if defined($is_tdm_api); + return $self->{_is_tdm_api}; +} + +sub analog_modules { + my ( $self, $analog_modules ) = @_; + $self->{_analog_modules} = $analog_modules if defined($analog_modules); + return $self->{_analog_modules}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + +} + + +sub get_alpha_from_num { + my ($num) = @_; + my $alpha_str=""; + my $alpha_char=""; + my $i; + my @chars = split(//, $num); + for $i (0..$#chars) { + if ( $i == 0 ) { + $alpha_char=chr(ord(@chars[$i])+48); + } else { + $alpha_char=chr(ord(@chars[$i])+49); + } + $alpha_str=$alpha_str."".$alpha_char; + } + return $alpha_str; +} + +sub gen_wanpipe_conf{ + my ($self, $is_freebsd) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a200"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $tdm_law = $self->tdm_law; + my $tdm_opermode = $self->tdm_opermode; + my $rm_network_sync = $self->rm_network_sync; + my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; + my $is_tdm_api = $self->is_tdm_api; + my $tdm_voice_op_mode = "TDM_VOICE"; + + my $device_alpha = &get_alpha_from_num($device_no); + + if($self->is_tdm_api eq '0') { + $tdm_voice_op_mode = "TDM_VOICE_API"; + } + + open(FH, $wanpipe_conf_template) or die "Can open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + open(FH, ">$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + + if ( $is_freebsd ) { + $wp_file =~ s/IFNUM/$device_alpha/g; + } else { + $wp_file =~ s/IFNUM/$device_no/g; + } + + $wp_file =~ s/TDM_VOICE_OP_MODE/$tdm_voice_op_mode/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/TDM_LAW/$tdm_law/g; + $wp_file =~ s/RMNETSYNC/$rm_network_sync/g; + $wp_file =~ s/TDM_OPERMODE/$tdm_opermode/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + + print FH $wp_file; + close (FH); + +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} +sub gen_zaptel_conf{ + my ($self, $channel, $type) = @_; + my $zp_file=''; + if ( $type eq 'fxo'){ + #this is an FXS module + $zp_file.="fxoks=$channel\n"; + }else{ + $zp_file.="fxsks=$channel\n"; + } + return $zp_file; +} +sub gen_zapata_conf{ + my ($self, $channel, $type) = @_; + my $zp_file=''; + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $type eq 'fxo'){ + #this is an FXS module + $zp_file.="signalling = fxo_ks\n"; + }else{ + $zp_file.="signalling = fxs_ks\n"; + } + $zp_file.="channel => $channel\n\n"; + return $zp_file; +} + +1; diff --git a/util/wancfg_zaptel/.svn/text-base/A50x.pm.svn-base b/util/wancfg_zaptel/.svn/text-base/A50x.pm.svn-base new file mode 100644 index 0000000..2f5c621 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/A50x.pm.svn-base @@ -0,0 +1,194 @@ +#class A50x +#for A50x-sh series cards + +package A50x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _card => undef, + _fe_line => undef, + _fe_media => 'BRI', + _bri_switchtype => 'etsi', + _bri_country => 'europe', + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} + +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + + +sub bri_switchtype { + my ( $self, $bri_switchtype ) = @_; + $self->{_bri_switchtype} = $bri_switchtype if defined($bri_switchtype); + return $self->{_bri_switchtype}; +} + + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub get_alpha_from_num { + my ($num) = @_; + my $alpha_str=""; + my $alpha_char=""; + my $i; + my @chars = split(//, $num); + for $i (0..$#chars) { + if ( $i == 0 ) { + $alpha_char=chr(ord(@chars[$i])+48); + } else { + $alpha_char=chr(ord(@chars[$i])+49); + } + $alpha_str=$alpha_str."".$alpha_char; + } + return $alpha_str; +} + +sub gen_wanpipe_conf{ + my ($self, $is_freebsd) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a500"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_line = $self->fe_line; + my $hwec_mode = $self->card->hwec_mode; + + my $device_alpha = &get_alpha_from_num($device_no); + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + + if ( $is_freebsd ) { + $wp_file =~ s/IFNUM/$device_alpha/g; + } else { + $wp_file =~ s/IFNUM/$device_no/g; + } + + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + + print FH $wp_file; + close (FH); + +} + + +sub gen_bri_conf{ + my ($self, $span, $type, $group, $country, $operator, $conn_type, $default_tei) = @_; + my $bri_file=''; + + $bri_file.="\n"; + $bri_file.="group=$group\n"; + $bri_file.="country=$country\n"; + $bri_file.="operator=$operator\n"; + $bri_file.="connection_type=$conn_type\n"; + + + if ( $type eq 'bri_nt') { + $bri_file.="signalling=bri_nt\n"; + } else { + $bri_file.="signalling=bri_te\n"; + } + + if ( ! $default_tei eq ''){ + $bri_file.="default_tei=$default_tei\n"; + + } + $bri_file.="spans=$span\n"; + + return $bri_file; +} + + +sub gen_woomera_conf{ + my ($self, $group, $context) = @_; + my $woomera_file=''; + + $woomera_file.="\n"; + $woomera_file.="context=$context\n"; + $woomera_file.="group=$group\n"; + return $woomera_file; +} + + +1; diff --git a/util/wancfg_zaptel/.svn/text-base/Card.pm.svn-base b/util/wancfg_zaptel/.svn/text-base/Card.pm.svn-base new file mode 100644 index 0000000..7203bed --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/Card.pm.svn-base @@ -0,0 +1,117 @@ +package Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _cfg_dir => undef, + _device_no => undef, + _tdmv_span_no => undef, + _card_model => undef, + _pci_slot => undef, + _pci_bus => undef, + _fe_cpu => 'A', + _hwec_mode => 'NO', + _hw_dtmf => 'NO', + _first_chan => '0', + _zap_context => undef, + _zap_group => undef + }; + bless $self, $class; + return $self; +} + +sub device_no { + my ( $self, $device_no ) = @_; + $self->{_device_no} = $device_no if defined($device_no); + return $self->{_device_no}; +} + +sub tdmv_span_no { + my ( $self, $tdmv_span_no ) = @_; + $self->{_tdmv_span_no} = $tdmv_span_no if defined($tdmv_span_no); + return $self->{_tdmv_span_no}; +} + +sub card_model { + my ( $self, $card_model ) = @_; + $self->{_card_model} = $card_model if defined($card_model); + return $self->{_card_model}; +} + +sub pci_slot { + my ( $self, $pci_slot ) = @_; + $self->{_pci_slot} = $pci_slot if defined($pci_slot); + return $self->{_pci_slot}; +} + +sub pci_bus { + my ( $self, $pci_bus ) = @_; + $self->{_pci_bus} = $pci_bus if defined($pci_bus); + return $self->{_pci_bus}; +} + +sub fe_cpu { + my ( $self, $fe_cpu ) = @_; + $self->{_fe_cpu } = $fe_cpu if defined($fe_cpu); + return $self->{_fe_cpu}; +} + +sub hwec_mode { + my ( $self, $hwec_mode ) = @_; + $self->{_hwec_mode} = $hwec_mode if defined($hwec_mode); + return $self->{_hwec_mode}; +} + +sub hw_dtmf { + my ( $self, $hw_dtmf ) = @_; + $self->{_hw_dtmf} = $hw_dtmf if defined($hw_dtmf); + return $self->{_hw_dtmf}; +} + +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub first_chan { + my ( $self, $first_chan ) = @_; + $self->{_first_chan} = $first_chan if defined($first_chan); + return $self->{_first_chan}; +} + +sub zap_context { + my ( $self, $zap_context ) = @_; + $self->{_zap_context} = $zap_context if defined($zap_context); + return $self->{_zap_context}; +} + +sub zap_group { + my ( $self, $zap_group ) = @_; + $self->{_zap_group} = $zap_group if defined($zap_group); + return $self->{_zap_group}; +} + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub cfg_dir { + my ( $self, $cfg_dir ) = @_; + $self->{_cfg_dir} = $cfg_dir if defined($cfg_dir); + return $self->{_cfg_dir}; +} + +sub print { + my ($self) = @_; + printf (" span_no: %s\n card_model: %s\n pci_slot: %s\n pci_bus: %s\n hwec_mode: %s\n signalling %s\n first_chan: %s\n", $self->span_no, $self->card_model, $self->pci_slot, $self->pci_bus, $self->hwec_mode, $self->signalling, $self->first_chan); + +} + + +1; diff --git a/util/wancfg_zaptel/.svn/text-base/Makefile.svn-base b/util/wancfg_zaptel/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..50e5b7c --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/Makefile.svn-base @@ -0,0 +1,25 @@ +# ============================================================================ +# Makefile Make script for building Linux WAN router utilities. +# ---------------------------------------------------------------------------- +# Copyright (c) 1995-2000 Sangoma Technologies Inc. All Rights Reserved. +# ============================================================================ + +####### MACROS ############################################################### + +# Build options. +WZDIR=/etc/wanpipe/wancfg_zaptel +WAN_VIRTUAL= + +all: + +install: + @echo "Installing Wanconfig Zaptel/SMG utilites in $(WAN_VIRTUAL)/$(WZDIR)" + $(shell ./install.sh $(WZDIR) $(WAN_VIRTUAL) ) + +uninstall: + @echo "Un-installing Wanpipe utilites from $(WAN_VIRTUAL)/$(WZDIR)" + $(shell ./uninstall.sh $(WZDIR) $(WAN_VIRTUAL) ) + +clean: + @echo "Removing temporary wancfg_zaptel files" + $(shell ./clean.sh) diff --git a/util/wancfg_zaptel/.svn/text-base/clean.sh.svn-base b/util/wancfg_zaptel/.svn/text-base/clean.sh.svn-base new file mode 100644 index 0000000..5b8315d --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/clean.sh.svn-base @@ -0,0 +1,4 @@ +#!/bin/sh + + +rm -f tmp_cfg/* diff --git a/util/wancfg_zaptel/.svn/text-base/install.sh.svn-base b/util/wancfg_zaptel/.svn/text-base/install.sh.svn-base new file mode 100644 index 0000000..11fd0ff --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/install.sh.svn-base @@ -0,0 +1,38 @@ +#!/bin/sh + + +WAN_VIRTUAL=$2 +WZDIR=${1:-usr/local/sbin/wancfg_zaptel} + +if [ -z $WZDIR ]; then + echo "Directory not found $WZDIR" + exit 1 +fi + +if [ -e $WAN_VIRTUAL/$WZDIR ]; then + rm -rf $WAN_VIRTUAL/$WZDIR +fi + +mkdir -p $WAN_VIRTUAL/$WZDIR +cp -rf . $WAN_VIRTUAL/$WZDIR + +install -D -m 755 setup-sangoma $WAN_VIRTUAL/usr/local/sbin/setup-sangoma +install -D -m 755 wancfg_zaptel $WAN_VIRTUAL/usr/sbin/wancfg_zaptel +install -D -m 755 wancfg_dahdi $WAN_VIRTUAL/usr/sbin/wancfg_dahdi +install -D -m 755 wancfg_smg $WAN_VIRTUAL/usr/sbin/wancfg_smg +install -D -m 755 wancfg_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi +install -D -m 755 wancfg_hp_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_hp_tdmapi + + +#cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin +#chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma + + +#cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel + +#cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg + +#cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi diff --git a/util/wancfg_zaptel/.svn/text-base/setup-sangoma.svn-base b/util/wancfg_zaptel/.svn/text-base/setup-sangoma.svn-base new file mode 100644 index 0000000..1690edd --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/setup-sangoma.svn-base @@ -0,0 +1,5 @@ +#!/bin/sh +home=`pwd` +cd /etc/wanpipe/wancfg_zaptel +./wancfg_zaptel.pl --trixbox +cd $home diff --git a/util/wancfg_zaptel/.svn/text-base/uninstall.sh.svn-base b/util/wancfg_zaptel/.svn/text-base/uninstall.sh.svn-base new file mode 100644 index 0000000..c8dd3c6 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/uninstall.sh.svn-base @@ -0,0 +1,13 @@ +#!/bin/sh + +WAN_VIRTUAL=$2 +WZDIR=${1:-usr/local/sbin/wancfg_zaptel} + +if [ -z $WZDIR ]; then + echo "Directory not found $WZDIR" + exit 1 +fi + +if [ -e $WAN_VIRTUAL/$WZDIR ]; then + rm -rf $WAN_VIRTUAL/$WZDIR +fi diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_dahdi.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_dahdi.svn-base new file mode 100644 index 0000000..239eaca --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_dahdi.svn-base @@ -0,0 +1,51 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_hp_tdmapi.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_hp_tdmapi.svn-base new file mode 100644 index 0000000..c8bda84 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_hp_tdmapi.svn-base @@ -0,0 +1,52 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --hp_tdm_api --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_smg.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_smg.svn-base new file mode 100644 index 0000000..31feb04 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_smg.svn-base @@ -0,0 +1,51 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --smg --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_tdmapi.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_tdmapi.svn-base new file mode 100644 index 0000000..f501149 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_tdmapi.svn-base @@ -0,0 +1,52 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --tdm_api --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.pl.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.pl.svn-base new file mode 100644 index 0000000..9e35649 --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.pl.svn-base @@ -0,0 +1,2931 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Dahdi/Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 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. +# ---------------------------------------------------------------------------- +# Sep 30 2008 2.20 Jignesh Patel Configuration Support for Dahdi +# Aug 20 2008 2.19 Jignesh Patel Suppor for HP TDM API for A10x added hp_a100 +# Update A10x.pm-for SH and old a101/2cards +# Aug 1 2008 2.17 Jignesh Patel Support for Analog & a101/2 card for wancfg_tdmapi +# Update A10u.pm,A20x.pm,wanpipe.tdm.a10u/a200 +# Jul 22 2008 2.17 Jignesh Patel Support for FreeBSD ztcfg path +# Jun 6 2008 2.16 Jignesh Patel Added Zaptel Timer option for a500 cards +# May 28 2008 2.15 Jignesh Patel Minor d-chan update for FreeBSD- A10x.pm update +# May 27 2008 2.14 Jignesh Patel Added XMPT2 only option for SS7 +# May 27 2008 2.14 Jignesh Patel Updated ss7_a100x templates for new XMPT2 interface +# May 22 2008 2.13 Jignesh Patel Added confirmation /dev/zap/* loaded for hardhdlc test +# Apr 28 2008 2.13 Jignesh Patel Added TDM_OP_MODE for Analog and confirmation check +# Mar 28 2008 2.12 Jignesh Patel Removed BRI master clock and update unload_zap +# Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n########################################################################"; +print "\n# Sangoma Wanpipe #"; +print "\n# Dahdi/Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; +print "\n# v2.20 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2008. #"; +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 $rc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a 2>/dev/null |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $rc_dir=$etc_dir; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="lsmod"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $rc_dir="/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $no_boot=$FALSE; +my $boot_only=$FALSE; +my $no_hwdtmf=$FALSE; +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + +my $ztcfg_path=''; + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; + +my $is_tdm_api=$FALSE; +my $is_hp_tdm_api=$FALSE; + +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_woomera_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; +my $def_tdm_law=''; +my $def_tdm_opermode="FCC"; +my $def_is_ss7_xmpt2_only=''; + +my @silent_femedias; +my @silent_feframes; +my @silent_felcodes; +my @silent_tdm_laws; +my @silent_feclocks; +my @silent_signallings; +my @silent_pri_switchtypes; +my @silent_zapata_contexts; +my @silent_woomera_contexts; +my @silent_zapata_groups; +my @silent_bri_conn_types; +my @silent_woomera_groups; +my @silent_hwdtmfs; +my @silent_first_chans; +my @silent_last_chans; + + +my $silent_hwdtmf; +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +#my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_pri_switchtype="national"; +my $silent_zapata_context="from-pstn"; +my $silent_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"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; +my $silent_zapata_conf_file = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $dahdi_installed=$FALSE; +my $modprobe_list=`$module_list`; +my $is_ss7_xmpt2_only = $FALSE; +my $zaptel_dahdi_installed=$FALSE; + +my $def_chunk_size=40; +my $def_mtu_mru=' '; + + +read_args(); +if($boot_only==$TRUE){ + if ($os_type_list =~ m/FreeBSD/){ + exit( &config_boot_freebsd()); + } else { + exit( &config_boot_linux()); + } +} + +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`; +check_dahdi(); +check_zaptel(); +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 $zaptel_string="Zaptel"; +my $zapata_string="Zapata"; +my $wancfg_config="wancfg_zaptel"; +my $zaptel_boot = "zaptel"; +my $zaptel_cfg_script="zaptel_cfg_script"; +my $zap_cfg = "ztcfg"; + +if ($dahdi_installed== $TRUE) { + $zapata_conf_file_t="$asterisk_conf_dir/chan_dahdi.conf"; + $zaptel_conf_file_t="$etc_dir/dahdi/system.conf"; + $zaptel_string="Dahdi"; + $dchan_str="hardhdlc"; + $zapata_string="Chan-Dahdi"; + $wancfg_config="wancfg_dahdi"; + $zaptel_boot="dahdi"; + $zaptel_cfg_script="dahdi_cfg_script"; + $zap_cfg="dahdi_cfg"; + +} + + + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; +if( $zaptel_installed==$TRUE || $dahdi_installed==$TRUE ) { + $zaptel_dahdi_installed=$TRUE; +} + +if ($os_type_list =~ m/FreeBSD/ && $zaptel_dahdi_installed==$TRUE) { + parse_wanrouter_rc(); + update_zaptel_cfg_script(); +} + +if( $zaptel_installed==$TRUE && $os_type_list =~ m/Linux/ ) { + set_zaptel_hwhdlc(); +} + + +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +config_tdmv_dummy(); +summary(); +apply_changes(); + + +if ($os_type_list =~ m/FreeBSD/){ + config_boot_freebsd(); +} else { + config_boot_linux(); +} + +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; + + +#######################################FUNCTIONS################################################## + + +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_freebsd{ + if($no_boot==$TRUE){ + return 1; + } + my $res; + my $rc_init=""; + if (!open (FH,"$rc_dir/rc.conf")) { + print "Warning: Could not open $rc_dir/rc.conf. Using empty template\n"; + open (FH,"$current_dir/templates/rc_init_template_freebsd"); + } + + while () { + $rc_init .= $_; + } + close (FH); + + print ("Would you like wanrouter to start on system boot?\n"); + $res= &prompt_user_list("YES","NO",""); + + open (FH,">$rc_dir/rc.conf"); +# $rc_init =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + if ( $res eq "YES" ) { + $rc_init =~ s/wanpipe_enable\s*=.*/wanpipe_enable="YES"/g; + } else { + $rc_init =~ s/wanpipe_enable\s*=.*/wanpipe_enable="NO"/g; + } + print FH $rc_init; + close (FH); + +} + +sub config_boot_linux{ + if($no_boot==$TRUE){ + return 1; + } + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $network_start_level=10; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; + my $command=''; +# my $rc_dir=$etc_dir; + + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; + print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + my $res='YES'; + if($silent==$FALSE){ + print ("Would you like $script_name to start on system boot?\n"); + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return 1; + } + } + print "Verifying $zaptel_string boot scripts..."; + if($zaptel_dahdi_installed==$TRUE){ + print "Verifying $zaptel_string boot scripts..."; + #find zaptel/dahdi start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*$zaptel_boot >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*$zaptel_boot"; + $res=`$command`; + if ($res =~ /.*S(\d+)$zaptel_boot/){ + $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_string shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*$zaptel_boot >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*$zaptel_boot"; + $res=`$command`; + if ($res =~ /.*K(\d+)$zaptel_boot/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level-1; + } + } + + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return 1; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return 1; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return 1; + } + } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return 1; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return; + } + } + } + + } + + } + return 0; +} + + +sub config_ztcfg_start{ + + if ($num_zaptel_config ==0 || $silent==$TRUE){ + return; + } + my $command="find /etc/rc?.d/*$zaptel_boot >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel/Dahdi init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'$zap_cfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + if ( ! -d "$wanpipe_conf_dir/scripts" ) { + exec_command("mkdir -p $wanpipe_conf_dir/scripts"); + } + + exec_command("cp -f $current_dir/templates/$zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + my $res; + if($silent==$FALSE) { + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + $res = &prompt_user_list("YES","NO",""); + } else { + $res = "YES"; + } + if ($res 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){ + + 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 ((system("$module_list | grep zaptel > /dev/null 2> /dev/null")) == 0){ + $zaptel_installed=$TRUE; + } +} + +sub check_dahdi +{ + + if ((system("$module_list | grep dahdi > /dev/null 2> /dev/null")) == 0){ + $dahdi_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + if($silent==$FALSE) {system('clear')}; + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE || $is_hp_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 "\n$zaptel_string 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"); + } elsif ($is_tdm_api==$FALSE || $is_hp_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_dahdi_installed==$TRUE){ + if($is_tdm_api==$FALSE || $is_hp_tdm_api==$FALSE){ + print "\nUnloading $zaptel_string modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + if ($zaptel_dahdi_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new $zaptel_string configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new $zapata_string 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 && $is_hp_tdm_api==$FALSE ){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + + if ($num_zaptel_config != 0){ + print "Loading $zaptel_string...\n"; + sleep 2; + exec_command("$ztcfg_path\ztcfg -v"); + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + + if ($num_zaptel_config != 0){ + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + } + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_chan_no{ + my ($chan_name,$first_ch, $last_ch)=@_; + + my $res_ch=&prompt_user("\nInput the $chan_name channel for this span [$first_ch-$last_ch]\n"); + while(length($res_ch)==0 ||!($res_ch =~/(\d+)/) + || $res_ch<$first_ch || $res_ch>$last_ch){ + print "Invalid channel, must be between $first_ch and $last_ch\n"; + $res_ch=&prompt_user("Input the channel for this port[$first_ch-$last_ch]"); + } + return $res_ch; +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_woomera_contexts >= 0){ + $silent_woomera_context=pop(@silent_woomera_contexts); + } + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub update_zapata_template{ + #update comments for zapata.conf or chan_dahdi.conf + my $zapfile=""; + if (!open (FH,"$zapata_conf_file")) { + printf("Unable to modify $zapata_conf_file\n"); + + } + while () { + $zapfile .= $_; + } + close (FH); + open (FH,">$zapata_conf_file"); + $zapfile =~ s/ZAPATA_STRING/$zaptel_string/g; + $zapfile =~ s/LOCATION/$zapata_conf_file_t/g; + $zapfile =~ s/WANCFG_CONFIG/$wancfg_config/g; + $zapfile =~ s/DATE/$date/g; + print FH $zapfile; + close (FH); +} + + +sub update_zaptel_template{ + #update coments forzaptel.conf or chan_dahdi.conf + my $zapfile=""; + if (!open (FH,"$zaptel_conf_file")) { + printf("Unable to modify $zaptel_conf_file\n"); + + } + while () { + $zapfile .= $_; + } + close (FH); + open (FH,">$zaptel_conf_file"); + $zapfile =~ s/ZAPATA_STRING/$zaptel_string/g; + $zapfile =~ s/LOCATION/$zaptel_conf_file_t/g; + $zapfile =~ s/WANCFG_CONFIG/$wancfg_config/g; + $zapfile =~ s/DATE/$date/g; + print FH $zapfile; + close (FH); +} + + +sub prepare_files{ + + if ($is_trixbox==$TRUE || ($silent_zapata_conf_file==$TRUE && $silent==$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 && $is_hp_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 parse_wanrouter_rc +{ + #Set ztcfg_path based on $etc_dir/wanpipe/wanrouter.rc + if ( -f "$etc_dir/wanpipe/wanrouter.rc" ) { + my $line= `cat $etc_dir/wanpipe/wanrouter.rc | grep ZAPTEL_BIN_DIR`; + chop($line); + { + my @parts = split(/=/,$line); + $ztcfg_path="$parts[1]\/"; + } + #Use this wanrouter.rc as new template + my $command="cp -f $etc_dir/wanpipe/wanrouter.rc $current_dir/templates/wanrouter.rc.template.new > /dev/null 2>/dev/null "; + $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template.new"; + + } + +} + +sub update_zaptel_cfg_script(){ + + #update zaptel_cfg_script based on ztcfg_path + + my $sscript =""; + open (FH,"$current_dir/templates/$zaptel_cfg_script"); + + while () { + $sscript .= $_; + } + close (FH); + open (FH,">$current_dir/templates/$zaptel_cfg_script"); + $sscript =~ s/.*ztcfg.*/$ztcfg_path\ztcfg -v/; + print FH $sscript; + close (FH); +} + +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","xpp_usb","xpp" ,"wcte12xp","opvxa1200", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module /){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + if ($silent==$FALSE) {system('clear')}; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + update_zaptel_template(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($num_zaptel_config != 0 && $config_zapata==$TRUE){ + write_zapata_conf(); + update_zapata_template(); + + } + save_debug_info(); + if ($silent==$FALSE) {system('clear')}; + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + + print "\nConfigurator will create 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_string config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_string config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($num_zaptel_config !=0 && $config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + print "\n###################################################################\n\n"; + if($silent==$FALSE){ + 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 ){ + print "Error executing command:\n@command\n\n"; + if($silent==$FALSE){ + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--install_boot_script/){ + $boot_only=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--hp_tdm_api/){ + $is_hp_tdm_api=$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; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + + push(@silent_signallings, $silent_signalling); + + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + push(@silent_pri_switchtypes, $silent_pri_switchtype); + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + }elsif ( $_ =~/--zapata_auto_conf/){ + $silent_zapata_conf_file=$TRUE; + + }else { + printf("Error: Unrecognized parameter \"$_\" \n"); + exit(1); + + } + } + @silent_femedias = reverse(@silent_femedias); + @silent_feframes = reverse(@silent_feframes); + @silent_felcodes = reverse(@silent_felcodes); + @silent_tdm_laws = reverse(@silent_tdm_laws); + @silent_feclocks = reverse(@silent_feclocks); + @silent_signallings = reverse(@silent_signallings); + @silent_pri_switchtypes = reverse(@silent_pri_switchtypes); + @silent_zapata_contexts = reverse(@silent_zapata_contexts); + @silent_woomera_contexts = reverse(@silent_woomera_contexts); + @silent_zapata_groups = reverse(@silent_zapata_groups); + @silent_hwdtmfs = reverse(@silent_hwdtmfs); + @silent_first_chans = reverse(@silent_first_chans); + @silent_last_chans = reverse(@silent_last_chans); + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for Sangoma Media Gateway\n"; + } + if ($is_tdm_api==$TRUE | $is_hp_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_woomera_group{ + if($silent==$TRUE){ + if($#silent_woomera_groups >= 0){ + $silent_woomera_group=pop(@silent_woomera_groups); + } + return $silent_woomera_group; + } + + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_woomera_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_woomera_group); + } + $group=$res_group; + $def_woomera_group=$group; + return $def_woomera_group; +} + + + +sub get_bri_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"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; + } + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; + } + close (FH); + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; + close(FH); +} + + +sub get_bri_conn_type{ + my ($port)=@_; + + if($silent==$TRUE){ + if($#silent_bri_conn_types >= 0){ + $silent_bri_conn_type=pop(@silent_bri_conn_types); + } + return $silent_bri_conn_type; + } + printf("\nSelect connection type for port %d\n", $port); + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; + } + my $a50x; + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + if ($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + +select_bri_option: + if($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + } else { + $def_bri_option="YES"; + } + + + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + my $context=""; + my $group=""; + my $bri_pos=$a50x->card->tdmv_span_no; + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + my $conn_type=get_bri_conn_type($a50x->fe_line()); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + if($is_trixbox==$TRUE && $silent==$FALSE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=2; + } + } else { + $group=get_woomera_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); + + } + } + if ($os_type_list =~ m/FreeBSD/){ + $a50x->gen_wanpipe_conf(1); + } else { + $a50x->gen_wanpipe_conf(0); + } + + # $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); + } + + } + } + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + } + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } +} + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; + } else { + $f_port = "Port ".$port; + } + push(@f_list_normal_clocks, $f_port); + } + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; + } + } + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($silent==$TRUE){ + if($#silent_zapata_groups >= 0){ + $silent_zapata_group=pop(@silent_zapata_groups); + } + $silent_zapata_group = + return $silent_zapata_group; + } + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + if( $no_hwdtmf == $TRUE){ + return "NO"; + } + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; +} + +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} +sub prompt_tdm_opemode { + print("Which Operation Mode will be used?\n"); + my @options = ("FCC","TBR21","AUSTRALIA"); + my $def_tdm_opermode = &prompt_user_list(@options, $def_tdm_opermode); + return $def_tdm_opermode; +# +} + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + $first_cfg=0; + if($silent==$FALSE){ + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + } + my $fe_media = ''; + if ($silent==$TRUE){ + if($#silent_femedias >= 0){ + $silent_femedia=pop(@silent_femedias); + } + + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + + if($is_hp_tdm_api == $TRUE){ + #hp_tdm_api uses same templates:) + $a10x = eval {new A10x(); } or die ($@); + $a10x->old_a10u("YES"); + + }else{ + + $a10x = eval {new A10u(); } or die ($@); + #$a10x->card($card); + } + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + if($#silent_feclocks >= 0){ + $silent_feclock=pop(@silent_feclocks); + } + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_dahdi_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_dahdi_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } elsif ($is_hp_tdm_api==$TRUE){ + $def_signalling="HPTDM 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 && $is_hp_tdm_api == $FALSE ){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + if($#silent_signallings >= 0){ + $silent_signalling=pop(@silent_signallings); + } + if($is_tdm_api == $TRUE){ + $def_signalling="TDM API"; + } elsif ($is_hp_tdm_api == $TRUE){ + $def_signalling="HPTDM API"; + } else { + $def_signalling=$silent_signalling; + } + } + $a10x->signalling($def_signalling); + if ($fe_media eq 'E1') { + if (($def_signalling eq 'TDM API' ||$def_signalling eq 'HPTDM API') & $silent==$FALSE){ + 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); + my @options=""; + print("Select an option below to configure SS7 signalling channels:\n"); + my @options =("Configure SS7 XMPT2 Only", + "Configure SS7 XMPT2 + Voice"); + $def_is_ss7_xmpt2_only = &prompt_user_list(@options, "$def_is_ss7_xmpt2_only"); + + if($def_is_ss7_xmpt2_only=~ m/Only/){ + $is_ss7_xmpt2_only = $TRUE; + }else{ + $is_ss7_xmpt2_only = $FALSE; + } + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + if ($is_ss7_xmpt2_only ==$FALSE){ + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + } + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'HPTDM API'){ + $a10x->hp_option(1); + + @options = ("160","80", "40"); + + if ($silent==$FALSE){ + printf ("Select Chunk Size for AFT-A%s on port %s [slot:%s bus:%s]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_chunk_size=&prompt_user_list(@options,$def_chunk_size); + } + + my @options=""; + + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + @ss7_chan_array=&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media); + + } + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + 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); + #wanrouter start/stop for signalling span is controlled by ss7boxd + $startup_string.="wanpipe$devnum "; + + + + if ($ss7_sorted[0]==0) { + $def_mtu_mru=$def_chunk_size*$max_chans; + }else{ + my $no_chans = $max_chans - 1; + $def_mtu_mru=$def_chunk_size*($no_chans); + + } + $a10x->mtu_mru($def_mtu_mru); + + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + if($#silent_pri_switchtypes >= 0){ + $silent_pri_switchtype=pop(@silent_pri_switchtypes); + } + $def_feframe=$silent_feframe; + $a10x->pri_switchtype($silent_pri_switchtype); + } + } + #wanpipe gen section + 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 ($os_type_list =~ m/FreeBSD/){ + $a10x->gen_wanpipe_conf(1); + } else { + $a10x->gen_wanpipe_conf(0); + } + 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(); + } + }elsif ($a10x->signalling =~ m/HPTDM/){ + + $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){ + if ($ss7_element != 0) { + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + } + + #$a10x->gen_wanpipe_conf(); + if ($os_type_list =~ m/FreeBSD/){ + $a10x->gen_wanpipe_conf(1); + } else { + $a10x->gen_wanpipe_conf(0); + } + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + printf("@ss7_sorted\n"); + prompt_user("Press any key to continue"); + + if (@ss7_sorted != 0) { + foreach $ss7_element (@ss7_sorted){ + if ($ss7_element != 0) { + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + } + } + }else{ + if ($os_type_list =~ m/FreeBSD/){ + $a10x->gen_wanpipe_conf(1); + } else { + $a10x->gen_wanpipe_conf(0); + } + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + if($silent==$FALSE){ + printf ("Configuring port %s on %s as a full %s\n", $a10x->fe_line(), $a10x->card->card_model(),$a10x->fe_media()); + my $res=&prompt_user_list("YES - Use all channels", "NO - Configure for fractional","YES"); + if ($res =~ m/NO/){ + my $max_chan=0; + if($a10x->fe_media eq 'T1'){ + $max_chan=24; + } else { + $max_chan=31; + } + my $first_chan = &get_chan_no("first",1,$max_chan-1); + my $last_chan = &get_chan_no("last",$first_chan,$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 && $is_hp_tdm_api == $FALSE ){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\nPort ".$port." on AFT-A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + + my $a20x; + + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + if($is_tdm_api == $FALSE && $is_hp_tdm_api == $FALSE) { + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + } + foreach my $dev (@hwprobe) { + + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + if($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + if($is_trixbox==$FALSE){ + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE && $silent==$FALSE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law(&prompt_tdm_law()); + $a20x->tdm_opermode(&prompt_tdm_opemode()); + + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + + if($#silent_tdm_laws >= 0){ + $silent_tdm_law=pop(@silent_tdm_laws); + } + + $a20x->tdm_law($silent_tdm_law); + + } + + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + my $i; + if( $is_tdm_api == $FALSE) { + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $current_zap_channel+=24; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + }else{ + print "A$1 configured on slot:$3 bus:$4 span:$current_tdmapi_span\n"; + $a20x->is_tdm_api($TRUE); + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + } + $devnum++; + $num_analog_devices++; + if ($os_type_list =~ m/FreeBSD/){ + $a20x->gen_wanpipe_conf(1); + } else { + $a20x->gen_wanpipe_conf(0); + } + + }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 & $is_tdm_api==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + 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 & $is_tdm_api==$FALSE ){ + my $zap_pos = $1+$current_zap_channel-25; + 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"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } + +} +sub config_tdmv_dummy +{ + my $command=''; + if( $num_digital_devices == 0 && $num_analog_devices == 0 && $num_bri_devices !=0 && $zaptel_dahdi_installed==$TRUE && $os_type_list =~ m/Linux/ && $silent == $FALSE ){ + system('clear'); + print("Would you like to configure A500 BRI card as timing source for $zaptel_string?\n"); + print("(Visit http://wiki.sangoma.com/wanpipe-linux-asterisk-appendix#bri-tdmv for more information)\n"); + + if(&prompt_user_list("YES", "NO" ,"") =~ m/YES/){ +# + $command=("sed -i -e 's/TDMV_DUMMY.*/\TDMV_DUMMY_REF = YES/' $current_dir/$cfg_dir/wanpipe1.conf"); + + if ( system($command) == 0){ + printf("TDMV $zaptel_string Timer Enabled\n"); + prompt_user("Press any key to continue"); + + }else{ + printf("Failed to Enable TDMV $zaptel_string Timer for A500\n"); + printf("Please contact Sangoma Tech Support\n"); + exit 1; + } + } + } + + + + +} + diff --git a/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.svn-base b/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.svn-base new file mode 100644 index 0000000..239eaca --- /dev/null +++ b/util/wancfg_zaptel/.svn/text-base/wancfg_zaptel.svn-base @@ -0,0 +1,51 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/A10u.pm b/util/wancfg_zaptel/A10u.pm index 28905d7..2295ae1 100644 --- a/util/wancfg_zaptel/A10u.pm +++ b/util/wancfg_zaptel/A10u.pm @@ -255,6 +255,7 @@ sub gen_wanpipe_conf{ my $dchan = 0; my $fe_lbo; my $fe_cpu; + my $tdm_voice_op_mode = "TDM_VOICE"; my $device_alpha = &get_alpha_from_num($device_no); @@ -294,6 +295,15 @@ sub gen_wanpipe_conf{ $fe_lbo='120OH'; $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; } + + if($self->signalling eq 'TDM API'){ + $tdm_voice_op_mode = "TDM_VOICE_API"; + #for tdm_api hw_dchan is set by user + $dchan = $self->hw_dchan; + + } + + open(FH, $wanpipe_conf_template ) or die "Cannot open $wanpipe_conf_template"; my $wp_file=''; while () { @@ -309,7 +319,7 @@ sub gen_wanpipe_conf{ } else { $wp_file =~ s/IFNUM/$device_no/g; } - + $wp_file =~ s/TDM_VOICE_OP_MODE/$tdm_voice_op_mode/g; $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/FEMEDIA/$fe_media/g; @@ -332,6 +342,9 @@ sub gen_zaptel_conf{ my $zap_lcode; my $zap_frame; my $zap_crc4; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; + my $dahdi_echo = $self->card->dahdi_echo; if ( $self->fe_lcode eq 'B8ZS' ){ $zap_lcode='b8zs'; @@ -371,9 +384,23 @@ sub gen_zaptel_conf{ } my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$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"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + } + + } + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; } } else { @@ -391,16 +418,37 @@ sub gen_zaptel_conf{ my $mid_ch2=$self->card->first_chan + 16; $zp_file.="bchan=".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$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"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$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"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$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"; } } @@ -428,17 +476,43 @@ sub gen_zaptel_conf{ 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"; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$first_ch."-".$last_ch."\n"; + } + + } + } else { $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$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"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$first_ch."-".$last_ch."\n"; + } + + } } else { $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + + } + } } } @@ -449,8 +523,10 @@ sub gen_zaptel_conf{ sub gen_zapata_conf{ my ($self) = @_; - - my $zp_file=''; + my $zp_file=''; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; + $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"; @@ -462,6 +538,15 @@ sub gen_zapata_conf{ $zp_file.="context=".$self->card->zap_context."\n"; $zp_file.="group=".$self->card->zap_group."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocancel=yes\n"; + } else { + $zp_file.="echocancel=no\n"; + } + + } + if ( $self->signalling eq 'PRI NET' ){ $zp_file.="signalling=pri_net\n"; diff --git a/util/wancfg_zaptel/A10x.pm b/util/wancfg_zaptel/A10x.pm index c6b1fb4..c5709f6 100644 --- a/util/wancfg_zaptel/A10x.pm +++ b/util/wancfg_zaptel/A10x.pm @@ -28,6 +28,9 @@ sub new { _ss7_tdmchan => undef, _ss7_subinterface => undef, _ss7_tdminterface => undef, + _hp_option => undef, + _mtu_mru => undef, + _old_a10u => undef, }; bless $self, $class; return $self; @@ -122,6 +125,12 @@ sub ss7_option { return $self->{_ss7_option}; } +sub hp_option { + my ( $self, $hp_option ) = @_; + $self->{_hp_option} = $hp_option if defined($hp_option); + return $self->{_hp_option}; +} + sub ss7_sigchan { my ( $self, $ss7_sigchan ) = @_; $self->{_ss7_sigchan} = $ss7_sigchan if defined($ss7_sigchan); @@ -146,6 +155,18 @@ sub ss7_tdminterface { return $self->{_ss7_tdminterface}; } +sub mtu_mru { + my ( $self, $mtu_mru ) = @_; + $self->{_mtu_mru} = $mtu_mru if defined($mtu_mru); + return $self->{_mtu_mru}; +} + +sub old_a10u { + my ( $self, $old_a10u ) = @_; + $self->{_old_a10u} = $old_a10u if defined($old_a10u); + return $self->{_old_a10u}; +} + sub prompt_user{ my($promptString, $defaultValue) = @_; if ($defaultValue) { @@ -219,9 +240,22 @@ sub gen_wanpipe_ss7_subinterfaces{ my $device_no = $self->card->device_no; my $ss7_subinterface = $self->ss7_subinterface; my $ss7_tdmchan = $self->ss7_tdmchan; + my $mtu_mru = $self->mtu_mru; my $hwec_mode = $self->card->hwec_mode; my $ss7_tdminterface = $self->ss7_tdminterface; + my $hp_option = $self->hp_option; + my $card_type="WAN_AFT_TE1"; + my $old_a10u = $self->old_a10u; my $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.$ss7_subinterface"; + if (!($hp_option == ' ')) { + #for hp tdmapi change templates + $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/hp_a100/wanpipe.hp.$ss7_subinterface"; + } + + if(($old_a10u =~ m/YES/)){ + $card_type="WAN_AFT"; + } + my $hw_dtmf = $self->card->hw_dtmf; open(FH, $wanpipe_ss7_interfaces_template) or die "Can't open $wanpipe_ss7_interfaces_template"; @@ -235,14 +269,15 @@ sub gen_wanpipe_ss7_subinterfaces{ close (FH); open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; + $wp_file =~ s/WAN_AFT_TYPE/$card_type/g; $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/CHUNKTIME/$mtu_mru/g; $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; $wp_file =~ s/HWDTMF/$hw_dtmf/g; - print FH $wp_file; close (FH); } @@ -265,8 +300,12 @@ sub gen_wanpipe_conf{ my $hwec_mode = $self->card->hwec_mode; my $hw_dtmf = $self->card->hw_dtmf; my $ss7_option = $self->ss7_option; + my $hp_option = $self->hp_option; my $dchan = $self->hw_dchan; my $fe_lbo; + my $old_a10u = $self->old_a10u; + my $fe_cpu = "A"; + my $card_type="WAN_AFT_TE1"; my $device_alpha = &get_alpha_from_num($device_no); @@ -276,12 +315,22 @@ sub gen_wanpipe_conf{ $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.4"; } elsif ($ss7_option == 2){ $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.tdmvoiceapi.a100"; + } elsif ($hp_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/hp_a100/wanpipe.hp.4"; } - - if($self->signalling eq 'TDM API'){ - $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a100"; + + if(($old_a10u =~ m/YES/)){ + #Set card type and CPU for old card in for hpdmapi + $card_type="WAN_AFT"; + if ($self->fe_line eq '1'){ + $fe_cpu='A'; + }elsif($self->fe_line eq '2'){ + $fe_cpu='B'; + }else{ + print "Error: Invalid port on A101-2u\n"; + exit 1; + } } - $dchan = 0; if(!$is_freebsd){ if ($self->signalling =~ m/PRI/ | $self->signalling =~ m/SS7/ ){ @@ -300,6 +349,13 @@ sub gen_wanpipe_conf{ $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; } + if($self->signalling eq 'TDM API' ){ + $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a100"; + #for tdm_api hw_dchan is set by user + $dchan = $self->hw_dchan; + + } + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; my $wp_file=''; while () { @@ -315,8 +371,10 @@ sub gen_wanpipe_conf{ } else { $wp_file =~ s/IFNUM/$device_no/g; } - - $wp_file =~ s/SLOTNUM/$pci_slot/g; + + $wp_file =~ s/FECPU/$fe_cpu/g; + $wp_file =~ s/WAN_AFT_TYPE/$card_type/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/FEMEDIA/$fe_media/g; $wp_file =~ s/FELCODE/$fe_lcode/g; @@ -330,7 +388,6 @@ sub gen_wanpipe_conf{ $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; $wp_file =~ s/HWDTMF/$hw_dtmf/g; - print FH $wp_file; close (FH); # print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; @@ -343,6 +400,9 @@ sub gen_zaptel_conf{ my $zap_frame; my $zap_crc4; my $zp_file=""; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; + my $dahdi_echo = $self->card->dahdi_echo; if ( $self->fe_lcode eq 'B8ZS' ){ $zap_lcode='b8zs'; @@ -378,6 +438,12 @@ sub gen_zaptel_conf{ if ($self->frac_chan_first == $self->frac_chan_last) { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; $zp_file.="bchan=".$first_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$first_ch."\n"; + } + + } $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; } else { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; @@ -386,10 +452,27 @@ sub gen_zaptel_conf{ } my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + #$zp_file.="echocanceller=mg2".$first_ch."-".$last_ch."\n"; + #dahdi software echo canellation conf + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$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"; + + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + } + + } + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; } } else { @@ -404,6 +487,13 @@ sub gen_zaptel_conf{ } else { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; $zp_file.="bchan=".$first_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$first_ch."\n"; + } + + } + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; } } else { @@ -420,17 +510,40 @@ sub gen_zaptel_conf{ my $mid_ch2=$self->card->first_chan + 16; $zp_file.="bchan=".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$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"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$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"; + + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$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"; } } @@ -459,13 +572,36 @@ sub gen_zaptel_conf{ if ($self->frac_chan_first == $self->frac_chan_last) { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; $zp_file.=$zap_signal."=".$first_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$first_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.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$first_ch."-".$last_ch."\n"; + } + + } + + } } else { $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=".$dahdi_echo.",".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } + + } + } } else { if($self->frac_chan_first() != 0){ @@ -490,6 +626,8 @@ sub gen_zapata_conf{ my ($self) = @_; my $zp_file=''; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ @@ -498,6 +636,15 @@ sub gen_zapata_conf{ $zp_file.="context=".$self->card->zap_context."\n"; $zp_file.="group=".$self->card->zap_group."\n"; + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocancel=yes\n"; + } else { + $zp_file.="echocancel=no\n"; + } + + } + if ( $self->signalling eq 'PRI NET' ){ $zp_file.="signalling=pri_net\n"; @@ -529,6 +676,7 @@ sub gen_zapata_conf{ if ($self->frac_chan_first == $self->frac_chan_last) { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; $zp_file.="channel =>".$first_ch."\n"; + } else { my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; if($self->frac_chan_last == 24){ @@ -536,6 +684,7 @@ sub gen_zapata_conf{ } 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"; diff --git a/util/wancfg_zaptel/A20x.pm b/util/wancfg_zaptel/A20x.pm index 69d0795..49c8677 100644 --- a/util/wancfg_zaptel/A20x.pm +++ b/util/wancfg_zaptel/A20x.pm @@ -9,6 +9,7 @@ use strict; sub new { my ($class) = @_; my $self = { + _is_tdm_api => undef, _card => undef, _tdm_opermode => 'FCC', _tdm_law => 'MULAW', @@ -43,6 +44,12 @@ sub rm_network_sync { return $self->{_rm_network_sync}; } +sub is_tdm_api { + my ( $self, $is_tdm_api ) = @_; + $self->{_is_tdm_api} = $is_tdm_api if defined($is_tdm_api); + return $self->{_is_tdm_api}; +} + sub analog_modules { my ( $self, $analog_modules ) = @_; $self->{_analog_modules} = $analog_modules if defined($analog_modules); @@ -128,9 +135,15 @@ sub gen_wanpipe_conf{ my $rm_network_sync = $self->rm_network_sync; my $hwec_mode = $self->card->hwec_mode; my $hw_dtmf = $self->card->hw_dtmf; + my $is_tdm_api = $self->is_tdm_api; + my $tdm_voice_op_mode = "TDM_VOICE"; my $device_alpha = &get_alpha_from_num($device_no); + if($self->is_tdm_api eq '0') { + $tdm_voice_op_mode = "TDM_VOICE_API"; + } + open(FH, $wanpipe_conf_template) or die "Can open $wanpipe_conf_template"; my $wp_file=''; while () { @@ -146,7 +159,7 @@ sub gen_wanpipe_conf{ $wp_file =~ s/IFNUM/$device_no/g; } - + $wp_file =~ s/TDM_VOICE_OP_MODE/$tdm_voice_op_mode/g; $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/TDM_LAW/$tdm_law/g; @@ -164,19 +177,43 @@ sub gen_wanpipe_conf{ sub gen_zaptel_conf{ my ($self, $channel, $type) = @_; my $zp_file=''; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; + my $dahdi_echo = $self->card->dahdi_echo; if ( $type eq 'fxo'){ #this is an FXS module $zp_file.="fxoks=$channel\n"; }else{ $zp_file.="fxsks=$channel\n"; } + + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocanceller=" .$dahdi_echo.",".$channel."\n"; + } + + } + return $zp_file; } sub gen_zapata_conf{ + my ($self, $channel, $type) = @_; + my $dahdi_conf = $self->card->dahdi_conf; + my $hwec_mode = $self->card->hwec_mode; + my $dahdi_echo = $self->card->dahdi_echo; my $zp_file=''; $zp_file.="context=".$self->card->zap_context."\n"; $zp_file.="group=".$self->card->zap_group."\n"; + + if($dahdi_conf eq 'YES') { + if($hwec_mode eq 'NO' ) { + $zp_file.="echocancel=yes\n"; + } else { + $zp_file.="echocancel=no\n"; + } + + } if ( $type eq 'fxo'){ #this is an FXS module diff --git a/util/wancfg_zaptel/Card.pm b/util/wancfg_zaptel/Card.pm index 7203bed..cdae9bc 100644 --- a/util/wancfg_zaptel/Card.pm +++ b/util/wancfg_zaptel/Card.pm @@ -17,7 +17,9 @@ sub new { _hw_dtmf => 'NO', _first_chan => '0', _zap_context => undef, - _zap_group => undef + _zap_group => undef, + _dahdi_conf => 'NO', + _dahdi_echo => 'mg2' }; bless $self, $class; return $self; @@ -95,6 +97,18 @@ sub zap_group { return $self->{_zap_group}; } +sub dahdi_conf { + my ( $self, $dahdi_conf ) = @_; + $self->{_dahdi_conf} = $dahdi_conf if defined($dahdi_conf); + return $self->{_dahdi_conf}; +} + +sub dahdi_echo { + my ( $self, $dahdi_echo ) = @_; + $self->{_dahdi_echo} = $dahdi_echo if defined($dahdi_echo); + return $self->{_dahdi_echo}; +} + sub current_dir { my ( $self, $current_dir ) = @_; $self->{_current_dir} = $current_dir if defined($current_dir); diff --git a/util/wancfg_zaptel/install.sh b/util/wancfg_zaptel/install.sh index 951ae7d..11fd0ff 100755 --- a/util/wancfg_zaptel/install.sh +++ b/util/wancfg_zaptel/install.sh @@ -18,8 +18,10 @@ cp -rf . $WAN_VIRTUAL/$WZDIR install -D -m 755 setup-sangoma $WAN_VIRTUAL/usr/local/sbin/setup-sangoma install -D -m 755 wancfg_zaptel $WAN_VIRTUAL/usr/sbin/wancfg_zaptel +install -D -m 755 wancfg_dahdi $WAN_VIRTUAL/usr/sbin/wancfg_dahdi install -D -m 755 wancfg_smg $WAN_VIRTUAL/usr/sbin/wancfg_smg install -D -m 755 wancfg_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi +install -D -m 755 wancfg_hp_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_hp_tdmapi #cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin diff --git a/util/wancfg_zaptel/templates/.svn/all-wcprops b/util/wancfg_zaptel/templates/.svn/all-wcprops new file mode 100644 index 0000000..e8ada5e --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/all-wcprops @@ -0,0 +1,125 @@ +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates +END +wanpipe.tdm_api.a100 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanpipe.tdm_api.a100 +END +zaptel.conf_test +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zaptel.conf_test +END +wanpipe.tdm_api.a500 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6121/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanpipe.tdm_api.a500 +END +zaptel.conf +K 25 +svn:wc:ra_dav:version-url +V 102 +/svn/wanpipe/!svn/ver/6524/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zaptel.conf +END +smgbri_start_script +K 25 +svn:wc:ra_dav:version-url +V 110 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/smgbri_start_script +END +wanpipe.tdm.a100 +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanpipe.tdm.a100 +END +wanpipe.tdm.a200 +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/6296/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanpipe.tdm.a200 +END +smgbri_start_script_addon +K 25 +svn:wc:ra_dav:version-url +V 116 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/smgbri_start_script_addon +END +wanpipe.tdm.a10u +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/6270/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanpipe.tdm.a10u +END +woomera.conf +K 25 +svn:wc:ra_dav:version-url +V 103 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/woomera.conf +END +zaptel_cfg_script +K 25 +svn:wc:ra_dav:version-url +V 108 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zaptel_cfg_script +END +wanrouter.rc.template +K 25 +svn:wc:ra_dav:version-url +V 112 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanrouter.rc.template +END +zapata.conf +K 25 +svn:wc:ra_dav:version-url +V 102 +/svn/wanpipe/!svn/ver/6525/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zapata.conf +END +smg_bri.conf +K 25 +svn:wc:ra_dav:version-url +V 103 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/smg_bri.conf +END +zapata-auto.conf +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zapata-auto.conf +END +zaptel_cfg_script.FreeBSD +K 25 +svn:wc:ra_dav:version-url +V 116 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD +END +wanrouter.rc.template.FreeBSD +K 25 +svn:wc:ra_dav:version-url +V 120 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD +END +smgbri_stop_script +K 25 +svn:wc:ra_dav:version-url +V 109 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/smgbri_stop_script +END +rc_init_template_freebsd +K 25 +svn:wc:ra_dav:version-url +V 115 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/rc_init_template_freebsd +END +dahdi_cfg_script +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/wanpipe/!svn/ver/6529/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/dahdi_cfg_script +END diff --git a/util/wancfg_zaptel/templates/.svn/entries b/util/wancfg_zaptel/templates/.svn/entries new file mode 100644 index 0000000..cae444f --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/entries @@ -0,0 +1,278 @@ +8 + +dir +6523 +http://192.168.1.168/svn/wanpipe/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates +http://192.168.1.168/svn/wanpipe + + + +2008-09-29T21:12:18.983268Z +6522 +jpatel + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +0135086f-934c-0410-bbf7-b457164207c2 + +wanpipe.tdm_api.a100 +file + + + + +2008-09-29T21:41:43.000000Z +0e32d95d52cc353197b8705330fd89ea +2007-12-18T22:48:00.000000Z +5191 +sangoma + +zaptel.conf_test +file + + + + +2008-09-29T21:41:43.000000Z +252260603c3b6d02137b38d7ba1746fa +2008-02-15T16:18:58.000000Z +5379 +sangoma + +zaptel.conf +file +6524 + + + +2008-09-30T13:47:22.000000Z +51d35979a9250a27e10f3dad5b207fa3 +2008-09-30T15:40:48.614276Z +6524 +jpatel + +wanpipe.tdm_api.a500 +file + + + + +2008-09-29T21:41:43.000000Z +e4cf9645ce73ca84c1a11e67a5f1ecb9 +2008-07-15T15:10:52.223945Z +6121 +jpatel +has-props + +smgbri_start_script +file + + + + +2008-09-29T21:41:43.000000Z +7f142c319fc428bca8db102240675fd1 +2007-10-18T20:26:11.000000Z +4928 +sangoma + +wanpipe.tdm.a100 +file + + + + +2008-09-29T21:41:43.000000Z +1adcc2f8d0b59d9ba0afe8551ba84828 +2008-04-11T19:07:10.000000Z +5668 +sangoma + +wanpipe.tdm.a200 +file + + + + +2008-09-29T21:41:43.000000Z +8ebb269ef494ce44b8cf9593f414b0fa +2008-08-05T14:33:49.325752Z +6296 +jpatel + +hp_a100 +dir + +smgbri_start_script_addon +file + + + + +2008-09-29T21:41:43.000000Z +a7357626aaec063df93fbb56b8ad9f39 +2007-10-18T20:26:11.000000Z +4928 +sangoma + +wanpipe.tdm.a10u +file + + + + +2008-09-29T21:41:43.000000Z +72542adb6a63dd95e76401405d0b1d9b +2008-08-01T17:26:10.068623Z +6270 +jpatel + +woomera.conf +file + + + + +2008-09-29T21:41:43.000000Z +3208876e7f89304a6c9f7b67c0258ff9 +2007-12-18T22:48:00.000000Z +5191 +sangoma + +ss7_a100 +dir + +zaptel_cfg_script +file + + + + +2008-09-29T21:41:43.000000Z +34024ea35600779f71945493a51f1e29 +2007-11-21T22:45:01.000000Z +5065 +sangoma + +ss7_a10u +dir + +wanrouter.rc.template +file + + + + +2008-09-29T21:41:43.000000Z +bc4c710d5c9a3a9bcd4db1b64ab75512 +2007-11-07T13:52:32.000000Z +4981 +sangoma + +zapata.conf +file +6525 + + + +2008-09-30T13:47:27.000000Z +f2d8d605dd75d46c3e81175f21151e06 +2008-09-30T15:41:06.881099Z +6525 +jpatel + +smg_bri.conf +file + + + + +2008-09-29T21:41:43.000000Z +1382c164adaec70dec8d60575ca1f282 +2008-02-28T21:46:00.000000Z +5420 +sangoma + +zapata-auto.conf +file + + + + +2008-09-29T21:41:43.000000Z +5c098b1e75cb53f20c2ed2c4c02a2122 +2007-04-09T20:45:24.000000Z +4309 +sangoma + +zaptel_cfg_script.FreeBSD +file + + + + +2008-09-29T21:41:43.000000Z +f3e555d9128eed1186e637844c40518b +2007-11-07T14:46:43.000000Z +4983 +sangoma + +wanrouter.rc.template.FreeBSD +file + + + + +2008-09-29T21:41:43.000000Z +e25d0269230e6191dcb3c3b4665c1f0f +2007-11-07T13:52:32.000000Z +4981 +sangoma + +smgbri_stop_script +file + + + + +2008-09-29T21:41:43.000000Z +fb0ed7fdfe8b236b000a6e261a14d47d +2007-11-29T17:48:57.000000Z +5110 +sangoma + +rc_init_template_freebsd +file + + + + +2008-09-29T21:41:43.000000Z +545847e2deb63437c92acd9b4b7b7db1 +2008-04-11T19:06:32.000000Z +5667 +sangoma + +dahdi_cfg_script +file +6529 + + + +2008-09-30T14:20:51.000000Z +37dd824b1af4541c944a0e210df40551 +2008-09-30T15:43:06.030359Z +6529 +jpatel + diff --git a/util/wancfg_zaptel/templates/.svn/format b/util/wancfg_zaptel/templates/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/format @@ -0,0 +1 @@ +8 diff --git a/util/wancfg_zaptel/templates/.svn/prop-base/wanpipe.tdm_api.a500.svn-base b/util/wancfg_zaptel/templates/.svn/prop-base/wanpipe.tdm_api.a500.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/prop-base/wanpipe.tdm_api.a500.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/util/wancfg_zaptel/templates/.svn/text-base/dahdi_cfg_script.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/dahdi_cfg_script.svn-base new file mode 100644 index 0000000..fc334c0 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/dahdi_cfg_script.svn-base @@ -0,0 +1,29 @@ +#!/bin/sh +#Make sure that udev/devfs Dahdi device +#has come up. +cnt=0 +max_delay=30 + + +echo -n "Waiting for Dahdi /dev/dahdi ..." +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/dahdi ]; then + break; + fi + echo -n "." + sleep 2 +done +echo " " +if [ ! -e /dev/dahdi ]; then + echo + echo "Error: Dahdi device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +dahdi_cfg -v + diff --git a/util/wancfg_zaptel/templates/.svn/text-base/rc_init_template_freebsd.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/rc_init_template_freebsd.svn-base new file mode 100644 index 0000000..9562671 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/rc_init_template_freebsd.svn-base @@ -0,0 +1,4 @@ +#Warning: This file was added by the wancfg_zaptel utility. + +wanpipe_enable="NO" +wanrouter_rc_file="/usr/local/etc/wanpipe/wanrouter.rc" diff --git a/util/wancfg_zaptel/templates/.svn/text-base/smg_bri.conf.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/smg_bri.conf.svn-base new file mode 100644 index 0000000..6f3921e --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/smg_bri.conf.svn-base @@ -0,0 +1,148 @@ +;Country: +;possible values (default:europe): +;australia, austria, belgium, canada, chile, denmark, europe, finland, france, +;germany, hong_kong, india, irlande, israel, italy, japan, korea, luxembourg, +;netherlands, new_zealand, norway, portugal, singapore, south_africa, spain, +;sweden, switzerland, taiwan, uk, usa, ussr +; +;country=europe + +;Verbose: +;Increase level to at least 5 when debugging protocol related issues +;possible values (default:1): +;1-10 +; +;verbose=3 + +;Protocol capture: +;Enable/disable BRI protocol stack capture +;possible values (default:no): +;yes/no +; +;prot_capture=no + +;D-channel log: +;Enable/disable d-channel log +;Log file stored in /var/log/bri_log_span_# +;possible values (default:no) +;yes/no +; +;dchan_log=no + +;Dialplan: +;Some switches require the 'type of number' network specific facility IE to be set. +;This affects outgoing calls only. +;possible values (default:unknown): +;unknown +;national +;international +;network_specific +;subscriber +;abbreviated + +;dialplan=unknown + +;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. +;This affects incoming calls only. +; +;unknown_prefix= +;national_prefix= +;international_prefix= +;networkspf_prefix= +;subscriber_prefix= +;abbreviated_prefix= +; +;international_prefix=001 + +;Local Number (MSN): +;Used in point to multipoint configurations +;Protocol will only answer if called number = local number +; +;local_number=12356789 + +;Incoming calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;in_calls_behaviour=VOICE_ALERT_RQ + +;Outgoing calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;out_calls_behaviour=USER_SENDING_COMPLETE + +;General calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;gen_calls_behaviour=CHAN_ALLOC_LOWEST + +;Number of incoming digits +;Number of digits to route call if "Sending complete" bit is not set +;This only applies to incoming calls in overlap dial mode only +;possible values(default:8) +;1-31 +; +;num_digits=8 + +;Signalling: +;Signalling method. +;possible values (default:bri_te) +;bri_te :Customer side +;bri_nt ;Network side (Telco) + +;Connection: +;Connection type +;Most telcos use point_to_multipoint. +;set to point_to_point when connecting a NT port to ISDN BRI phone +;possible values (default:point_to_multipoint) +;point_to_point +;point_to_multipoint +; +;connection_type=point_to_multipoint + +;Group: +;Group assigned for outgoing calls +;possible values (default:1) +;1-63 +; +;group=1 + +;Spans +;Physical spans +;spans=1,2,3,4 + diff --git a/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script.svn-base new file mode 100644 index 0000000..1fab1fe --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script.svn-base @@ -0,0 +1,24 @@ +#!/bin/sh +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script_addon.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script_addon.svn-base new file mode 100644 index 0000000..ad57d2b --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_start_script_addon.svn-base @@ -0,0 +1,24 @@ + +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/wancfg_zaptel/templates/.svn/text-base/smgbri_stop_script.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_stop_script.svn-base new file mode 100644 index 0000000..daed6de --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/smgbri_stop_script.svn-base @@ -0,0 +1,2 @@ +#!/bin/sh +smg_ctrl stop diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a100.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a100.svn-base new file mode 100644 index 0000000..035a6fa --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a100.svn-base @@ -0,0 +1,51 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF + +[wIFNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a10u.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a10u.svn-base new file mode 100644 index 0000000..c9c18bf --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a10u.svn-base @@ -0,0 +1,50 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue Dec 12 16:21:45 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_OP_MODE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN + +[wIFNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a200.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a200.svn-base new file mode 100644 index 0000000..ef9067f --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm.a200.svn-base @@ -0,0 +1,47 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Mon Jul 31 17:10:23 EDT 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_ANALOG, Comment + +[interfaces] +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_OP_MODE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FXO/FXS +TDMV_LAW = TDM_LAW +TDMV_OPERMODE = TDM_OPERMODE +RM_BATTTHRESH = 3 +RM_BATTDEBOUNCE = 16 +FE_NETWORK_SYNC = RMNETSYNC +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_HW_DTMF = HWDTMF + +[wIFNUMg1] +ACTIVE_CH = ALL +MTU = 8 +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a100.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a100.svn-base new file mode 100644 index 0000000..66c68ad --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a100.svn-base @@ -0,0 +1,52 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a500.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a500.svn-base new file mode 100644 index 0000000..e3199f5 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanpipe.tdm_api.a500.svn-base @@ -0,0 +1,45 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + + + + +[devices] +wanpipeDEVNUM = WAN_AFT_ISDN_BRI, Comment + +[interfaces] +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = BRI +FE_LINE = FELINE +TDMV_LAW = ALAW +TDMV_DUMMY_REF = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO + +[wIFNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.FreeBSD.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.FreeBSD.svn-base new file mode 100644 index 0000000..a9f6188 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.FreeBSD.svn-base @@ -0,0 +1,34 @@ + +# /usr/local/etc/wanpipe/wanrouter.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /usr/local/etc/wanpipe directory. These are: +# +# ROUTER_BOOT= Boot flag (YES/NO). +# WAN_CONF_DIR= Directory of wanpipe config files. +# WAN_INTR_DIR= Where to put wanpipe interface files. +# WAN_FIRMWARE_DIR= Where to put protocol firmware files. +# WAN_LOG= Where to put start-up log file. +# WAN_LOCK_DIR= Directory of wanpipe device lock files. +# WAN_DEVICES= Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# /usr/local/etc/wanpipe directory: +# (ex. /usr/local/etc/wanpipe/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ROUTER_BOOT=YES +WAN_BIN_DIR=/usr/local/sbin +WAN_CONF_DIR=/usr/local/etc/wanpipe +WAN_INTR_DIR=/usr/local/etc/wanpipe/interfaces +WAN_MODULE_DIR=/usr/local/lib/wanpipe +WAN_FIRMWARE_DIR=/usr/local/etc/wanpipe/firmware +WAN_LOG=/var/log/wanrouter +WAN_LOCK_DIR=/var/lock +WAN_LIB_DIR=/usr/local/etc/wanpipe/lib +WAN_ADSL_LIST=/usr/local/etc/wanpipe/wan_adsl.list +WAN_DEVICES="WPSTARTUP" diff --git a/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.svn-base new file mode 100644 index 0000000..0e8cf8e --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/wanrouter.rc.template.svn-base @@ -0,0 +1,41 @@ +#!/bin/sh +# router.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /etc/wanpipe directory. These are: +# +# ROUTER_BOOT = Boot flag (YES/NO). +# WAN_CONF_DIR = Where to put wanpipe config files. +# WAN_INTR_DIR = Where to put wanpipe interface files. +# WAN_LOG = Where to put start-up log file. +# WAN_LOCK = File used as a lock. +# WAN_LOCK_DIR = +# WAN_IP_FORWARD = Enable IP Forwarding on startup. +# WAN_DEVICES = Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# WANPIPE_CONF_DIR directory: +# (ex. /etc/wanpipe/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ROUTER_BOOT=YES +WAN_CONF_DIR=/etc/wanpipe +WAN_INTR_DIR=/etc/wanpipe/interfaces +WAN_LOG=/var/log/wanrouter +WAN_LOCK=/var/lock/subsys/wanrouter +WAN_LOCK_DIR=/var/lock/subsys +WAN_IP_FORWARD=NO +NEW_IF_TYPE=NO +WAN_LIB_DIR=/etc/wanpipe/lib +WAN_ADSL_LIST=/etc/wanpipe/wan_adsl.list +WAN_ANNEXG_LOAD=NO +WAN_LIP_LOAD=YES +WAN_DYN_WANCONFIG=NO +WAN_SCRIPTS_DIR=/etc/wanpipe/scripts +WAN_FIRMWARE_DIR=/etc/wanpipe/firmware +WAN_DEVICES_REV_STOP_ORDER=YES +WAN_DEVICES="WPSTARTUP" diff --git a/util/wancfg_zaptel/templates/.svn/text-base/woomera.conf.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/woomera.conf.svn-base new file mode 100644 index 0000000..9fe5c8e --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/woomera.conf.svn-base @@ -0,0 +1,12 @@ +[settings] +debug=2 + +[default] +host=localhost +port=42420 +audio_ip=127.0.0.1 +default_context=sangoma +debug=2 +dtmf_enable=1 +jb_enable=0 +progress_enable=0 diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zapata-auto.conf.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zapata-auto.conf.svn-base new file mode 100644 index 0000000..ef0fd10 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zapata-auto.conf.svn-base @@ -0,0 +1,7 @@ +; Autogenerated by /usr/local/sbin/sangoma/setup-sangoma -- do not hand edit +; Zaptel Channels Configurations (zapata.conf) +; +; This is not intended to be a complete zapata.conf. Rather, it is intended +; to be #include-d by /etc/zapata.conf that will include the global settings +; +callerid=asreceived diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zapata.conf.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zapata.conf.svn-base new file mode 100644 index 0000000..af3ec8c --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zapata.conf.svn-base @@ -0,0 +1,28 @@ +;autogenerated by /usr/sbin/WANCFG_CONFIG do not hand edit +;autogenrated on DATE +;ZAPATA_STRING Channels Configurations +;For detailed ZAPATA_STRING options, view LOCATION.bak + +[trunkgroups] + +[channels] +context=default +usecallerid=yes +hidecallerid=no +callwaiting=yes +usecallingpres=yes +callwaitingcallerid=yes +threewaycalling=yes +transfer=yes +canpark=yes +cancallforward=yes +callreturn=yes +echocancel=yes +echocancelwhenbridged=yes +relaxdtmf=yes +rxgain=0.0 +txgain=0.0 +group=1 +callgroup=1 +pickupgroup=1 +immediate=no diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf.svn-base new file mode 100644 index 0000000..68fd39f --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf.svn-base @@ -0,0 +1,6 @@ +#autogenerated by /usr/sbin/WANCFG_CONFIG do not hand edit +#autogenrated on DATE +#ZAPATA_STRING Channels Configurations +#For detailed ZAPATA_STRING options, view LOCATION.bak +loadzone=us +defaultzone=us diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf_test.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf_test.svn-base new file mode 100644 index 0000000..2823dcc --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zaptel.conf_test.svn-base @@ -0,0 +1 @@ +hardhdlc=24 diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.FreeBSD.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.FreeBSD.svn-base new file mode 100644 index 0000000..6f2deaf --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.FreeBSD.svn-base @@ -0,0 +1,6 @@ +#!/bin/sh + +sleep 1 + +ztcfg -v + diff --git a/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.svn-base b/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.svn-base new file mode 100644 index 0000000..9793904 --- /dev/null +++ b/util/wancfg_zaptel/templates/.svn/text-base/zaptel_cfg_script.svn-base @@ -0,0 +1,29 @@ +#!/bin/sh +#Make sure that udev/devfs zaptel device +#has come up. +cnt=0 +max_delay=30 + + +echo -n "Waiting for zaptel device /dev/zap ..." +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/zap ]; then + break; + fi + echo -n "." + sleep 2 +done +echo " " +if [ ! -e /dev/zap ]; then + echo + echo "Error: Zaptel device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +ztcfg -v + diff --git a/util/wancfg_zaptel/templates/dahdi_cfg_script b/util/wancfg_zaptel/templates/dahdi_cfg_script new file mode 100644 index 0000000..fc334c0 --- /dev/null +++ b/util/wancfg_zaptel/templates/dahdi_cfg_script @@ -0,0 +1,29 @@ +#!/bin/sh +#Make sure that udev/devfs Dahdi device +#has come up. +cnt=0 +max_delay=30 + + +echo -n "Waiting for Dahdi /dev/dahdi ..." +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/dahdi ]; then + break; + fi + echo -n "." + sleep 2 +done +echo " " +if [ ! -e /dev/dahdi ]; then + echo + echo "Error: Dahdi device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +dahdi_cfg -v + diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/all-wcprops b/util/wancfg_zaptel/templates/hp_a100/.svn/all-wcprops new file mode 100644 index 0000000..6637447 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/all-wcprops @@ -0,0 +1,41 @@ +K 25 +svn:wc:ra_dav:version-url +V 98 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100 +END +wanpipe.hp.1 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.1 +END +wanpipe.hp.2 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.2 +END +wanpipe.hp.3 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.3 +END +wanpipe.hp.4 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.4 +END +wanpipe.hp.5 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.5 +END +wanpipe.hp.6 +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/wanpipe/!svn/ver/6522/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100/wanpipe.hp.6 +END diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/entries b/util/wancfg_zaptel/templates/hp_a100/.svn/entries new file mode 100644 index 0000000..33c0edc --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/entries @@ -0,0 +1,100 @@ +8 + +dir +6523 +http://192.168.1.168/svn/wanpipe/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/hp_a100 +http://192.168.1.168/svn/wanpipe + + + +2008-09-29T21:12:18.983268Z +6522 +jpatel + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +0135086f-934c-0410-bbf7-b457164207c2 + +wanpipe.hp.1 +file + + + + +2008-09-29T21:41:43.000000Z +8909cab26d338db7f811d5ba995b344a +2008-09-29T21:12:18.983268Z +6522 +jpatel + +wanpipe.hp.2 +file + + + + +2008-09-29T21:41:43.000000Z +06d8d7f24a480a5d6eb1a80518a42692 +2008-09-29T21:12:18.983268Z +6522 +jpatel + +wanpipe.hp.3 +file + + + + +2008-09-29T21:41:43.000000Z +7017251b80969f316a911a7cb586359b +2008-09-29T21:12:18.983268Z +6522 +jpatel + +wanpipe.hp.4 +file + + + + +2008-09-29T21:41:43.000000Z +0f9cfd71fa8d2da5e62e04e9bb91c192 +2008-09-29T21:12:18.983268Z +6522 +jpatel + +wanpipe.hp.5 +file + + + + +2008-09-29T21:41:43.000000Z +b8025314874cf0aa81652f93e2fcc93c +2008-09-29T21:12:18.983268Z +6522 +jpatel + +wanpipe.hp.6 +file + + + + +2008-09-29T21:41:43.000000Z +54310e8c43f85c689facd6b9c1140d93 +2008-09-29T21:12:18.983268Z +6522 +jpatel + diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/format b/util/wancfg_zaptel/templates/hp_a100/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/format @@ -0,0 +1 @@ +8 diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.1.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.1.svn-base new file mode 100644 index 0000000..13209b5 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.1.svn-base @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2007 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg_hq_tdmapi program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TYPE, Comment + +[interfaces] diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.2.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.2.svn-base new file mode 100644 index 0000000..480de0a --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.2.svn-base @@ -0,0 +1 @@ +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_SPAN_VOICE_API, Comment diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.3.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.3.svn-base new file mode 100644 index 0000000..510c84e --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.3.svn-base @@ -0,0 +1 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , API, Comment diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.4.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.4.svn-base new file mode 100644 index 0000000..3828274 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.4.svn-base @@ -0,0 +1,23 @@ + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 80 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_HW_DTMF = HWDTMF diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.5.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.5.svn-base new file mode 100644 index 0000000..a68b4e4 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.5.svn-base @@ -0,0 +1,7 @@ + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = CHUNKTIME +MRU = CHUNKTIME diff --git a/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.6.svn-base b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.6.svn-base new file mode 100644 index 0000000..4d9135b --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/.svn/text-base/wanpipe.hp.6.svn-base @@ -0,0 +1,4 @@ + +[wDEVNUMgSS7SIGCHAN] +HDLC_STREAMING = YES +ACTIVE_CH = SS7SIGCHAN \ No newline at end of file diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.1 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.1 new file mode 100644 index 0000000..13209b5 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.1 @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2007 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg_hq_tdmapi program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TYPE, Comment + +[interfaces] diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.2 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.2 new file mode 100644 index 0000000..480de0a --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.2 @@ -0,0 +1 @@ +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_SPAN_VOICE_API, Comment diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.3 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.3 new file mode 100644 index 0000000..510c84e --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.3 @@ -0,0 +1 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , API, Comment diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.4 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.4 new file mode 100644 index 0000000..3828274 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.4 @@ -0,0 +1,23 @@ + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 80 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_HW_DTMF = HWDTMF diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.5 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.5 new file mode 100644 index 0000000..a68b4e4 --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.5 @@ -0,0 +1,7 @@ + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = CHUNKTIME +MRU = CHUNKTIME diff --git a/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.6 b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.6 new file mode 100644 index 0000000..4d9135b --- /dev/null +++ b/util/wancfg_zaptel/templates/hp_a100/wanpipe.hp.6 @@ -0,0 +1,4 @@ + +[wDEVNUMgSS7SIGCHAN] +HDLC_STREAMING = YES +ACTIVE_CH = SS7SIGCHAN \ No newline at end of file diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/all-wcprops b/util/wancfg_zaptel/templates/ss7_a100/.svn/all-wcprops new file mode 100644 index 0000000..4d525c9 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100 +END +wanpipe.ss7.3 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.3 +END +wanpipe.ss7.4 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.4 +END +wanpipe.ss7.5 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 +END +wanpipe.ss7.6 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.6 +END +wanpipe.tdmvoiceapi.a100 +K 25 +svn:wc:ra_dav:version-url +V 124 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 +END +wanpipe.ss7.1 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.1 +END +wanpipe.ss7.2 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.2 +END diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/entries b/util/wancfg_zaptel/templates/ss7_a100/.svn/entries new file mode 100644 index 0000000..b73f782 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/entries @@ -0,0 +1,112 @@ +8 + +dir +6523 +http://192.168.1.168/svn/wanpipe/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a100 +http://192.168.1.168/svn/wanpipe + + + +2008-05-30T15:26:40.074436Z +5942 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +0135086f-934c-0410-bbf7-b457164207c2 + +wanpipe.ss7.3 +file + + + + +2008-09-29T21:41:43.000000Z +ad62cc46a6fed0b1ab958db7b41959d6 +2008-05-30T15:24:44.393525Z +5939 +ncorbic + +wanpipe.ss7.4 +file + + + + +2008-09-29T21:41:43.000000Z +37fbbda6592fe7135e5252d27f4ab09a +2008-05-30T15:24:57.978559Z +5940 +ncorbic + +wanpipe.ss7.5 +file + + + + +2008-09-29T21:41:43.000000Z +c814e301ff10d67f3e44e7840a4ade2b +2008-05-30T15:26:32.330142Z +5941 +ncorbic + +wanpipe.ss7.6 +file + + + + +2008-09-29T21:41:43.000000Z +246fe0251da34c7255eae559310bbcf7 +2008-05-30T15:26:40.074436Z +5942 +ncorbic + +wanpipe.tdmvoiceapi.a100 +file + + + + +2008-09-29T21:41:43.000000Z +7d032649d18a235b593575ebac38471c +2007-12-17T21:48:07.000000Z +5184 +sangoma + +wanpipe.ss7.1 +file + + + + +2008-09-29T21:41:43.000000Z +ee999444751be93ca4412152de1339d9 +2007-06-14T18:18:13.000000Z +4519 +sangoma + +wanpipe.ss7.2 +file + + + + +2008-09-29T21:41:43.000000Z +626f92d682491cb85766430508250ba1 +2008-05-30T15:24:33.908166Z +5938 +ncorbic + diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/format b/util/wancfg_zaptel/templates/ss7_a100/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/format @@ -0,0 +1 @@ +8 diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.1.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.1.svn-base new file mode 100644 index 0000000..01adec1 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.1.svn-base @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2007 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.2.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.2.svn-base new file mode 100644 index 0000000..6c519b6 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.2.svn-base @@ -0,0 +1,3 @@ + +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_VOICE_API, Comment + diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.3.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.3.svn-base new file mode 100644 index 0000000..f4d9693 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.3.svn-base @@ -0,0 +1,2 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , XMTP2_API, Comment + diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.4.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.4.svn-base new file mode 100644 index 0000000..a5dedc8 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.4.svn-base @@ -0,0 +1,21 @@ +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 80 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.5.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.5.svn-base new file mode 100644 index 0000000..12c3acc --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.5.svn-base @@ -0,0 +1,10 @@ +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 + diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.6.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.6.svn-base new file mode 100644 index 0000000..0091b63 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.ss7.6.svn-base @@ -0,0 +1,9 @@ + +[wDEVNUMgSS7SIGCHAN] +HDLC_STREAMING = NO +ACTIVE_CH = SS7SIGCHAN +MTU = 80 +MRU = 80 +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +TRUE_ENCODING_TYPE = NO diff --git a/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.tdmvoiceapi.a100.svn-base b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.tdmvoiceapi.a100.svn-base new file mode 100644 index 0000000..52155c4 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a100/.svn/text-base/wanpipe.tdmvoiceapi.a100.svn-base @@ -0,0 +1,52 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/all-wcprops b/util/wancfg_zaptel/templates/ss7_a10u/.svn/all-wcprops new file mode 100644 index 0000000..630cfc3 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u +END +wanpipe.ss7.3 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.3 +END +wanpipe.ss7.4 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.4 +END +wanpipe.ss7.5 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 +END +wanpipe.ss7.6 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.6 +END +wanpipe.tdmvoiceapi.a10u +K 25 +svn:wc:ra_dav:version-url +V 124 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u +END +wanpipe.ss7.1 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.1 +END +wanpipe.ss7.2 +K 25 +svn:wc:ra_dav:version-url +V 113 +/svn/wanpipe/!svn/ver/5952/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.2 +END diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/entries b/util/wancfg_zaptel/templates/ss7_a10u/.svn/entries new file mode 100644 index 0000000..d436bb5 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/entries @@ -0,0 +1,112 @@ +8 + +dir +6523 +http://192.168.1.168/svn/wanpipe/wanpipe_common/branches/jpatel/wantools/wancfg_zaptel/templates/ss7_a10u +http://192.168.1.168/svn/wanpipe + + + +2008-05-30T15:27:21.335648Z +5944 +ncorbic + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +0135086f-934c-0410-bbf7-b457164207c2 + +wanpipe.ss7.3 +file + + + + +2008-09-29T21:41:43.000000Z +1f7f45980cd09ed875e27a9f28d1765a +2008-05-30T15:27:11.421574Z +5943 +ncorbic + +wanpipe.ss7.4 +file + + + + +2008-09-29T21:41:43.000000Z +afa1320703076b11f05afb32a64e643d +2007-06-14T18:18:13.000000Z +4519 +sangoma + +wanpipe.ss7.5 +file + + + + +2008-09-29T21:41:43.000000Z +827ec1983c9860e4b89841f29f0cc99f +2007-11-21T22:45:01.000000Z +5065 +sangoma + +wanpipe.ss7.6 +file + + + + +2008-09-29T21:41:43.000000Z +246fe0251da34c7255eae559310bbcf7 +2008-05-30T15:27:21.335648Z +5944 +ncorbic + +wanpipe.tdmvoiceapi.a10u +file + + + + +2008-09-29T21:41:43.000000Z +7af16b27e6191abf763c410cce4e1248 +2007-11-21T22:45:01.000000Z +5065 +sangoma + +wanpipe.ss7.1 +file + + + + +2008-09-29T21:41:43.000000Z +8f66b47a6b9d001fc1e632aa4fd8f8ac +2007-06-14T18:18:13.000000Z +4519 +sangoma + +wanpipe.ss7.2 +file + + + + +2008-09-29T21:41:43.000000Z +1dc0228dda627e4adc5965fc242f0c2d +2007-06-25T18:38:53.000000Z +4551 +sangoma + diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/format b/util/wancfg_zaptel/templates/ss7_a10u/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/format @@ -0,0 +1 @@ +8 diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.1.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.1.svn-base new file mode 100644 index 0000000..09bc65b --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.1.svn-base @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2006 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.2.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.2.svn-base new file mode 100644 index 0000000..7c9f79e --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.2.svn-base @@ -0,0 +1,2 @@ +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_VOICE_API, Comment + diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.3.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.3.svn-base new file mode 100644 index 0000000..0d79d3c --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.3.svn-base @@ -0,0 +1,3 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , XMTP2_API, Comment + + diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.4.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.4.svn-base new file mode 100644 index 0000000..6ee7b3b --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.4.svn-base @@ -0,0 +1,20 @@ +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.5.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.5.svn-base new file mode 100644 index 0000000..1cf9c93 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.5.svn-base @@ -0,0 +1,9 @@ +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +MTU = 80 + diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.6.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.6.svn-base new file mode 100644 index 0000000..0091b63 --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.ss7.6.svn-base @@ -0,0 +1,9 @@ + +[wDEVNUMgSS7SIGCHAN] +HDLC_STREAMING = NO +ACTIVE_CH = SS7SIGCHAN +MTU = 80 +MRU = 80 +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +TRUE_ENCODING_TYPE = NO diff --git a/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.tdmvoiceapi.a10u.svn-base b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.tdmvoiceapi.a10u.svn-base new file mode 100644 index 0000000..379d36e --- /dev/null +++ b/util/wancfg_zaptel/templates/ss7_a10u/.svn/text-base/wanpipe.tdmvoiceapi.a10u.svn-base @@ -0,0 +1,50 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +MTU = 80 diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a10u b/util/wancfg_zaptel/templates/wanpipe.tdm.a10u index 24f3256..c9c18bf 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a10u +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a10u @@ -18,7 +18,7 @@ wanpipeDEVNUM = WAN_AFT, Comment [interfaces] -wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_OP_MODE, Comment [wanpipeDEVNUM] CARD_TYPE = AFT diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 index 700ab5a..ef9067f 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 @@ -18,7 +18,7 @@ wanpipeDEVNUM = WAN_AFT_ANALOG, Comment [interfaces] -wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment +wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_OP_MODE, Comment [wanpipeDEVNUM] CARD_TYPE = AFT @@ -42,5 +42,6 @@ TDMV_HW_DTMF = HWDTMF [wIFNUMg1] ACTIVE_CH = ALL +MTU = 8 TDMV_ECHO_OFF = NO TDMV_HWEC = HWECMODE diff --git a/util/wancfg_zaptel/templates/zapata.conf b/util/wancfg_zaptel/templates/zapata.conf index 051f98f..af3ec8c 100644 --- a/util/wancfg_zaptel/templates/zapata.conf +++ b/util/wancfg_zaptel/templates/zapata.conf @@ -1,7 +1,7 @@ -;autogenerated by /usr/local/sbin/config-zaptel do not hand edit -;Zaptel Channels Configurations (zapata.conf) -; -;For detailed zapata options, view /etc/asterisk/zapata.conf.orig +;autogenerated by /usr/sbin/WANCFG_CONFIG do not hand edit +;autogenrated on DATE +;ZAPATA_STRING Channels Configurations +;For detailed ZAPATA_STRING options, view LOCATION.bak [trunkgroups] @@ -25,5 +25,4 @@ txgain=0.0 group=1 callgroup=1 pickupgroup=1 - immediate=no diff --git a/util/wancfg_zaptel/templates/zaptel.conf b/util/wancfg_zaptel/templates/zaptel.conf index 63741b7..68fd39f 100644 --- a/util/wancfg_zaptel/templates/zaptel.conf +++ b/util/wancfg_zaptel/templates/zaptel.conf @@ -1,5 +1,6 @@ -# Autogenerated by /usr/local/sbin/sangoma/setup-sangoma -- do not hand edit -# Zaptel Channels Configurations (zaptel.conf) -# +#autogenerated by /usr/sbin/WANCFG_CONFIG do not hand edit +#autogenrated on DATE +#ZAPATA_STRING Channels Configurations +#For detailed ZAPATA_STRING options, view LOCATION.bak loadzone=us defaultzone=us diff --git a/util/wancfg_zaptel/wancfg_dahdi b/util/wancfg_zaptel/wancfg_dahdi new file mode 100755 index 0000000..239eaca --- /dev/null +++ b/util/wancfg_zaptel/wancfg_dahdi @@ -0,0 +1,51 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_BASE $ARGS +cd $home diff --git a/util/wancfg_zaptel/wancfg_hp_tdmapi b/util/wancfg_zaptel/wancfg_hp_tdmapi new file mode 100755 index 0000000..c8bda84 --- /dev/null +++ b/util/wancfg_zaptel/wancfg_hp_tdmapi @@ -0,0 +1,52 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --hp_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 88c180b..88deef3 100755 --- a/util/wancfg_zaptel/wancfg_zaptel.pl +++ b/util/wancfg_zaptel/wancfg_zaptel.pl @@ -1,14 +1,21 @@ #!/usr/bin/perl # config-zaptel.pl -# Sangoma Zaptel/TDM API/SMG Configuration Script. +# Sangoma Dahdi/Zaptel/TDM API/SMG Configuration Script. # -# Copyright (c) 2006, Sangoma Technologies Inc. +# Copyright (c) 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. # ---------------------------------------------------------------------------- +# Oct 07 2008 2.21 Jignesh Patel Dahdi Soft-EC conf support for Analog & A101/2 cards +# Sep 30 2008 2.20 Jignesh Patel Configuration Support for Dahdi +# Aug 20 2008 2.19 Jignesh Patel Suppor for HP TDM API for A10x added hp_a100 +# Update A10x.pm-for SH and old a101/2cards +# Aug 1 2008 2.17 Jignesh Patel Support for Analog & a101/2 card for wancfg_tdmapi +# Update A10u.pm,A20x.pm,wanpipe.tdm.a10u/a200 +# Jul 22 2008 2.17 Jignesh Patel Support for FreeBSD ztcfg path # Jun 6 2008 2.16 Jignesh Patel Added Zaptel Timer option for a500 cards # May 28 2008 2.15 Jignesh Patel Minor d-chan update for FreeBSD- A10x.pm update # May 27 2008 2.14 Jignesh Patel Added XMPT2 only option for SS7 @@ -36,8 +43,9 @@ system('clear'); print "\n########################################################################"; -print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; -print "\n# v2.16 #"; +print "\n# Sangoma Wanpipe #"; +print "\n# Dahdi/Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; +print "\n# v2.21 #"; print "\n# Sangoma Technologies Inc. #"; print "\n# Copyright(c) 2008. #"; print "\n########################################################################\n\n"; @@ -52,6 +60,7 @@ use A20x; use A50x; + my $FALSE = 1; my $TRUE = 0; my $zaptelprobe=' '; @@ -72,7 +81,7 @@ if ($os_type_list =~ m/Linux/){ $rc_dir=$etc_dir; $module_load="modprobe"; $module_unload="modprobe -r"; - $module_list="modprobe -l"; + $module_list="lsmod"; $include_dir="/usr/include"; }elsif ($os_type_list =~ m/FreeBSD/){ $os_type_name="FreeBSD"; @@ -116,7 +125,7 @@ my $max_chans=0; my $ss7_tdmvoicechans=''; my $ss7_array_length=0; - +my $ztcfg_path=''; my $device_has_hwec=$FALSE; my $device_has_normal_clock=$FALSE; @@ -125,6 +134,7 @@ my @woomera_groups=("0"); my $bri_device_has_master_clock=$FALSE; my $is_tdm_api=$FALSE; +my $is_hp_tdm_api=$FALSE; my $def_femedia=''; my $def_feframe=''; @@ -202,11 +212,18 @@ my $silent = $FALSE; my $config_zaptel = $TRUE; my $config_zapata = $TRUE; my $is_smg = $FALSE; +my $silent_zapata_conf_file = $FALSE; my $tdm_api_span_num=0; my $zaptel_installed=$FALSE; +my $dahdi_installed=$FALSE; my $modprobe_list=`$module_list`; my $is_ss7_xmpt2_only = $FALSE; +my $zaptel_dahdi_installed=$FALSE; +my $dahdi_echo='mg2'; + +my $def_chunk_size=40; +my $def_mtu_mru=' '; read_args(); @@ -231,6 +248,7 @@ unless ( -d $curdircfg ) { my $debug_info_file="$current_dir/$cfg_dir/debug_info"; my @hwprobe=`wanrouter hwprobe verbose`; +check_dahdi(); check_zaptel(); my $wanpipe_conf_dir="$etc_dir/wanpipe"; my $asterisk_conf_dir="$etc_dir/asterisk"; @@ -244,6 +262,29 @@ 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 $zaptel_string="Zaptel"; +my $zapata_string="Zapata"; +my $wancfg_config="wancfg_zaptel"; +my $zaptel_boot = "zaptel"; +my $zaptel_cfg_script="zaptel_cfg_script"; +my $zap_cfg = "ztcfg"; +my $zap_com ="zap"; + +if ($dahdi_installed== $TRUE) { + $zapata_conf_file_t="$asterisk_conf_dir/chan_dahdi.conf"; + $zaptel_conf_file_t="$etc_dir/dahdi/system.conf"; + $zaptel_string="Dahdi"; + $dchan_str="hardhdlc"; + $zapata_string="Chan-Dahdi"; + $wancfg_config="wancfg_dahdi"; + $zaptel_boot="dahdi"; + $zaptel_cfg_script="dahdi_cfg_script"; + $zap_cfg="dahdi_cfg"; + $zap_com="dahdi"; + +} + + my $bri_conf_template="$current_dir/templates/smg_bri.conf"; my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; @@ -256,9 +297,20 @@ my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; my $date=`date +%F`; chomp($date); my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; -if( $zaptel_installed==$TRUE && $os_type_list =~ m/Linux/ ){ +if( $zaptel_installed==$TRUE || $dahdi_installed==$TRUE ) { + $zaptel_dahdi_installed=$TRUE; +} + +if ($os_type_list =~ m/FreeBSD/ && $zaptel_dahdi_installed==$TRUE) { + parse_wanrouter_rc(); + update_zaptel_cfg_script(); +} + +if( $zaptel_installed==$TRUE && $os_type_list =~ m/Linux/ ) { set_zaptel_hwhdlc(); } + + prepare_files(); config_t1e1(); config_bri(); @@ -399,15 +451,15 @@ sub config_boot_linux{ return 1; } } - - if($zaptel_installed==$TRUE){ - print "Verifying Zaptel boot scripts..."; - #find zaptel start scripts - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + print "Verifying $zaptel_string boot scripts..."; + if($zaptel_dahdi_installed==$TRUE){ + print "Verifying $zaptel_string boot scripts..."; + #find zaptel/dahdi start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*$zaptel_boot >/dev/null 2>/dev/null"; if (system($command) == 0){ - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $command="find $rc_dir/rc".$current_run_level.".d/*$zaptel_boot"; $res=`$command`; - if ($res =~ /.*S(\d+)zaptel/){ + if ($res =~ /.*S(\d+)$zaptel_boot/){ $zaptel_start_level=$1; print "Enabled (level:$zaptel_start_level)\n"; } else { @@ -419,12 +471,12 @@ sub config_boot_linux{ } #find zaptel stop scripts - print "Verifying Zaptel shutdown scripts..."; - $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + print "Verifying $zaptel_string shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*$zaptel_boot >/dev/null 2>/dev/null"; if (system($command) == 0){ - $command="find ".$rc_dir."/rc6.d/*zaptel"; + $command="find ".$rc_dir."/rc6.d/*$zaptel_boot"; $res=`$command`; - if ($res =~ /.*K(\d+)zaptel/){ + if ($res =~ /.*K(\d+)$zaptel_boot/){ $zaptel_stop_level=$1; print "Enabled (level:$zaptel_stop_level)\n"; } else { @@ -538,18 +590,21 @@ sub config_boot_linux{ sub config_ztcfg_start{ + if ($num_zaptel_config ==0 || $silent==$TRUE){ return; } - my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + my $command="find /etc/rc?.d/*$zaptel_boot >/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"); + #Zaptel/Dahdi init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'$zap_cfg\' each time wanrouter starts?\n"); if (&prompt_user_list("YES","NO","") eq 'YES'){ if ( ! -d "$wanpipe_conf_dir/scripts" ) { exec_command("mkdir -p $wanpipe_conf_dir/scripts"); } - exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + + exec_command("cp -f $current_dir/templates/$zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } } } @@ -598,11 +653,20 @@ sub config_smg_ctrl_start{ } sub check_zaptel{ - if ((system("lsmod | grep zaptel > /dev/null 2> /dev/null")) == 0) { + + if ((system("$module_list | grep zaptel > /dev/null 2> /dev/null")) == 0){ $zaptel_installed=$TRUE; } } +sub check_dahdi +{ + + if ((system("$module_list | grep dahdi > /dev/null 2> /dev/null")) == 0){ + $dahdi_installed=$TRUE; + } +} + sub apply_changes{ my $asterisk_command=''; my $bri_command=''; @@ -613,13 +677,13 @@ sub apply_changes{ if($silent==$TRUE){ $res="Stop now"; - }elsif($is_tdm_api==$TRUE){ + }elsif($is_tdm_api==$TRUE || $is_hp_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"; + print "\n$zaptel_string 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", @@ -647,7 +711,7 @@ sub apply_changes{ if ($is_trixbox==$TRUE){ exec_command("amportal stop"); - } elsif ($is_tdm_api==$FALSE ){ + } elsif ($is_tdm_api==$FALSE || $is_hp_tdm_api==$FALSE ){ if (`(pidof asterisk)` != 0 ){ print "\nStopping Asterisk...\n"; exec_command("asterisk -rx \"$asterisk_command\""); @@ -691,9 +755,9 @@ sub apply_changes{ print "\nStopping Wanpipe...\n"; exec_command("wanrouter stop all"); - if ($zaptel_installed==$TRUE){ - if($is_tdm_api==$FALSE){ - print "\nUnloading Zaptel modules...\n"; + if ($zaptel_dahdi_installed==$TRUE){ + if($is_tdm_api==$FALSE || $is_hp_tdm_api==$FALSE){ + print "\nUnloading $zaptel_string modules...\n"; unload_zap_modules(); } } @@ -711,11 +775,10 @@ sub apply_changes{ exec_command("cp -f $bri_conf_file $bri_conf_file_t"); exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); } - - if ($zaptel_installed==$TRUE){ + if ($zaptel_dahdi_installed==$TRUE){ if($config_zaptel==$TRUE){ if ($num_zaptel_config !=0){ - print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + print "\nCopying new $zaptel_string configuration file ($zaptel_conf_file_t)...\n"; exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); } } @@ -723,12 +786,12 @@ sub apply_changes{ if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ if ($num_zaptel_config !=0){ - print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + print "\nCopying new $zapata_string 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){ + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE && $is_hp_tdm_api==$FALSE ){ print "\nStarting Wanpipe...\n"; exec_command("wanrouter start"); @@ -739,10 +802,13 @@ sub apply_changes{ } if ($num_zaptel_config != 0){ - print "Loading Zaptel...\n"; + print "Loading $zaptel_string...\n"; sleep 2; - exec_command("ztcfg -v"); -# } + if ($zaptel_installed==$TRUE){ + exec_command("$ztcfg_path\ztcfg -v"); + }else{ + exec_command("dahdi_cfg -v"); + } } if ($is_trixbox==$TRUE){ print "\nStarting Amportal...\n"; @@ -756,7 +822,7 @@ sub apply_changes{ if ($num_zaptel_config != 0){ print "\nListing Asterisk channels...\n\n"; - exec_command("asterisk -rx \"zap show channels\""); + exec_command("asterisk -rx \"$zap_com show channels\""); } print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; }else{ @@ -925,16 +991,58 @@ sub gen_wanrouter_rc{ close (FH); } +sub update_zapata_template{ + #update comments for zapata.conf or chan_dahdi.conf + my $zapfile=""; + if (!open (FH,"$zapata_conf_file")) { + printf("Unable to modify $zapata_conf_file\n"); + + } + while () { + $zapfile .= $_; + } + close (FH); + open (FH,">$zapata_conf_file"); + $zapfile =~ s/ZAPATA_STRING/$zaptel_string/g; + $zapfile =~ s/LOCATION/$zapata_conf_file_t/g; + $zapfile =~ s/WANCFG_CONFIG/$wancfg_config/g; + $zapfile =~ s/DATE/$date/g; + print FH $zapfile; + close (FH); +} + + +sub update_zaptel_template{ + #update coments forzaptel.conf or chan_dahdi.conf + my $zapfile=""; + if (!open (FH,"$zaptel_conf_file")) { + printf("Unable to modify $zaptel_conf_file\n"); + + } + while () { + $zapfile .= $_; + } + close (FH); + open (FH,">$zaptel_conf_file"); + $zapfile =~ s/ZAPATA_STRING/$zaptel_string/g; + $zapfile =~ s/LOCATION/$zaptel_conf_file_t/g; + $zapfile =~ s/WANCFG_CONFIG/$wancfg_config/g; + $zapfile =~ s/DATE/$date/g; + print FH $zapfile; + close (FH); +} + + sub prepare_files{ - if ($is_trixbox==$TRUE){ + if ($is_trixbox==$TRUE || ($silent_zapata_conf_file==$TRUE && $silent==$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){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE && $is_hp_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; @@ -956,6 +1064,41 @@ sub prepare_files{ if ( -f $zapata_conf_file_t ) { exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); } + +} +sub parse_wanrouter_rc +{ + #Set ztcfg_path based on $etc_dir/wanpipe/wanrouter.rc + if ( -f "$etc_dir/wanpipe/wanrouter.rc" ) { + my $line= `cat $etc_dir/wanpipe/wanrouter.rc | grep ZAPTEL_BIN_DIR`; + chop($line); + { + my @parts = split(/=/,$line); + $ztcfg_path="$parts[1]\/"; + } + #Use this wanrouter.rc as new template + my $command="cp -f $etc_dir/wanpipe/wanrouter.rc $current_dir/templates/wanrouter.rc.template.new > /dev/null 2>/dev/null "; + $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template.new"; + + } + +} + +sub update_zaptel_cfg_script(){ + + #update zaptel_cfg_script based on ztcfg_path + + my $sscript =""; + open (FH,"$current_dir/templates/$zaptel_cfg_script"); + + while () { + $sscript .= $_; + } + close (FH); + open (FH,">$current_dir/templates/$zaptel_cfg_script"); + $sscript =~ s/.*ztcfg.*/$ztcfg_path\ztcfg -v/; + print FH $sscript; + close (FH); } sub clean_files{ @@ -986,7 +1129,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","opvxa1200", "dahdi_dummy" ,"dahdi_echocan_mg2", "dahdi", "zaptel"); foreach my $module (@modules_list) { if ($modprobe_list =~ m/$module /){ exec_command("$module_unload $module"); @@ -1019,6 +1162,7 @@ sub summary{ }else{ if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ write_zaptel_conf(); + update_zaptel_template(); } if ($num_bri_devices != 0 ){ write_bri_conf(); @@ -1026,6 +1170,8 @@ sub summary{ } if ($num_zaptel_config != 0 && $config_zapata==$TRUE){ write_zapata_conf(); + update_zapata_template(); + } save_debug_info(); if ($silent==$FALSE) {system('clear')}; @@ -1037,7 +1183,7 @@ sub summary{ print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - + print "\nConfigurator will create the following files:\n"; print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; $file_list++; @@ -1048,11 +1194,11 @@ sub summary{ } if ($num_zaptel_config != 0){ - print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + print "\t$file_list. $zaptel_string 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"; + print "\t$file_list. $zapata_string config file $zapata_conf_file_t\n"; } if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ @@ -1173,6 +1319,8 @@ sub read_args { $is_tdm_api=$TRUE; }elsif ( /^--smg$/){ $is_smg=$TRUE; + }elsif ( /^--hp_tdm_api/){ + $is_hp_tdm_api=$TRUE; }elsif ( /^--no_boot$/){ $no_boot=$TRUE; }elsif ( /^--no_hwdtmf$/){ @@ -1318,6 +1466,9 @@ sub read_args { printf("Error: directory $1 does not exist\n"); exit(1); } + }elsif ( $_ =~/--zapata_auto_conf/){ + $silent_zapata_conf_file=$TRUE; + }else { printf("Error: Unrecognized parameter \"$_\" \n"); exit(1); @@ -1344,7 +1495,7 @@ sub read_args { if ($is_smg==$TRUE){ print "\nGenerating configuration files for Sangoma Media Gateway\n"; } - if ($is_tdm_api==$TRUE){ + if ($is_tdm_api==$TRUE | $is_hp_tdm_api==$TRUE){ $config_zapata = $FALSE; } @@ -1946,6 +2097,12 @@ sub config_t1e1{ $card->fe_cpu($5); my $hwec=0; + + if($dahdi_installed == $TRUE) { + $card->dahdi_conf('YES'); + $card->dahdi_echo($dahdi_echo) + } + if ( $dev =~ /HWEC=(\d+)/){ if($1 gt 0){ $hwec=1; @@ -1958,6 +2115,7 @@ sub config_t1e1{ $card->hwec_mode('NO'); }else{ $card->hwec_mode('YES'); + } my $port=$6; if ($6 eq 'PRI') { @@ -2016,8 +2174,18 @@ sub config_t1e1{ $cfg_string.="wanpipe$devnum "; my $a10x; - if ($1 !~ m/104/ && $2 !~ m/SH/) { - $a10x = eval {new A10u(); } or die ($@); + if ($1 !~ m/104/ && $2 !~ m/SH/) { + + if($is_hp_tdm_api == $TRUE){ + #hp_tdm_api uses same templates:) + $a10x = eval {new A10x(); } or die ($@); + $a10x->old_a10u("YES"); + + }else{ + + $a10x = eval {new A10u(); } or die ($@); + #$a10x->card($card); + } $a10x->card($card); if ($5 eq "A") { $a10x->fe_line("1"); @@ -2126,21 +2294,7 @@ sub config_t1e1{ # $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); } - if ($def_signalling eq 'TDM API'){ - printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); - my @options=("CCS","CAS"); - $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); - } elsif ($def_signalling eq 'PRI CPE' | - $def_signalling eq 'PRI NET' | - $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| - $def_signalling eq 'No Signaling (Voice Only)'){ - - $def_te_sig_mode="CCS"; - } else { - $def_te_sig_mode="CAS"; - } - - + } else { if($#silent_felcodes >= 0){ $silent_felcode=pop(@silent_felcodes); @@ -2214,17 +2368,19 @@ sub config_t1e1{ my @options=""; - if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + if ($is_smg==$TRUE && $zaptel_dahdi_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){ + } elsif ($is_smg==$TRUE && $zaptel_dahdi_installed==$FALSE){ @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); } elsif ($is_tdm_api==$TRUE){ $def_signalling="TDM API"; + } elsif ($is_hp_tdm_api==$TRUE){ + $def_signalling="HPTDM 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){ + if( $is_tdm_api == $FALSE && $is_hp_tdm_api == $FALSE ){ printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); $def_signalling=&prompt_user_list(@options,$def_signalling); } @@ -2232,26 +2388,32 @@ sub config_t1e1{ if($#silent_signallings >= 0){ $silent_signalling=pop(@silent_signallings); } - $def_signalling=$silent_signalling; + if($is_tdm_api == $TRUE){ + $def_signalling="TDM API"; + } elsif ($is_hp_tdm_api == $TRUE){ + $def_signalling="HPTDM API"; + } 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"; + if ($fe_media eq 'E1') { + if (($def_signalling eq 'TDM API' ||$def_signalling eq 'HPTDM API') & $silent==$FALSE){ + 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); } - $a10x->te_sig_mode($def_te_sig_mode); - my $ss7_chan; my $ss7_group_start; my $ss7_group_end; @@ -2364,6 +2526,51 @@ ENDSS7CONFIG: $card->tdmv_span_no($current_tdmapi_span); $startup_string.="wanpipe$devnum "; $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'HPTDM API'){ + $a10x->hp_option(1); + + @options = ("160","80", "40"); + + if ($silent==$FALSE){ + printf ("Select Chunk Size for AFT-A%s on port %s [slot:%s bus:%s]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_chunk_size=&prompt_user_list(@options,$def_chunk_size); + } + + my @options=""; + + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + @ss7_chan_array=&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media); + + } + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + 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); + #wanrouter start/stop for signalling span is controlled by ss7boxd + $startup_string.="wanpipe$devnum "; + + + + if ($ss7_sorted[0]==0) { + $def_mtu_mru=$def_chunk_size*$max_chans; + }else{ + my $no_chans = $max_chans - 1; + $def_mtu_mru=$def_chunk_size*($no_chans); + + } + $a10x->mtu_mru($def_mtu_mru); + }else{ $num_zaptel_config++; $card->tdmv_span_no($current_zap_span); @@ -2371,8 +2578,6 @@ ENDSS7CONFIG: $current_zap_span++; $current_zap_channel+=$max_chans; } - - if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ if ($silent==$FALSE && $config_zapata==$TRUE){ @@ -2386,7 +2591,7 @@ ENDSS7CONFIG: $a10x->pri_switchtype($silent_pri_switchtype); } } - + #wanpipe gen section if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ $a10x->ss7_subinterface(1); $a10x->gen_wanpipe_ss7_subinterfaces(); @@ -2415,7 +2620,47 @@ ENDSS7CONFIG: $a10x->ss7_sigchan($ss7_element); $a10x->ss7_subinterface(6); $a10x->gen_wanpipe_ss7_subinterfaces(); - } + } + }elsif ($a10x->signalling =~ m/HPTDM/){ + + $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){ + if ($ss7_element != 0) { + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + } + + #$a10x->gen_wanpipe_conf(); + if ($os_type_list =~ m/FreeBSD/){ + $a10x->gen_wanpipe_conf(1); + } else { + $a10x->gen_wanpipe_conf(0); + } + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + printf("@ss7_sorted\n"); + prompt_user("Press any key to continue"); + + if (@ss7_sorted != 0) { + foreach $ss7_element (@ss7_sorted){ + if ($ss7_element != 0) { + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + } + } }else{ if ($os_type_list =~ m/FreeBSD/){ $a10x->gen_wanpipe_conf(1); @@ -2470,7 +2715,7 @@ ENDSS7CONFIG: $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){ + }elsif ($is_tdm_api == $FALSE && $is_hp_tdm_api == $FALSE ){ $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); } $devnum++; @@ -2503,10 +2748,9 @@ ENDSS7CONFIG: sub config_analog{ - if($is_tdm_api==$TRUE){ - return; - } + my $a20x; + if (!$first_cfg && $silent==$FALSE) { system('clear'); } @@ -2516,9 +2760,12 @@ sub config_analog{ print "------------------------------------\n"; my $skip_card=$FALSE; - $zaptel_conf.="\n"; - $zapata_conf.="\n"; + if($is_tdm_api == $FALSE && $is_hp_tdm_api == $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 ($@); @@ -2530,11 +2777,16 @@ sub config_analog{ $card->pci_bus($4); $card->fe_cpu($5); my $hwec=$7; + if($dahdi_installed == $TRUE) { + $card->dahdi_conf('YES'); + $card->dahdi_echo($dahdi_echo) + } 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++; @@ -2557,7 +2809,7 @@ sub config_analog{ $a20x = eval {new A20x(); } or die ($@); $a20x->card($card); $card->first_chan($current_zap_channel); - + if ( $device_has_hwec==$TRUE && $silent==$FALSE){ print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; print "\n WARNING: for hardware and firmware requirements, check:\n"; @@ -2569,7 +2821,7 @@ sub config_analog{ $a20x->rm_network_sync('YES'); } } - + if ($silent==$FALSE){ if ($card->hwec_mode eq "YES"){ $card->hw_dtmf(&prompt_hw_dtmf()); @@ -2597,38 +2849,42 @@ sub config_analog{ $a20x->tdm_law($silent_tdm_law); } - - - print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; - $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; - $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; $cfg_string.="wanpipe$devnum "; if($silent==$FALSE){ prompt_user("Press any key to continue"); } - - $current_zap_channel+=24; my $i; - $devnum++; - $num_analog_devices++; - $num_zaptel_config++; - $card->tdmv_span_no($current_zap_span); - $current_zap_span++; -# $a20x->gen_wanpipe_conf(); + if( $is_tdm_api == $FALSE) { + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $current_zap_channel+=24; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + }else{ + print "A$1 configured on slot:$3 bus:$4 span:$current_tdmapi_span\n"; + $a20x->is_tdm_api($TRUE); + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + } + $devnum++; + $num_analog_devices++; if ($os_type_list =~ m/FreeBSD/){ $a20x->gen_wanpipe_conf(1); } else { $a20x->gen_wanpipe_conf(0); } - + }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){ + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE & $is_tdm_api==$FALSE){ my $zap_pos = $1+$current_zap_channel-25; if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ if($#silent_zapata_contexts >= 0){ @@ -2641,7 +2897,7 @@ sub config_analog{ $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){ + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE & $is_tdm_api==$FALSE ){ my $zap_pos = $1+$current_zap_channel-25; if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ if($#silent_zapata_contexts >= 0){ @@ -2667,9 +2923,9 @@ sub config_analog{ sub config_tdmv_dummy { my $command=''; - if( $num_digital_devices == 0 && $num_analog_devices == 0 && $num_bri_devices !=0 && $zaptel_installed==$TRUE && $os_type_list =~ m/Linux/ && $silent == $FALSE ){ + if( $num_digital_devices == 0 && $num_analog_devices == 0 && $num_bri_devices !=0 && $zaptel_dahdi_installed==$TRUE && $os_type_list =~ m/Linux/ && $silent == $FALSE ){ system('clear'); - print("Would you like to configure A500 BRI card as timing source for Zaptel?\n"); + print("Would you like to configure A500 BRI card as timing source for $zaptel_string?\n"); print("(Visit http://wiki.sangoma.com/wanpipe-linux-asterisk-appendix#bri-tdmv for more information)\n"); if(&prompt_user_list("YES", "NO" ,"") =~ m/YES/){ @@ -2677,11 +2933,11 @@ sub config_tdmv_dummy $command=("sed -i -e 's/TDMV_DUMMY.*/\TDMV_DUMMY_REF = YES/' $current_dir/$cfg_dir/wanpipe1.conf"); if ( system($command) == 0){ - printf("TDMV Zaptel Timer Enabled\n"); + printf("TDMV $zaptel_string Timer Enabled\n"); prompt_user("Press any key to continue"); }else{ - printf("Failed to Enable TDMV Zaptel Timer for A500\n"); + printf("Failed to Enable TDMV $zaptel_string Timer for A500\n"); printf("Please contact Sangoma Tech Support\n"); exit 1; } @@ -2692,3 +2948,4 @@ sub config_tdmv_dummy } + diff --git a/util/wanconfig/wanconfig.c b/util/wanconfig/wanconfig.c index 8673bb2..12d68ed 100644 --- a/util/wanconfig/wanconfig.c +++ b/util/wanconfig/wanconfig.c @@ -1071,6 +1071,7 @@ key_word_t lip_hdlc_annexg_conftab[] = { "SEVEN_BIT_HDLC", smemof(wan_lip_hdlc_if_conf_t, seven_bit_hdlc), DTYPE_CHAR }, { "RX_CRC_BYTES", smemof(wan_lip_hdlc_if_conf_t, rx_crc_bytes), DTYPE_CHAR }, + { "LINEIDLE", smemof(wan_lip_hdlc_if_conf_t, lineidle), DTYPE_CHAR }, { NULL, 0, 0 } }; @@ -2525,6 +2526,7 @@ int build_chandef_list (FILE* file) ( strcmp(chandef->usedby, "BRIDGE_NODE") != 0 ) && ( strcmp(chandef->usedby, "TDM_VOICE") != 0 ) && ( strcmp(chandef->usedby, "TDM_VOICE_API") != 0 ) && + ( strcmp(chandef->usedby, "TDM_SPAN_VOICE_API") != 0 ) && ( strcmp(chandef->usedby, "TDM_API") != 0 ) && ( strcmp(chandef->usedby, "TRUNK") != 0 ) && ( strcmp(chandef->usedby, "ANNEXG") != 0 ))) diff --git a/util/wanec_apilib/wanec_api.c b/util/wanec_apilib/wanec_api.c index d1dc1f3..f4c66e9 100644 --- a/util/wanec_apilib/wanec_api.c +++ b/util/wanec_apilib/wanec_api.c @@ -89,7 +89,6 @@ extern int wanec_api_lib_cmd(wan_ec_api_t *ec_api); static int wanec_api_print_chip_stats(wan_ec_api_t *ec_api) { tPOCT6100_CHIP_STATS pChipStats; - tPOCT6100_CHIP_IMAGE_INFO pChipImageInfo; pChipStats = &ec_api->u_chip_stats.f_ChipStats; printf("****** Echo Canceller Chip Get Stats %s ******\n", @@ -135,33 +134,12 @@ static int wanec_api_print_chip_stats(wan_ec_api_t *ec_api) pChipStats->ulSoftOverflowBufferPlayoutEventsCount); printf("\n"); - if (ec_api->u_chip_stats.f_ChipImageInfo){ - pChipImageInfo = ec_api->u_chip_stats.f_ChipImageInfo; - printf("****** Echo Canceller Chip Image Info %s ******\n", - ec_api->devname); - printf("%10s: Echo Canceller chip image build description:\n%s\n", - ec_api->devname, - pChipImageInfo->szVersionNumber); - printf("%10s: Echo Canceller chip build ID\t\t\t%d\n", - ec_api->devname, - pChipImageInfo->ulBuildId); - printf("%10s: Echo Canceller image type\t\t\t\t%d\n", - ec_api->devname, - pChipImageInfo->ulImageType); - printf("%10s: Maximum number of channels supported by the image\t%d\n", - ec_api->devname, - pChipImageInfo->ulMaxChannels); - printf("\n"); - } return 0; } static int wanec_api_print_full_chip_stats(wan_ec_api_t *ec_api) { tPOCT6100_CHIP_STATS pChipStats; - tPOCT6100_CHIP_IMAGE_INFO pChipImageInfo; - tPOCT6100_CHIP_TONE_INFO pChipToneInfo; - unsigned int i; pChipStats = &ec_api->u_chip_stats.f_ChipStats; printf("****** Echo Canceller Chip Get Stats %s ******\n", @@ -211,8 +189,17 @@ static int wanec_api_print_full_chip_stats(wan_ec_api_t *ec_api) pChipStats->ulSoftOverflowBufferPlayoutEventsCount); printf("\n"); - if (ec_api->u_chip_stats.f_ChipImageInfo){ - pChipImageInfo = ec_api->u_chip_stats.f_ChipImageInfo; + return 0; +} + +static int wanec_api_print_chip_image(wan_ec_api_t *ec_api, int full) +{ + tPOCT6100_CHIP_IMAGE_INFO pChipImageInfo; + tPOCT6100_CHIP_TONE_INFO pChipToneInfo; + unsigned int i; + + if (ec_api->u_chip_image.f_ChipImageInfo){ + pChipImageInfo = ec_api->u_chip_image.f_ChipImageInfo; printf("****** Echo Canceller Chip Image Info %s ******\n", ec_api->devname); printf("%10s: Echo Canceller chip image build description:\n%s\n", @@ -227,44 +214,46 @@ static int wanec_api_print_full_chip_stats(wan_ec_api_t *ec_api) printf("%10s: Maximum number of channels supported by the image\t%d\n", ec_api->devname, pChipImageInfo->ulMaxChannels); - printf("%10s: Support Acoustic echo cancellation\t%s\n", + if (full) printf("%10s: Support Acoustic echo cancellation\t%s\n", ec_api->devname, (pChipImageInfo->fAcousticEcho == TRUE) ? "TRUE" : "FALSE"); - printf("%10s: Support configurable tail length for Aec\t%s\n", + if (full) printf("%10s: Support configurable tail length for Aec\t%s\n", ec_api->devname, (pChipImageInfo->fAecTailLength == TRUE) ? "TRUE" : "FALSE"); - printf("%10s: Support configurable default ERL\t%s\n", + if (full) printf("%10s: Support configurable default ERL\t%s\n", ec_api->devname, (pChipImageInfo->fDefaultErl == TRUE) ? "TRUE" : "FALSE"); - printf("%10s: Support configurable non-linearity A\t%s\n", + if (full) printf("%10s: Support configurable non-linearity A\t%s\n", ec_api->devname, (pChipImageInfo->fNonLinearityBehaviorA == TRUE) ? "TRUE" : "FALSE"); - printf("%10s: Support configurable non-linearity B\t%s\n", + if (full) printf("%10s: Support configurable non-linearity B\t%s\n", ec_api->devname, (pChipImageInfo->fNonLinearityBehaviorB == TRUE) ? "TRUE" : "FALSE"); - printf("%10s: Tone profile number built in the image\t%d\n", + if (full) printf("%10s: Tone profile number built in the image\t%d\n", ec_api->devname, pChipImageInfo->ulToneProfileNumber); - printf("%10s: Number of tone available in the image\t%d\n", + if (full) printf("%10s: Number of tone available in the image\t%d\n", ec_api->devname, pChipImageInfo->ulNumTonesAvailable); - for(i = 0; i < pChipImageInfo->ulNumTonesAvailable; i++){ - pChipToneInfo = &pChipImageInfo->aToneInfo[i]; - printf("%10s: \tDetection Port: %s\tToneId: 0x%X\n", - ec_api->devname, - (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_SIN)?"SIN": - (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT)?"ROUT": - (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT)?"SOUT": - (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT_SOUT)?"ROUT/SOUT": + if (full) { + for(i = 0; i < pChipImageInfo->ulNumTonesAvailable; i++){ + pChipToneInfo = &pChipImageInfo->aToneInfo[i]; + printf("%10s: \tDetection Port: %s\tToneId: 0x%X\n", + ec_api->devname, + (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_SIN)?"SIN": + (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT)?"ROUT": + (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT)?"SOUT": + (pChipToneInfo->ulDetectionPort == cOCT6100_CHANNEL_PORT_ROUT_SOUT)?"ROUT/SOUT": "INV", - pChipToneInfo->ulToneID); + pChipToneInfo->ulToneID); + } + printf("\n"); } - printf("\n"); } return 0; } @@ -962,6 +951,30 @@ int wanec_api_stats( char *devname, } +int wanec_api_hwimage( char *devname, + int verbose, + wanec_api_image_t *image) +{ + int err; + + memcpy(ec_api.devname, devname, strlen(devname)); + ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = WAN_EC_API_CMD_STATS_IMAGE; +#if 0 + ec_api.u_chip_image.f_ChipImageInfo = + malloc(sizeof(tOCT6100_CHIP_IMAGE_INFO)); + memset(ec_api.u_chip_image.f_ChipImageInfo, + 0, sizeof(tOCT6100_CHIP_IMAGE_INFO)); +#endif + err = wanec_api_lib_cmd(&ec_api); + if (err) return err; + if (ec_api.err) return 0; + + wanec_api_print_chip_image(&ec_api, 0); + return err; + +} + int wanec_api_buffer_load(char *devname, int verbose, wanec_api_bufferload_t *bufferload) diff --git a/util/wanec_apilib/wanec_api.h b/util/wanec_apilib/wanec_api.h index 5793a20..6eea7cb 100644 --- a/util/wanec_apilib/wanec_api.h +++ b/util/wanec_apilib/wanec_api.h @@ -51,6 +51,9 @@ typedef struct { int reset; int silent; } wanec_api_stats_t; +typedef struct { + int notused; +} wanec_api_image_t; typedef struct { char *buffer; unsigned char pcmlaw; @@ -86,6 +89,7 @@ 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_hwimage(char*,int,wanec_api_image_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*); diff --git a/util/wanec_client/.Makefile.Linux.swp b/util/wanec_client/.Makefile.Linux.swp new file mode 100644 index 0000000000000000000000000000000000000000..38795d955445035578981b8dd773f114f3d473d4 GIT binary patch literal 12288 zcmeI2&u<$=6vtnC0Jcy-4H6QkX=({ut#|E&5L(Gn-L;df2?;oG1d8|rfE#?rUbl8=C@MXmYDW2FXJ_7fGw(aI z>-?CV+?KV;R`ndAJWI6DzPV97dX+wWo+u20ST^6U#60qx`x&AC4H?kr@ICGY!vXhW zV_9D|t~>rv40#rHJ-?*CWQ=0r$yV;#t|z3~rgM#Vg~$KJ7|KK`pcJ@=0;9N_edRbU zFXeNm7EiK;6YYB#sV1d>Qa~x76i^B%1(X6x0i}Ra;89i}9v-1Tk>F8K0!I>XQAH`B z6i^B%1(X6x0i}RaKq;UUPzopolmbeDM??XqL-gBYL@zvngz*1=`8R-1pCO9CE_e}q z|1{CZ;0m}5jsXq)ah&K!@GZCnz64)@kH81u9pHnDAP;ij82I%mqHn<0;1>7{ybaz0 ztKj!1i9P`V@WBai`xw#B;7xD?#xB@PM1@H^< zy$yZN1%#QKq;UUPzopo{^ts4;echk45#R99HVo>o~OI? zx5jIvH=DOrOQ|Ze^)6B4Jhh>8qTWC6Sr|-{r zqHE$Q{ZeUjtx{ZXB0|7Y=UM7CHZ`4`raXrsnhn!7D^|JMk`D5&Y}ydCVqM5!4vF-& zYx*KVcuG|@ymT|l~4bv9jwmhyJ1QM4zrO-&0ddkML-Y;B2UOSWCHs_kvt zM%}Dc*Q|A0D$+JvHuiDds+a9nX>$uQO5;-bLVMjVq|)OGvMSl@)wXF9&5g}Y7w+UM zv!6~`raMj(jk61L(D|+u2fb&+8b4ZzcGI)A?7%#b>s0q-6?EOe*U*XGK97uRolxxY zFuD_#=C+JXbZ(}}>0P9OO?!B!?TH<{DaOGjyRk5N90rc?=eGO&=9llX@qSFqlVid} z-0z4kVL{3!CR8xoU@!>$$!th;`7TSJNu{p~uj4vl2Q!o?* zU_I`Ui-vrt*f2L33c6D1sL!#5M!qw^z8z#}t6pqvXydL*&BS_U&ZW|=&AL>bYV8)T zvUd=444O2{+juafQ>-2aSGgOrH5`OybtmpeI(}8by8;$FA_{yO?>5{m(N?+9v}#q< z^ElZpwL&#{)kHiV$#@q=(1F#4u?Tz_YWiT8%4=5jKR?=t#|jUzAY5_ObJ^0$8Mc(m zt!P@&3aS$SoG-pjW6vJ31_7GJq&|hs6iwXb$ literal 0 HcmV?d00001 diff --git a/util/wanec_client/Makefile.Linux b/util/wanec_client/Makefile.Linux index 6e77816..c2ad07b 100755 --- a/util/wanec_client/Makefile.Linux +++ b/util/wanec_client/Makefile.Linux @@ -17,7 +17,6 @@ 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 @@ -36,7 +35,7 @@ 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) +CFLAGS += $(INC_EC_APILIB) $(EXTRA_FLAGS) #$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api/include -I$(WANEC_DIR)/oct6100_api/octdeviceapi/oct6100api/ diff --git a/util/wanec_client/wan_ec_arg.l b/util/wanec_client/wan_ec_arg.l index f27b793..e9c175d 100644 --- a/util/wanec_client/wan_ec_arg.l +++ b/util/wanec_client/wan_ec_arg.l @@ -129,6 +129,7 @@ static struct table_args_t { {"enable", token(ENABLE_TOKEN), "Description" }, {"help", token(HELP_TOKEN), "Description" }, {"help1", token(HELP1_TOKEN), "Description" }, + {"hwimage", token(HWIMAGE_TOKEN), "Description" }, {"kill", token(KILL_TOKEN), "Description" }, {"load", token(LOAD_TOKEN), "Description" }, {"mhtf", token(MODE_HT_FREEZE_TOKEN), "Description" }, @@ -265,6 +266,7 @@ int help(int verbose) 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(" hwimage - Read Echo Canceller image statistis\n"); printf(" monitor - Enable Debug monitoring for specified channel\n"); printf(" monitor - Get debug data for previously specified channel\n"); printf("\n"); diff --git a/util/wanec_client/wan_ec_arg.y b/util/wanec_client/wan_ec_arg.y index e44b665..93843d5 100644 --- a/util/wanec_client/wan_ec_arg.y +++ b/util/wanec_client/wan_ec_arg.y @@ -43,6 +43,7 @@ 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_hwimage(int full); extern int wanec_client_bufferload(void); extern int wanec_client_bufferunload(unsigned long buffer_id); extern int wanec_client_playout(int start); @@ -79,6 +80,7 @@ extern int wanec_client_monitor(int); %token ALL_TOKEN %token HELP_TOKEN %token HELP1_TOKEN +%token HWIMAGE_TOKEN %token MONITOR_TOKEN %token MONITOR120_TOKEN %token MODIFY_TOKEN @@ -155,6 +157,8 @@ command : CONFIG_TOKEN custom_param_list { gl_err = wanec_client_stats(0); } | STATS_FULL_TOKEN stats_debug_args { gl_err = wanec_client_stats(1); } + | HWIMAGE_TOKEN + { gl_err = wanec_client_hwimage(1); } | BUFFER_LOAD_TOKEN CHAR_STRING { strcpy(ec_client.filename,$2); } buffer_load_args diff --git a/util/wanec_client/wan_ecmain.c b/util/wanec_client/wan_ecmain.c index e35b7c3..35c678e 100644 --- a/util/wanec_client/wan_ecmain.c +++ b/util/wanec_client/wan_ecmain.c @@ -234,6 +234,19 @@ int wanec_client_stats(int full) return err; } +int wanec_client_hwimage(void) +{ + wanec_api_image_t image; + int err; + + memset(&image, 0, sizeof(wanec_api_image_t)); + err = wanec_api_hwimage( + ec_client.devname, + ec_client.verbose, + &image); + return err; +} + int wanec_client_bufferload(char *buf) { wanec_api_bufferload_t bufferload; diff --git a/util/wanpipemon/Makefile b/util/wanpipemon/Makefile index 4e0f0bd..4ff49fd 100644 --- a/util/wanpipemon/Makefile +++ b/util/wanpipemon/Makefile @@ -12,7 +12,6 @@ DEBUG = 2 PROD=wanpipemon -SYSINC=/lib/modules/$(shell uname -r)/build/include WAN_VIRTUAL= LXDIR=../lxdialog @@ -27,7 +26,7 @@ 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) +CFLAGS += -D$(OS_TYPE) -I../ft1 -O2 -fomit-frame-pointer -DLOCALE -D_DEBUG_=$(DEBUG) WAN_VIRTUAL= @@ -72,7 +71,7 @@ OBJS+=$(LX_OBJ) ####### RULES ################################################################ all: $(PROD) - @echo "Ok. Using INCLUDE $(SYSINC)" + @echo "Ok." $(PROD): $(OBJS) @@ -89,7 +88,7 @@ ncurses: fi nenad: - @echo "Ok. Using INCLUDE $(SYSINC)" + @echo "Ok. " install: @echo "Installing Wanpipe utilites in $(WAN_VIRTUAL)/usr/sbin" diff --git a/util/wanpipemon/Makefile.Linux b/util/wanpipemon/Makefile.Linux index 4e0f0bd..4ff49fd 100644 --- a/util/wanpipemon/Makefile.Linux +++ b/util/wanpipemon/Makefile.Linux @@ -12,7 +12,6 @@ DEBUG = 2 PROD=wanpipemon -SYSINC=/lib/modules/$(shell uname -r)/build/include WAN_VIRTUAL= LXDIR=../lxdialog @@ -27,7 +26,7 @@ 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) +CFLAGS += -D$(OS_TYPE) -I../ft1 -O2 -fomit-frame-pointer -DLOCALE -D_DEBUG_=$(DEBUG) WAN_VIRTUAL= @@ -72,7 +71,7 @@ OBJS+=$(LX_OBJ) ####### RULES ################################################################ all: $(PROD) - @echo "Ok. Using INCLUDE $(SYSINC)" + @echo "Ok." $(PROD): $(OBJS) @@ -89,7 +88,7 @@ ncurses: fi nenad: - @echo "Ok. Using INCLUDE $(SYSINC)" + @echo "Ok. " install: @echo "Installing Wanpipe utilites in $(WAN_VIRTUAL)/usr/sbin" diff --git a/util/wanpipemon/aftpipemon.c b/util/wanpipemon/aftpipemon.c index 5465b95..526103e 100644 --- a/util/wanpipemon/aftpipemon.c +++ b/util/wanpipemon/aftpipemon.c @@ -79,6 +79,10 @@ * GLOBAL VARIABLES * *****************************************************************************/ /* The ft1_lib needs these global variables */ +extern wan_femedia_t femedia; +extern char *csudsu_menu_te1_pmc[]; +extern char *csudsu_menu_te1_dm[]; +extern char *csudsu_menu_te3[]; /****************************************************************************** * FUNCTION PROTOTYPES * @@ -168,15 +172,34 @@ 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++; + if (strcmp(cmd_name, "csudsu_menu") == 0){ + + if (femedia.media == WAN_MEDIA_T1 || femedia.media == WAN_MEDIA_E1){ + if (femedia.chip_id == WAN_TE_CHIP_PMC){ + cmd_menu = csudsu_menu_te1_pmc; + }else if (femedia.chip_id == WAN_TE_CHIP_DM){ + cmd_menu = csudsu_menu_te1_dm; + }else{ + cmd_menu = csudsu_menu; } - break; + }else if (femedia.media == WAN_MEDIA_DS3 || femedia.media == WAN_MEDIA_E3){ + cmd_menu = csudsu_menu_te3; + }else{ + cmd_menu = csudsu_menu; + } + }else{ + 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; + break; + } + i++; + } + } + if (cmd_menu){ + while (strcmp(cmd_menu[j],".") != 0){ + j++; } - i++; } *len=j/2; return cmd_menu; @@ -1130,22 +1153,26 @@ int AFTUsage(void) printf("\t T a Read T1/E1/56K alarms.\n"); printf("\t lt Diagnostic Digital Loopback testing (T1/E1 card only)\n"); printf("\t lb Read Loopback status (T1/E1 cards)\n"); - printf("\t allb Active Line/Remote Loopback mode (T1/E1/T3/E3 cards)\n"); - printf("\t dllb Deactive Line/Remote Loopback mode (T1/E1/T3/E3 cards)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1/T3/E3 cards)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1/T3/E3 cards)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1/T3/E3 cards)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1/T3/E3 cards)\n"); + printf("\t allb Active Line/Remote Loopback mode (T1/E1 cards)\n"); + printf("\t dllb Deactive Line/Remote Loopback mode (T1/E1 cards)\n"); + printf("\t aplb Active Payload Loopback mode (T1/E1 cards)\n"); + printf("\t dplb Deactive Payload Loopback mode (T1/E1 cards)\n"); + printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 cards)\n"); + printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 cards)\n"); printf("\t salb Send Loopback Activate Code (T1/E1 PMC card only)\n"); printf("\t sdlb Send Loopback Deactive Code (T1/E1 PMC card only)\n"); printf("\t alalb Active LIU Analog Loopback mode (T1/E1 DM card only)\n"); printf("\t dlalb Deactive LIU Analog Loopback mode (T1/E1 DM card only)\n"); printf("\t alllb Active LIU Local Loopback mode (T1/E1 DM card only)\n"); printf("\t dlllb Deactive LIU Local Loopback mode (T1/E1 DM card only)\n"); - printf("\t alrlb Active LIU Remote Loopback mode (T1/E1 DM card only)\n"); - printf("\t dlrlb Deactive LIU Remote Loopback mode (T1/E1 DM card only)\n"); printf("\t aldlb Active LIU Dual Loopback mode (T1/E1 DM card only)\n"); printf("\t dldlb Deactive LIU Dual Loopback mode (T1/E1 DM card only)\n"); + printf("\t allb3 Active Analog Local Loopback mode (DS3/E3 cards)\n"); + printf("\t dllb3 Deactive Analog Local Loopback mode (DS3/E3 cards)\n"); + printf("\t arlb3 Active Remote Loopback mode (DS3/E3 cards)\n"); + printf("\t drlb3 Deactive Remote Loopback mode (DS3/E3 cards)\n"); + printf("\t adlb3 Active Digital Loopback mode (DS3/E3 cards)\n"); + printf("\t ddlb3 Deactive Digital Loopback mode (DS3/E3 cards)\n"); printf("\t txe Enable TX (AFT card only)\n"); printf("\t txd Disable TX (AFT card only)\n"); printf("\tFlush Statistics\n"); @@ -1310,45 +1337,49 @@ int AFTMain(char *command,int argc, char* argv[]) }else if (!strcmp(opt,"lb")){ get_lb_modes(); }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"alalb")){ - set_lb_modes(WAN_TE1_LIU_ALB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_ALB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dlalb")){ - set_lb_modes(WAN_TE1_LIU_ALB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_ALB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"alllb")){ - set_lb_modes(WAN_TE1_LIU_LLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_LLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dlllb")){ - set_lb_modes(WAN_TE1_LIU_LLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_LLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"alrlb")){ - set_lb_modes(WAN_TE1_LIU_RLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_RLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dlrlb")){ - set_lb_modes(WAN_TE1_LIU_RLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_RLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aldlb")){ - set_lb_modes(WAN_TE1_LIU_DLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_DLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dldlb")){ - set_lb_modes(WAN_TE1_LIU_DLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aflb")){ - set_lb_modes(WAN_TE1_FR_FLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dflb")){ - set_lb_modes(WAN_TE1_FR_FLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"afplb")){ - set_lb_modes(WAN_TE1_FR_PLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dfplb")){ - set_lb_modes(WAN_TE1_FR_PLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LIU_DLB_MODE, WAN_TE1_LB_DISABLE); + }else if (!strcmp(opt,"allb3")){ + set_lb_modes(WAN_TE3_LIU_LB_ANALOG, WAN_TE3_LB_ENABLE); + }else if (!strcmp(opt,"dllb3")){ + set_lb_modes(WAN_TE3_LIU_LB_ANALOG, WAN_TE3_LB_DISABLE); + }else if (!strcmp(opt,"arlb3")){ + set_lb_modes(WAN_TE3_LIU_LB_REMOTE, WAN_TE3_LB_ENABLE); + }else if (!strcmp(opt,"drlb3")){ + set_lb_modes(WAN_TE3_LIU_LB_REMOTE, WAN_TE3_LB_DISABLE); + }else if (!strcmp(opt,"adlb3")){ + set_lb_modes(WAN_TE3_LIU_LB_DIGITAL, WAN_TE3_LB_ENABLE); + }else if (!strcmp(opt,"ddlb3")){ + set_lb_modes(WAN_TE3_LIU_LB_DIGITAL, WAN_TE3_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); }else if (!strcmp(opt,"af")){ diff --git a/util/wanpipemon/atmpipemon.c b/util/wanpipemon/atmpipemon.c index ae72448..f615c5b 100644 --- a/util/wanpipemon/atmpipemon.c +++ b/util/wanpipemon/atmpipemon.c @@ -1246,21 +1246,21 @@ int ATMMain(char *command,int argc, char* 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); } else{ diff --git a/util/wanpipemon/bpipemon.c b/util/wanpipemon/bpipemon.c index 727f9a1..dce8e20 100644 --- a/util/wanpipemon/bpipemon.c +++ b/util/wanpipemon/bpipemon.c @@ -542,21 +542,21 @@ int BITSTRMMain(char *command,int argc, char* argv[]) 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); } else{ diff --git a/util/wanpipemon/cpipemon.c b/util/wanpipemon/cpipemon.c index d822c80..a9622b3 100644 --- a/util/wanpipemon/cpipemon.c +++ b/util/wanpipemon/cpipemon.c @@ -1826,21 +1826,21 @@ set_FT1_monitor_status(0x00); }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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); } else{ diff --git a/util/wanpipemon/fe_lib.c b/util/wanpipemon/fe_lib.c index 524d78b..0a2bbaa 100644 --- a/util/wanpipemon/fe_lib.c +++ b/util/wanpipemon/fe_lib.c @@ -61,6 +61,7 @@ #endif static void hw_set_lb_modes(unsigned char type, unsigned char mode); +static int hw_get_femedia_type(wan_femedia_t*); static int hw_get_fe_type(unsigned char* adapter_type); /****************************************************************************** @@ -77,6 +78,7 @@ extern int gfail; extern FT1_LED_STATUS FT1_LED; extern int wan_protocol; extern wan_udp_hdr_t wan_udp; +extern wan_femedia_t femedia; /****************************************************************************** * GUI MENU DEFINITION * @@ -116,6 +118,65 @@ char *csudsu_menu[]={ "." }; +char *csudsu_menu_te3[]={ +"","-- DS3/E3 (AFT) Stats --", +""," ", +"Ta","Read DS3/E3 alarms", +"Tallb3","E Analog Local Loopback DS3/E3", +"Tdllb3","D Analog Local Loopback DS3/E3", +"Tarlb3","E Remote Loopback DS3/E3", +"Tdrlb3","D Remote Loopback DS3/E3", +"Tadlb3","E Digital Loopback DS3/E3", +"Tddlb3","D Digital Loopback DS3/E3", +"." +}; + +char *csudsu_menu_te1_pmc[]={ +"","-- T1/E1 (S514-4-5-7-8/AFT) Stats --", +""," ", +"Ta","Read T1/E1 alarms", +"Tallb","E Line/Remote Loopback T1/E1", +"Tdllb","D Line/Remote 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", +"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", +"." +}; + +char *csudsu_menu_te1_dm[]={ +"","-- T1/E1 (AFT T1/E1-DM) Stats --", +""," ", +"Ta","Read T1/E1 alarms", +"Tallb","E Line/Remote Loopback T1/E1", +"Tdllb","D Line/Remote 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", +"Talalb","E LIU Analog Loopback T1/E1", +"Tdlalb","D LIU Analog Loopback T1/E1", +"Talllb","E LIU Local Loopback T1/E1", +"Tdlllb","D LIU Local Loopback T1/E1", +"Taldlb","E LIU Dual Loopback T1/E1", +"Tdldlb","D LIU Dual Loopback T1/E1", +"Tsalb","Send Loopback Activate Code", +"Tsdlb","Send Loopback Deactive Code", +"." +}; /****************************************************************************** * FUNCTION DEFINITION * @@ -765,20 +826,39 @@ int remote_running_RT_test(void) return(0); } -int get_fe_type(unsigned char* adapter_type) +static int hw_get_femedia_type(wan_femedia_t *fe_media) { - int rc; - - if(make_hardware_level_connection()){ - return 0; - } - rc = hw_get_fe_type(adapter_type); - - cleanup_hardware_level_connection(); + /* 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; + } - return rc; + memcpy((void*)fe_media, get_wan_udphdr_data_ptr(0), sizeof(wan_femedia_t)); + return 0; } +int get_femedia_type(wan_femedia_t *fe_media) +{ + int rc; + + if(make_hardware_level_connection()){ + return 0; + } + rc = hw_get_femedia_type(fe_media); + + cleanup_hardware_level_connection(); + + return rc; +} + + +#if 1 static int hw_get_fe_type(unsigned char* adapter_type) { /* Read Adapter Type */ @@ -803,6 +883,21 @@ static int hw_get_fe_type(unsigned char* adapter_type) 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; +} + +#endif + void set_lb_modes(unsigned char type, unsigned char mode) { if(make_hardware_level_connection()){ @@ -832,26 +927,34 @@ static void hw_set_lb_modes(unsigned char type, unsigned char 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"); + if (femedia.media == WAN_MEDIA_T1 || femedia.media == WAN_MEDIA_E1){ + printf("%s %s mode ... %s!\n", + WAN_TE1_LB_ACTION_DECODE(mode), + WAN_TE1_LB_MODE_DECODE(type), + (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); + }else if (femedia.media == WAN_MEDIA_DS3 || femedia.media == WAN_MEDIA_E3){ + printf("%s %s mode ... %s!\n", + WAN_TE3_LB_ACTION_DECODE(mode), + WAN_TE3_LB_TYPE_DECODE(type), + (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); }else{ - printf("%s mode is %s!\n", - WAN_TE1_LB_MODE_DECODE(type), - (mode == WAN_TE1_ACTIVATE_LB) ? "activated" : "deactivated"); + printf("%s %s mode ... %s (default)!\n", + WAN_TE1_LB_ACTION_DECODE(mode), + WAN_TE1_LB_MODE_DECODE(type), + (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); } return; } void get_lb_modes() { - unsigned char adapter_type = 0x00; - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ + if ((femedia.media != WAN_MEDIA_T1) && (femedia.media != WAN_MEDIA_E1) && + (femedia.media != WAN_MEDIA_DS3) && (femedia.media != WAN_MEDIA_E3)){ + printf("Error: Unsupported feature for current media type %02X!\n", + femedia.media); return; } - if(make_hardware_level_connection()){ return; } @@ -871,31 +974,42 @@ void get_lb_modes() printf("All loopback mode are disabled!"); }else{ printf("***** %s: %s Loopback status *****\n\n", - if_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - if (mode & (1<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){ + if (femedia.media == WAN_MEDIA_T1){ printf("RAI:\t%s\t| OOF:\t%s\n", WAN_TE_RAI_ALARM(fe_stats->alarms), WAN_TE_OOF_ALARM(fe_stats->alarms)); @@ -960,7 +1068,7 @@ void read_te1_56k_stat(int force) if (fe_stats->alarms & WAN_TE_BIT_LIU_ALARM){ printf("\n***** %s: %s Alarms (LIU) *****\n\n", - if_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); + if_name, (femedia.media == WAN_MEDIA_T1) ? "T1" : "E1"); printf("Short Circuit:\t%s\n", WAN_TE_LIU_ALARM_SC(fe_stats->alarms)); printf("Open Circuit:\t%s\n", @@ -969,11 +1077,11 @@ void read_te1_56k_stat(int force) WAN_TE_LIU_ALARM_LOS(fe_stats->alarms)); } - }else if (adapter_type == WAN_MEDIA_DS3 || adapter_type == WAN_MEDIA_E3){ + }else if (femedia.media == WAN_MEDIA_DS3 || femedia.media == WAN_MEDIA_E3){ printf("***** %s: %s Alarms *****\n\n", - if_name, (adapter_type == WAN_MEDIA_DS3) ? "DS3" : "E3"); + if_name, (femedia.media == WAN_MEDIA_DS3) ? "DS3" : "E3"); - if (adapter_type == WAN_MEDIA_DS3){ + if (femedia.media == 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)); @@ -994,7 +1102,7 @@ void read_te1_56k_stat(int force) WAN_TE3_LOF_ALARM(fe_stats->alarms)); } - }else if (adapter_type == WAN_MEDIA_56K){ + }else if (femedia.media == 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), @@ -1017,14 +1125,14 @@ void read_te1_56k_stat(int force) }else{ printf("***** %s: Unknown Front End 0x%X *****\n\n", - if_name, adapter_type); + if_name, femedia.media); } - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ + if (femedia.media == WAN_MEDIA_T1 || femedia.media == 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_name, (femedia.media == WAN_MEDIA_T1) ? "T1" : "E1"); if (pmon->mask & WAN_TE_BIT_PMON_LCV){ printf("Line Code Violation\t: %d\n", pmon->lcv_errors); @@ -1055,17 +1163,17 @@ void read_te1_56k_stat(int force) } } - if (adapter_type == WAN_MEDIA_DS3 || adapter_type == WAN_MEDIA_E3){ + if (femedia.media == WAN_MEDIA_DS3 || femedia.media == 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"); + if_name, (femedia.media == 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){ + if (femedia.media == 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", @@ -1078,7 +1186,7 @@ void read_te1_56k_stat(int force) } } - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ + if (femedia.media == WAN_MEDIA_T1 || femedia.media == WAN_MEDIA_E1){ if (strlen(fe_stats->u.te1_stats.rxlevel)){ printf("\n\nRx Level\t: %s\n", fe_stats->u.te1_stats.rxlevel); @@ -1091,18 +1199,12 @@ void read_te1_56k_stat(int force) 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){ + switch(femedia.media){ case WAN_MEDIA_T1: case WAN_MEDIA_E1: /* Flush perfomance mononitoring counters */ @@ -1126,14 +1228,9 @@ void flush_te1_pmon(void) 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) ? + if (femedia.media == WAN_MEDIA_T1 || femedia.media == WAN_MEDIA_E1){ + int num_of_chan = (femedia.media == WAN_MEDIA_T1) ? NUM_OF_T1_CHANNELS : NUM_OF_E1_TIMESLOTS; int i = 0, start_chan = 0; @@ -1168,7 +1265,7 @@ void read_te1_56k_config (void) FRAME_DECODE(fe_cfg)); printf("\tEncoding\t%s\n", LCODE_DECODE(fe_cfg)); - if (adapter_type == WAN_MEDIA_T1){ + if (femedia.media == WAN_MEDIA_T1){ printf("\tLine Build\t%s\n", LBO_DECODE(fe_cfg)); } @@ -1202,7 +1299,7 @@ void read_te1_56k_config (void) TECLK_DECODE(fe_cfg)); } } - else if (adapter_type == WAN_MEDIA_DS3){ + else if (femedia.media == WAN_MEDIA_DS3){ if(make_hardware_level_connection()){ return; diff --git a/util/wanpipemon/fpipemon.c b/util/wanpipemon/fpipemon.c index 269ff40..fb149d5 100644 --- a/util/wanpipemon/fpipemon.c +++ b/util/wanpipemon/fpipemon.c @@ -102,7 +102,6 @@ unsigned char station_config; - char *fr_card_stats_menu[]={ "xm","Modem Status", "xl","Link Status", @@ -1274,21 +1273,21 @@ int FRMain(char* command, int argc, char* argv[]) }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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); }else{ diff --git a/util/wanpipemon/ppipemon.c b/util/wanpipemon/ppipemon.c index eedfe86..2eedce3 100644 --- a/util/wanpipemon/ppipemon.c +++ b/util/wanpipemon/ppipemon.c @@ -1338,21 +1338,21 @@ int PPPMain(char *command,int argc, char* argv[]) }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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); } else{ diff --git a/util/wanpipemon/ss7pipemon.c b/util/wanpipemon/ss7pipemon.c index 4da88a3..3166494 100644 --- a/util/wanpipemon/ss7pipemon.c +++ b/util/wanpipemon/ss7pipemon.c @@ -1164,21 +1164,21 @@ int SS7Main(char *command,int argc, char* argv[]) read_ft1_te1_56k_config(); #endif if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(0); } else{ diff --git a/util/wanpipemon/wanpipemon.c b/util/wanpipemon/wanpipemon.c index ef4660d..497eabe 100644 --- a/util/wanpipemon/wanpipemon.c +++ b/util/wanpipemon/wanpipemon.c @@ -74,6 +74,8 @@ char* progname = "wanutil"; char* progname = "wanpipemon"; #endif + +wan_femedia_t femedia; wan_udp_hdr_t wan_udp; int sock = 0; int wan_protocol = 0; @@ -85,6 +87,7 @@ int gui_interface=0; extern int trace_hdlc_data(wanpipe_hdlc_engine_t *hdlc_eng, void *data, int len); +extern int get_femedia_type(wan_femedia_t *fe_media); static sa_family_t af = AF_INET; static struct sockaddr_in soin; @@ -1414,12 +1417,16 @@ int main(int argc, char* argv[]) } gui_loop: #endif + if (MakeConnection() == WAN_FALSE){ close(sock); err=-ENODEV; goto main_exit; } - + + /* Read fe media info for current interface */ + get_femedia_type(&femedia); + //get_hardware_level_interface_name(if_name); #ifdef WANPIPEMON_GUI diff --git a/util/wanpipemon/wanpipemon.h b/util/wanpipemon/wanpipemon.h index dca044b..f184d15 100644 --- a/util/wanpipemon/wanpipemon.h +++ b/util/wanpipemon/wanpipemon.h @@ -1,3 +1,6 @@ +#ifndef _WANPIPEMON_H_ +#define _WANPIPEMON_H_ + #ifdef WANPIPEMON_GUI #include "../lxdialog/dialog.h" #endif @@ -494,3 +497,12 @@ extern void hw_router_up_time(void); extern void hw_read_code_version(void); extern void hw_link_status(void); +#ifndef LONG_MAX +#define LONG_MAX ((long)(~0UL>>1)) +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX - 1) +#endif + +#endif diff --git a/util/wanpipemon_legacy/Makefile b/util/wanpipemon_legacy/Makefile index 07a539c..fc9b382 100644 --- a/util/wanpipemon_legacy/Makefile +++ b/util/wanpipemon_legacy/Makefile @@ -12,7 +12,6 @@ DEBUG = 2 PROD=wanpipemon_legacy # Project file paths. -SYSINC=/lib/modules/$(shell uname -r)/build/include WAN_VIRTUAL= LXDIR=../lxdialog ENABLE_GUI=YES @@ -21,7 +20,7 @@ PROTOCOL_DEFS= CC = gcc CPP = gcc -E -CFLAGS = -Wall -Wstrict-prototypes -I$(SYSINC) -D$(OS_TYPE) -I../ft1 -O2 -fomit-frame-pointer -DLOCALE -D_DEBUG_=$(DEBUG) -DCURSES_LOC="" +CFLAGS = -Wall -Wstrict-prototypes -D$(OS_TYPE) -I../ft1 -O2 -fomit-frame-pointer -DLOCALE -D_DEBUG_=$(DEBUG) -DCURSES_LOC="" WAN_VIRTUAL= CFLAGS += $(EXTRA_FLAGS) diff --git a/util/wanpipemon_legacy/aftpipemon.c b/util/wanpipemon_legacy/aftpipemon.c index 859fe9d..e0e2eec 100644 --- a/util/wanpipemon_legacy/aftpipemon.c +++ b/util/wanpipemon_legacy/aftpipemon.c @@ -746,21 +746,21 @@ int AFTMain(char *command,int argc, char* argv[]) 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/util/wanpipemon_legacy/atmpipemon.c b/util/wanpipemon_legacy/atmpipemon.c index 969bc2c..967c0d2 100644 --- a/util/wanpipemon_legacy/atmpipemon.c +++ b/util/wanpipemon_legacy/atmpipemon.c @@ -1255,21 +1255,21 @@ int ATMMain(char *command,int argc, char* 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/util/wanpipemon_legacy/bpipemon.c b/util/wanpipemon_legacy/bpipemon.c index b215997..a7bb199 100644 --- a/util/wanpipemon_legacy/bpipemon.c +++ b/util/wanpipemon_legacy/bpipemon.c @@ -551,21 +551,21 @@ int BITSTRMMain(char *command,int argc, char* argv[]) 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/util/wanpipemon_legacy/cpipemon.c b/util/wanpipemon_legacy/cpipemon.c index 6ec3da0..0eec23c 100644 --- a/util/wanpipemon_legacy/cpipemon.c +++ b/util/wanpipemon_legacy/cpipemon.c @@ -1468,21 +1468,21 @@ int CHDLCMain(char *command,int argc, char* 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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/util/wanpipemon_legacy/fe_lib.c b/util/wanpipemon_legacy/fe_lib.c index 096d7cc..c9ca567 100644 --- a/util/wanpipemon_legacy/fe_lib.c +++ b/util/wanpipemon_legacy/fe_lib.c @@ -801,10 +801,10 @@ void set_lb_modes(unsigned char type, unsigned char mode) 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"); + (mode == WAN_TE1_LB_ENABLE) ? "activate" : "deactivate"); }else{ printf("Line loopback mode is %s!\n", - (mode == WAN_TE1_ACTIVATE_LB) ? "activated" : "deactivated"); + (mode == WAN_TE1_LB_ENABLE) ? "activated" : "deactivated"); } return; } diff --git a/util/wanpipemon_legacy/fpipemon.c b/util/wanpipemon_legacy/fpipemon.c index ee4b54c..4438263 100644 --- a/util/wanpipemon_legacy/fpipemon.c +++ b/util/wanpipemon_legacy/fpipemon.c @@ -1671,21 +1671,21 @@ int FRMain(char* command, int argc, char* argv[]) }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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); }else{ diff --git a/util/wanpipemon_legacy/ppipemon.c b/util/wanpipemon_legacy/ppipemon.c index 2ffd40b..9686564 100644 --- a/util/wanpipemon_legacy/ppipemon.c +++ b/util/wanpipemon_legacy/ppipemon.c @@ -2016,21 +2016,21 @@ int PPPMain(char *command,int argc, char* argv[]) }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); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/util/wanpipemon_legacy/ss7pipemon.c b/util/wanpipemon_legacy/ss7pipemon.c index aa989d1..33f9653 100644 --- a/util/wanpipemon_legacy/ss7pipemon.c +++ b/util/wanpipemon_legacy/ss7pipemon.c @@ -1175,21 +1175,21 @@ int SS7Main(char *command,int argc, char* argv[]) read_ft1_te1_56k_config(); #endif if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_ENABLE); }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); + set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_LB_DISABLE); }else if (!strcmp(opt,"a")){ read_te1_56k_stat(); } else{ diff --git a/zaptel/zaptel.path b/zaptel/zaptel.path new file mode 100644 index 0000000..700d63d --- /dev/null +++ b/zaptel/zaptel.path @@ -0,0 +1 @@ +/usr/src/zaptel