From 7c176870b35cb55deea280f0a5343b096844acd9 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Fri, 14 Aug 2015 11:05:47 +0200 Subject: [PATCH] Imported Upstream version 2.10.2 --- .gitignore | 51 + .version | 1 + LICENSE | 341 + LICENSE.LGPL | 504 + Makefile | 390 + README | 371 + UPGRADE.txt | 102 + acinclude.m4 | 1113 ++ assigned-spans.conf.sample | 57 + autoconfig.h.in | 114 + bittest.h | 17 + blacklist.sample | 23 + bootstrap.sh | 48 + build_tools/dahdi_svn_tarball | 90 + build_tools/dahdi_sysfs_copy | 142 + build_tools/dump_sys_state | 76 + build_tools/make_dist | 26 + build_tools/make_firmware_object.in | 11 + build_tools/make_tree | 0 build_tools/make_version | 122 + build_tools/make_version_c | 10 + build_tools/menuselect-deps.in | 0 build_tools/test_kernel_git | 80 + build_tools/uninstall-modules | 41 + config.guess | 1526 ++ config.sub | 1658 ++ configure | 6470 ++++++++ configure.ac | 217 + dahdi-bash-completion | 133 + dahdi.init | 343 + dahdi.rules | 18 + dahdi.xml | 26 + dahdi_cfg.c | 1961 +++ dahdi_diag.c | 55 + dahdi_maint.c | 254 + dahdi_monitor.c | 785 + dahdi_pcap.c | 332 + dahdi_scan.c | 264 + dahdi_span_assignments | 333 + dahdi_span_types | 366 + dahdi_speed.c | 65 + dahdi_test.c | 177 + dahdi_tool.c | 541 + dahdi_tools_version.h | 21 + dahdi_waitfor_span_assignments | 73 + doc/dahdi_cfg.8 | 86 + doc/dahdi_diag.8 | 52 + doc/dahdi_maint.8 | 62 + doc/dahdi_monitor.8 | 145 + doc/dahdi_scan.8 | 101 + doc/dahdi_span_assignments.8 | 251 + doc/dahdi_span_types.8 | 197 + doc/dahdi_test.8 | 49 + doc/dahdi_tool.8 | 25 + doc/dahdi_waitfor_span_assignments.8 | 49 + doc/fxotune.8 | 208 + doc/fxstest.8 | 60 + doc/patgen.8 | 44 + doc/pattest.8 | 49 + fxotune.c | 1328 ++ fxotune.h | 119 + fxstest.c | 373 + hdlcgen.c | 135 + hdlcstress.c | 233 + hdlctest.c | 302 + hdlcverify.c | 136 + hotplug/dahdi_auto_assign_compat | 25 + hotplug/dahdi_handle_device | 87 + hotplug/dahdi_span_config | 97 + hotplug/handle_device.d/10-span-types | 12 + hotplug/handle_device.d/20-span-assignments | 15 + hotplug/span_config.d/10-dahdi-cfg | 28 + hotplug/span_config.d/20-fxotune | 12 + hotplug/span_config.d/50-asterisk | 14 + ifup-hdlc | 39 + init.conf.sample | 24 + install-sh | 323 + makeopts.in | 49 + modprobe.conf.sample | 4 + modules.sample | 63 + patgen.c | 175 + patlooptest.c | 345 + pattest.c | 181 + ppp/Makefile | 29 + ppp/dahdi.c | 293 + sethdlc.c | 704 + span-types.conf.sample | 28 + system.conf.sample | 326 + timertest.c | 78 + tonezone.c | 529 + tonezone.h | 90 + wavformat.h | 48 + xpp/Makefile | 202 + xpp/README.Astribank | 1677 ++ xpp/astribank_allow.8 | 80 + xpp/astribank_allow.c | 185 + xpp/astribank_hexload.8 | 133 + xpp/astribank_hexload.c | 316 + xpp/astribank_hook | 234 + xpp/astribank_is_starting.8 | 100 + xpp/astribank_is_starting.c | 196 + xpp/astribank_license.c | 340 + xpp/astribank_license.h | 29 + xpp/astribank_tool.8 | 86 + xpp/astribank_tool.c | 287 + xpp/astribank_upgrade | 150 + xpp/astribank_usb.c | 276 + xpp/astribank_usb.h | 113 + xpp/dahdi.cgi | 265 + xpp/dahdi_drivers | 23 + xpp/dahdi_genconf | 241 + xpp/dahdi_hardware | 196 + xpp/dahdi_registration | 248 + xpp/echo_loader.c | 876 + xpp/echo_loader.h | 32 + xpp/genconf_parameters | 169 + xpp/hexfile.c | 568 + xpp/hexfile.h | 87 + xpp/lsdahdi | 110 + xpp/mpp.h | 202 + xpp/mpptalk.c | 956 ++ xpp/mpptalk.h | 85 + xpp/mpptalk_defs.h | 113 + xpp/oct612x/Makefile | 38 + xpp/oct612x/apilib/bt/octapi_bt0.c | 1217 ++ xpp/oct612x/apilib/bt/octapi_bt0_private.h | 93 + xpp/oct612x/apilib/largmath/octapi_largmath.c | 628 + xpp/oct612x/apilib/llman/octapi_llman.c | 2787 ++++ .../apilib/llman/octapi_llman_private.h | 206 + xpp/oct612x/get_discards | 51 + xpp/oct612x/include/apilib/octapi_bt0.h | 75 + xpp/oct612x/include/apilib/octapi_largmath.h | 69 + xpp/oct612x/include/apilib/octapi_llman.h | 142 + xpp/oct612x/include/digium_unused.h | 297 + .../oct6100api/oct6100_adpcm_chan_inst.h | 74 + .../oct6100api/oct6100_adpcm_chan_pub.h | 90 + xpp/oct612x/include/oct6100api/oct6100_api.h | 84 + .../include/oct6100api/oct6100_api_inst.h | 138 + .../include/oct6100api/oct6100_apimi.h | 69 + .../include/oct6100api/oct6100_apiud.h | 312 + .../include/oct6100api/oct6100_channel_inst.h | 374 + .../include/oct6100api/oct6100_channel_pub.h | 547 + .../oct6100api/oct6100_chip_open_inst.h | 515 + .../oct6100api/oct6100_chip_open_pub.h | 241 + .../oct6100api/oct6100_chip_stats_inst.h | 84 + .../oct6100api/oct6100_chip_stats_pub.h | 150 + .../oct6100api/oct6100_conf_bridge_inst.h | 104 + .../oct6100api/oct6100_conf_bridge_pub.h | 169 + .../include/oct6100api/oct6100_debug_inst.h | 124 + .../include/oct6100api/oct6100_debug_pub.h | 76 + .../include/oct6100api/oct6100_defines.h | 679 + .../include/oct6100api/oct6100_errors.h | 838 + .../include/oct6100api/oct6100_events_inst.h | 69 + .../include/oct6100api/oct6100_events_pub.h | 111 + .../oct6100api/oct6100_interrupts_inst.h | 134 + .../oct6100api/oct6100_interrupts_pub.h | 102 + .../include/oct6100api/oct6100_mixer_inst.h | 86 + .../include/oct6100api/oct6100_mixer_pub.h | 77 + .../oct6100api/oct6100_phasing_tsst_inst.h | 68 + .../oct6100api/oct6100_phasing_tsst_pub.h | 78 + .../oct6100api/oct6100_playout_buf_inst.h | 88 + .../oct6100api/oct6100_playout_buf_pub.h | 183 + .../oct6100api/oct6100_remote_debug_inst.h | 73 + .../oct6100api/oct6100_remote_debug_pub.h | 64 + .../include/oct6100api/oct6100_tlv_inst.h | 72 + .../oct6100api/oct6100_tone_detection_inst.h | 46 + .../oct6100api/oct6100_tone_detection_pub.h | 74 + .../oct6100api/oct6100_tsi_cnct_inst.h | 70 + .../include/oct6100api/oct6100_tsi_cnct_pub.h | 76 + .../include/oct6100api/oct6100_tsst_inst.h | 55 + xpp/oct612x/include/octdef.h | 120 + xpp/oct612x/include/octmac.h | 98 + xpp/oct612x/include/octosdependant.h | 170 + .../include/octrpc/oct6100_rpc_protocol.h | 348 + xpp/oct612x/include/octrpc/rpc_protocol.h | 115 + xpp/oct612x/include/octtype.h | 159 + xpp/oct612x/include/octtypevx.h | 132 + xpp/oct612x/include/octtypewin.h | 100 + xpp/oct612x/octasic-helper | 39 + .../oct6100api/oct6100_adpcm_chan_priv.h | 131 + .../oct6100_api/oct6100_adpcm_chan.c | 1237 ++ .../oct6100api/oct6100_api/oct6100_channel.c | 13858 ++++++++++++++++ .../oct6100_api/oct6100_chip_open.c | 6899 ++++++++ .../oct6100_api/oct6100_chip_stats.c | 441 + .../oct6100_api/oct6100_conf_bridge.c | 7664 +++++++++ .../oct6100api/oct6100_api/oct6100_debug.c | 1278 ++ .../oct6100api/oct6100_api/oct6100_events.c | 1379 ++ .../oct6100_api/oct6100_interrupts.c | 1997 +++ .../oct6100api/oct6100_api/oct6100_memory.c | 831 + .../oct6100_api/oct6100_miscellaneous.c | 640 + .../oct6100api/oct6100_api/oct6100_mixer.c | 1586 ++ .../oct6100_api/oct6100_phasing_tsst.c | 922 + .../oct6100_api/oct6100_playout_buf.c | 3337 ++++ .../oct6100_api/oct6100_remote_debug.c | 1598 ++ .../oct6100api/oct6100_api/oct6100_tlv.c | 2056 +++ .../oct6100_api/oct6100_tone_detection.c | 1088 ++ .../oct6100api/oct6100_api/oct6100_tsi_cnct.c | 1023 ++ .../oct6100api/oct6100_api/oct6100_tsst.c | 572 + .../oct6100api/oct6100_api/oct6100_user.c | 508 + .../oct6100_apimi/oct6100_mask_interrupts.c | 116 + .../oct6100api/oct6100_channel_priv.h | 529 + .../oct6100api/oct6100_chip_open_priv.h | 264 + .../oct6100api/oct6100_chip_stats_priv.h | 55 + .../oct6100api/oct6100_conf_bridge_priv.h | 318 + .../oct6100api/oct6100_debug_priv.h | 58 + .../oct6100api/oct6100_events_priv.h | 82 + .../oct6100api/oct6100_interrupts_priv.h | 158 + .../oct6100api/oct6100_memory_priv.h | 97 + .../oct6100api/oct6100_miscellaneous_priv.h | 277 + .../oct6100api/oct6100_mixer_priv.h | 150 + .../oct6100api/oct6100_phasing_tsst_priv.h | 114 + .../oct6100api/oct6100_playout_buf_priv.h | 201 + .../oct6100api/oct6100_remote_debug_priv.h | 144 + .../oct6100api/oct6100_tlv_priv.h | 515 + .../oct6100api/oct6100_tone_detection_priv.h | 111 + .../oct6100api/oct6100_tsi_cnct_priv.h | 126 + .../oct6100api/oct6100_tsst_priv.h | 89 + .../octdeviceapi/oct6100api/oct6100_version.h | 39 + xpp/oct612x/test.c | 46 + xpp/parse_span_specs.c | 152 + xpp/parse_span_specs.h | 43 + xpp/perl_modules/Dahdi.pm | 78 + xpp/perl_modules/Dahdi/Chans.pm | 264 + xpp/perl_modules/Dahdi/Config/Gen.pm | 275 + .../Dahdi/Config/Gen/Assignedspans.pm | 63 + .../Dahdi/Config/Gen/Chandahdi.pm | 299 + .../Dahdi/Config/Gen/Freepbxdb.pm | 116 + xpp/perl_modules/Dahdi/Config/Gen/Modules.pm | 62 + .../Dahdi/Config/Gen/Spantypes.pm | 86 + xpp/perl_modules/Dahdi/Config/Gen/System.pm | 277 + xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm | 72 + xpp/perl_modules/Dahdi/Config/Gen/Users.pm | 227 + xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm | 142 + xpp/perl_modules/Dahdi/Config/Params.pm | 156 + xpp/perl_modules/Dahdi/Hardware.pm | 235 + xpp/perl_modules/Dahdi/Hardware/PCI.pm | 261 + xpp/perl_modules/Dahdi/Hardware/USB.pm | 221 + xpp/perl_modules/Dahdi/Span.pm | 420 + xpp/perl_modules/Dahdi/Utils.pm | 65 + xpp/perl_modules/Dahdi/Xpp.pm | 307 + xpp/perl_modules/Dahdi/Xpp/Line.pm | 65 + xpp/perl_modules/Dahdi/Xpp/Mpp.pm | 222 + xpp/perl_modules/Dahdi/Xpp/Xbus.pm | 212 + xpp/perl_modules/Dahdi/Xpp/Xpd.pm | 332 + xpp/pic_loader.c | 285 + xpp/pic_loader.h | 46 + xpp/test_parse.c | 57 + xpp/twinstar | 267 + xpp/twinstar_hook | 86 + xpp/twinstar_setup | 155 + xpp/waitfor_xpds | 163 + xpp/xpp.rules | 11 + xpp/xpp_blink | 168 + xpp/xpp_fxloader | 597 + xpp/xpp_fxloader.usermap | 10 + xpp/xpp_modprobe | 10 + xpp/xpp_sync | 227 + xpp/xpp_timing | 6 + xpp/xtalk/debug.c | 73 + xpp/xtalk/debug.h | 52 + xpp/xtalk/xlist.c | 94 + xpp/xtalk/xlist.h | 29 + xpp/xtalk/xtalk.c | 497 + xpp/xtalk/xtalk.h | 178 + xpp/xtalk/xtalk_defs.h | 41 + xpp/xtalk/xusb.c | 943 ++ xpp/xtalk/xusb.h | 102 + zonedata.c | 1069 ++ 268 files changed, 110975 insertions(+) create mode 100644 .gitignore create mode 100644 .version create mode 100644 LICENSE create mode 100644 LICENSE.LGPL create mode 100644 Makefile create mode 100644 README create mode 100644 UPGRADE.txt create mode 100644 acinclude.m4 create mode 100644 assigned-spans.conf.sample create mode 100644 autoconfig.h.in create mode 100644 bittest.h create mode 100644 blacklist.sample create mode 100755 bootstrap.sh create mode 100755 build_tools/dahdi_svn_tarball create mode 100755 build_tools/dahdi_sysfs_copy create mode 100755 build_tools/dump_sys_state create mode 100755 build_tools/make_dist create mode 100755 build_tools/make_firmware_object.in create mode 100755 build_tools/make_tree create mode 100755 build_tools/make_version create mode 100755 build_tools/make_version_c create mode 100644 build_tools/menuselect-deps.in create mode 100755 build_tools/test_kernel_git create mode 100755 build_tools/uninstall-modules create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100644 dahdi-bash-completion create mode 100755 dahdi.init create mode 100644 dahdi.rules create mode 100644 dahdi.xml create mode 100644 dahdi_cfg.c create mode 100644 dahdi_diag.c create mode 100644 dahdi_maint.c create mode 100644 dahdi_monitor.c create mode 100644 dahdi_pcap.c create mode 100644 dahdi_scan.c create mode 100755 dahdi_span_assignments create mode 100755 dahdi_span_types create mode 100644 dahdi_speed.c create mode 100644 dahdi_test.c create mode 100644 dahdi_tool.c create mode 100644 dahdi_tools_version.h create mode 100755 dahdi_waitfor_span_assignments create mode 100644 doc/dahdi_cfg.8 create mode 100644 doc/dahdi_diag.8 create mode 100644 doc/dahdi_maint.8 create mode 100644 doc/dahdi_monitor.8 create mode 100644 doc/dahdi_scan.8 create mode 100644 doc/dahdi_span_assignments.8 create mode 100644 doc/dahdi_span_types.8 create mode 100644 doc/dahdi_test.8 create mode 100644 doc/dahdi_tool.8 create mode 100644 doc/dahdi_waitfor_span_assignments.8 create mode 100644 doc/fxotune.8 create mode 100644 doc/fxstest.8 create mode 100644 doc/patgen.8 create mode 100644 doc/pattest.8 create mode 100644 fxotune.c create mode 100644 fxotune.h create mode 100644 fxstest.c create mode 100644 hdlcgen.c create mode 100644 hdlcstress.c create mode 100644 hdlctest.c create mode 100644 hdlcverify.c create mode 100755 hotplug/dahdi_auto_assign_compat create mode 100755 hotplug/dahdi_handle_device create mode 100755 hotplug/dahdi_span_config create mode 100755 hotplug/handle_device.d/10-span-types create mode 100755 hotplug/handle_device.d/20-span-assignments create mode 100755 hotplug/span_config.d/10-dahdi-cfg create mode 100755 hotplug/span_config.d/20-fxotune create mode 100755 hotplug/span_config.d/50-asterisk create mode 100644 ifup-hdlc create mode 100644 init.conf.sample create mode 100755 install-sh create mode 100644 makeopts.in create mode 100644 modprobe.conf.sample create mode 100644 modules.sample create mode 100644 patgen.c create mode 100644 patlooptest.c create mode 100644 pattest.c create mode 100644 ppp/Makefile create mode 100644 ppp/dahdi.c create mode 100644 sethdlc.c create mode 100644 span-types.conf.sample create mode 100644 system.conf.sample create mode 100644 timertest.c create mode 100644 tonezone.c create mode 100644 tonezone.h create mode 100644 wavformat.h create mode 100644 xpp/Makefile create mode 100644 xpp/README.Astribank create mode 100644 xpp/astribank_allow.8 create mode 100644 xpp/astribank_allow.c create mode 100644 xpp/astribank_hexload.8 create mode 100644 xpp/astribank_hexload.c create mode 100755 xpp/astribank_hook create mode 100644 xpp/astribank_is_starting.8 create mode 100644 xpp/astribank_is_starting.c create mode 100644 xpp/astribank_license.c create mode 100644 xpp/astribank_license.h create mode 100644 xpp/astribank_tool.8 create mode 100644 xpp/astribank_tool.c create mode 100755 xpp/astribank_upgrade create mode 100644 xpp/astribank_usb.c create mode 100644 xpp/astribank_usb.h create mode 100755 xpp/dahdi.cgi create mode 100755 xpp/dahdi_drivers create mode 100755 xpp/dahdi_genconf create mode 100755 xpp/dahdi_hardware create mode 100755 xpp/dahdi_registration create mode 100644 xpp/echo_loader.c create mode 100644 xpp/echo_loader.h create mode 100644 xpp/genconf_parameters create mode 100644 xpp/hexfile.c create mode 100644 xpp/hexfile.h create mode 100755 xpp/lsdahdi create mode 100644 xpp/mpp.h create mode 100644 xpp/mpptalk.c create mode 100644 xpp/mpptalk.h create mode 100644 xpp/mpptalk_defs.h create mode 100644 xpp/oct612x/Makefile create mode 100644 xpp/oct612x/apilib/bt/octapi_bt0.c create mode 100644 xpp/oct612x/apilib/bt/octapi_bt0_private.h create mode 100644 xpp/oct612x/apilib/largmath/octapi_largmath.c create mode 100644 xpp/oct612x/apilib/llman/octapi_llman.c create mode 100644 xpp/oct612x/apilib/llman/octapi_llman_private.h create mode 100755 xpp/oct612x/get_discards create mode 100644 xpp/oct612x/include/apilib/octapi_bt0.h create mode 100644 xpp/oct612x/include/apilib/octapi_largmath.h create mode 100644 xpp/oct612x/include/apilib/octapi_llman.h create mode 100644 xpp/oct612x/include/digium_unused.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_api.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_api_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_apimi.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_apiud.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_channel_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_channel_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_debug_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_debug_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_defines.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_errors.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_events_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_events_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h create mode 100644 xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h create mode 100644 xpp/oct612x/include/octdef.h create mode 100644 xpp/oct612x/include/octmac.h create mode 100644 xpp/oct612x/include/octosdependant.h create mode 100644 xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h create mode 100644 xpp/oct612x/include/octrpc/rpc_protocol.h create mode 100644 xpp/oct612x/include/octtype.h create mode 100644 xpp/oct612x/include/octtypevx.h create mode 100644 xpp/oct612x/include/octtypewin.h create mode 100755 xpp/oct612x/octasic-helper create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h create mode 100644 xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h create mode 100644 xpp/oct612x/test.c create mode 100644 xpp/parse_span_specs.c create mode 100644 xpp/parse_span_specs.h create mode 100644 xpp/perl_modules/Dahdi.pm create mode 100644 xpp/perl_modules/Dahdi/Chans.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Modules.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/System.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Users.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm create mode 100644 xpp/perl_modules/Dahdi/Config/Params.pm create mode 100644 xpp/perl_modules/Dahdi/Hardware.pm create mode 100644 xpp/perl_modules/Dahdi/Hardware/PCI.pm create mode 100644 xpp/perl_modules/Dahdi/Hardware/USB.pm create mode 100644 xpp/perl_modules/Dahdi/Span.pm create mode 100644 xpp/perl_modules/Dahdi/Utils.pm create mode 100644 xpp/perl_modules/Dahdi/Xpp.pm create mode 100644 xpp/perl_modules/Dahdi/Xpp/Line.pm create mode 100644 xpp/perl_modules/Dahdi/Xpp/Mpp.pm create mode 100644 xpp/perl_modules/Dahdi/Xpp/Xbus.pm create mode 100644 xpp/perl_modules/Dahdi/Xpp/Xpd.pm create mode 100644 xpp/pic_loader.c create mode 100644 xpp/pic_loader.h create mode 100644 xpp/test_parse.c create mode 100755 xpp/twinstar create mode 100755 xpp/twinstar_hook create mode 100755 xpp/twinstar_setup create mode 100755 xpp/waitfor_xpds create mode 100644 xpp/xpp.rules create mode 100755 xpp/xpp_blink create mode 100644 xpp/xpp_fxloader create mode 100644 xpp/xpp_fxloader.usermap create mode 100644 xpp/xpp_modprobe create mode 100755 xpp/xpp_sync create mode 100755 xpp/xpp_timing create mode 100644 xpp/xtalk/debug.c create mode 100644 xpp/xtalk/debug.h create mode 100644 xpp/xtalk/xlist.c create mode 100644 xpp/xtalk/xlist.h create mode 100644 xpp/xtalk/xtalk.c create mode 100644 xpp/xtalk/xtalk.h create mode 100644 xpp/xtalk/xtalk_defs.h create mode 100644 xpp/xtalk/xusb.c create mode 100644 xpp/xtalk/xusb.h create mode 100644 zonedata.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eec9c01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +*.o +.*.o.d +.*.lo.d +*.asciidoc +*.html +build_tools/menuselect-deps +autoconfig.h +config.log +config.status +dahdi_cfg +dahdi_diag +dahdi_maint +dahdi_monitor +dahdi_scan +dahdi_speed +dahdi_test +dahdi_tool +fxotune +fxstest +genconf_parameters.sample +hdlcgen +hdlcstress +hdlctest +hdlcverify +libtonezone.a +libtonezone.so +makeopts +patgen +patlooptest +pattest +sethdlc +timertest +tonezone.lo +tonezones.txt +version.c +xpp/.depend +xpp/.octasic.depend +xpp/.perlcheck +xpp/astribank_allow +xpp/astribank_hexload +xpp/astribank_is_starting +xpp/astribank_tool +xpp/dahdi_genconf.8 +xpp/dahdi_hardware.8 +xpp/dahdi_registration.8 +xpp/lsdahdi.8 +xpp/test_parse +xpp/twinstar.8 +xpp/xpp_blink.8 +xpp/xpp_sync.8 +zonedata.lo diff --git a/.version b/.version new file mode 100644 index 0000000..c6436a8 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +2.10.2 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a52b16e --- /dev/null +++ b/LICENSE @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/LICENSE.LGPL b/LICENSE.LGPL new file mode 100644 index 0000000..1f7c8cc --- /dev/null +++ b/LICENSE.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69741e6 --- /dev/null +++ b/Makefile @@ -0,0 +1,390 @@ +# +# Makefile for DAHDI tools +# +# Copyright (C) 2001-2010 Digium, Inc. +# +# + +ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) +endif + +ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) + ifneq ($(wildcard makeopts),) + include makeopts + endif +endif + +SUBDIRS_UTILS_ALL:= ppp +SUBDIRS_UTILS := xpp + +OPTFLAGS=-O2 +CFLAGS+=-I. $(OPTFLAGS) -g -fPIC -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER +ifneq (,$(findstring ppc,$(UNAME_M))) +CFLAGS+=-fsigned-char +endif +ifneq (,$(findstring x86_64,$(UNAME_M))) +CFLAGS+=-m64 +endif + +ifeq ($(DAHDI_DEVMODE),yes) + CFLAGS+=-Werror -Wunused -Wundef $(DAHDI_DECLARATION_AFTER_STATEMENT) -Wmissing-format-attribute -Wformat-security #-Wformat=2 +endif + +ROOT_PREFIX= + +# extra cflags to build dependencies. Recursively expanded. +MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP + +CFLAGS+=$(DAHDI_INCLUDE) + +CHKCONFIG := $(wildcard /sbin/chkconfig) +UPDATE_RCD := $(wildcard /usr/sbin/update-rc.d) +ifeq (,$(DESTDIR)) + ifneq (,$(CHKCONFIG)) + ADD_INITD := $(CHKCONFIG) --add dahdi + else + ifneq (,$(UPDATE_RCD)) + ADD_INITD := $(UPDATE_RCD) dahdi defaults 15 30 + endif + endif +endif + +INITRD_DIR := $(firstword $(wildcard $(DESTDIR)/etc/rc.d/init.d $(DESTDIR)/etc/init.d)) +ifneq (,$(INITRD_DIR)) + INIT_TARGET := $(INITRD_DIR)/dahdi + COPY_INITD := install -D dahdi.init $(INIT_TARGET) +endif + +RCCONF_FILE = /etc/dahdi/init.conf +MODULES_FILE = /etc/dahdi/modules +GENCONF_FILE = /etc/dahdi/genconf_parameters +MODPROBE_FILE = /etc/modprobe.d/dahdi.conf +BLACKLIST_FILE = /etc/modprobe.d/dahdi.blacklist.conf +BASH_COMP_DIR = /etc/bash_completion.d +BASH_COMP_FILE = $(BASH_COMP_DIR)/dahdi + +NETSCR_DIR := $(firstword $(wildcard $(DESTDIR)/etc/sysconfig/network-scripts )) +ifneq (,$(NETSCR_DIR)) + NETSCR_TARGET := $(NETSCR_DIR)/ifup-hdlc + COPY_NETSCR := install -D ifup-hdlc $(NETSCR_TARGET) +endif + +TOOLSVERSION=$(shell build_tools/make_version . dahdi/tools) + +LTZ_A:=libtonezone.a +LTZ_A_OBJS:=zonedata.o tonezone.o version.o +LTZ_SO:=libtonezone.so +LTZ_SO_OBJS:=zonedata.lo tonezone.lo version.o +LTZ_SO_MAJOR_VER:=2 +LTZ_SO_MINOR_VER:=0 + +# sbindir, libdir, includedir and mandir are defined in makeopts +# (from configure). +BIN_DIR:=$(sbindir) +LIB_DIR:=$(libdir) +INC_DIR:=$(includedir)/dahdi +MAN_DIR:=$(mandir)/man8 +DATA_DIR:=${datadir}/dahdi +CONFIG_DIR:=$(sysconfdir)/dahdi +CONFIG_FILE:=$(CONFIG_DIR)/system.conf +UDEVRULES_DIR:=$(sysconfdir)/udev/rules.d + +# Utilities we build with a standard build procedure: +UTILS = dahdi_tool dahdi_test dahdi_monitor dahdi_speed sethdlc dahdi_cfg \ + fxstest fxotune dahdi_diag dahdi_scan + +# some tests: +UTILS += patgen pattest patlooptest hdlcstress hdlctest hdlcgen \ + hdlcverify timertest dahdi_maint + + +BINS:=fxotune dahdi_cfg dahdi_monitor dahdi_speed dahdi_test dahdi_scan dahdi_maint +ifeq (1,$(PBX_NEWT)) + BINS += dahdi_tool +endif +ifeq (1,$(PBX_HDLC)) + BINS += sethdlc +endif +ASSIGNED_DATA_SCRIPTS:=\ + dahdi_handle_device \ + dahdi_span_config \ + dahdi_auto_assign_compat \ + span_config.d/10-dahdi-cfg \ + span_config.d/20-fxotune \ + span_config.d/50-asterisk \ + handle_device.d/10-span-types \ + handle_device.d/20-span-assignments + +ASSIGNED_UTILS:=dahdi_span_assignments dahdi_span_types \ + dahdi_waitfor_span_assignments +ASSIGNED_CONF:=assigned-spans.conf.sample span-types.conf.sample + +MAN_PAGES:= \ + $(wildcard $(BINS:%=doc/%.8)) \ + $(wildcard $(ASSIGNED_UTILS:%=doc/%.8)) + +TEST_BINS:=patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest dahdi_maint +# All the man pages. Not just installed ones: +GROFF_PAGES := $(wildcard doc/*.8 xpp/*.8) +GROFF_HTML := $(GROFF_PAGES:%=%.html) + +GENERATED_DOCS := $(GROFF_HTML) README.html README.Astribank.html + +all: prereq programs + +libs: $(LTZ_SO) $(LTZ_A) + +utils-subdirs: + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir; \ + done + +programs: libs utils + +utils: $(BINS) utils-subdirs + +version.c: FORCE + @TOOLSVERSION="${TOOLSVERSION}" build_tools/make_version_c > $@.tmp + @if cmp -s $@.tmp $@ ; then :; else \ + mv $@.tmp $@ ; \ + fi + @rm -f $@.tmp + +tests: $(TEST_BINS) + +$(UTILS): %: %.o + +$(UTILS): version.o + +%.o: %.c + $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< + +%.lo: %.c + $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< + +%: %.o + $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + +prereq: config.status + +dahdi_tool: CFLAGS+=$(NEWT_INCLUDE) +dahdi_tool: LIBS+=$(NEWT_LIB) + +dahdi_speed: CFLAGS+=-O0 + +$(LTZ_A): $(LTZ_A_OBJS) + ar rcs $@ $^ + ranlib $@ + +$(LTZ_SO): $(LTZ_SO_OBJS) + $(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm + +dahdi_cfg: $(LTZ_A) +dahdi_cfg: LIBS+=-lm -lpthread +dahdi_pcap: + $(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $< + + +fxstest: $(LTZ_SO) +fxstest: LIBS+=-lm +fxotune: LIBS+=-lm + +tonezones.txt: zonedata.c + perl -ne 'next unless (/\.(country|description) = *"([^"]*)/); \ + print (($$1 eq "country")? "* $$2\t":"$$2\n");' $< \ + >$@ + +%.asciidoc: %.sample + perl -n -e \ + 'if (/^#($$|\s)(.*)/){ if (!$$in_doc){print "\n"}; $$in_doc=1; print "$$2\n" } else { if ($$in_doc){print "\n"}; $$in_doc=0; print " $$_" }' \ + $< \ + | perl -p -e 'if (/^ #?(\w+)=/ && ! exists $$cfgs{$$1}){my $$cfg = $$1; $$cfgs{$$cfg} = 1; s/^/\n[[cfg_$$cfg]]\n/}' >$@ + +docs: $(GENERATED_DOCS) + +genconf_parameters.sample: xpp/genconf_parameters + cp $< $@ + +README.html: README system.conf.asciidoc init.conf.asciidoc tonezones.txt \ + UPGRADE.txt genconf_parameters.asciidoc assigned-spans.conf.asciidoc \ + span-types.conf.asciidoc + $(ASCIIDOC) -n -a toc -a toclevels=4 $< + +README.Astribank.html: xpp/README.Astribank + $(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $< + +# on Debian: this requires the full groff, not just groff-base. +%.8.html: %.8 + man -Thtml $^ >$@ + +htmlman: $(GROFF_HTML) + +install: all install-programs + @echo "###################################################" + @echo "###" + @echo "### DAHDI tools installed successfully." + @echo "### If you have not done so before, install init scripts with:" + @echo "###" + @echo "### make config" + @echo "###" + @echo "###################################################" + +install-programs: install-utils install-libs + +install-utils: utils install-utils-subdirs +ifneq (,$(BINS)) + install -d $(DESTDIR)$(BIN_DIR) + install $(BINS) $(DESTDIR)$(BIN_DIR)/ + install -d $(DESTDIR)$(MAN_DIR) + install -m 644 $(MAN_PAGES) $(DESTDIR)$(MAN_DIR)/ +endif +ifeq (,$(wildcard $(DESTDIR)$(CONFIG_FILE))) + $(INSTALL) -d $(DESTDIR)$(CONFIG_DIR) + $(INSTALL) -m 644 system.conf.sample $(DESTDIR)$(CONFIG_FILE) +endif + install -d $(DESTDIR)$(DATA_DIR) + tar cf - -C hotplug $(ASSIGNED_DATA_SCRIPTS) | tar xf - -C $(DESTDIR)$(DATA_DIR)/ + install $(ASSIGNED_UTILS) $(DESTDIR)/$(BIN_DIR)/ + install -m 644 $(ASSIGNED_CONF) $(DESTDIR)/$(CONFIG_DIR)/ + install -d $(DESTDIR)$(BASH_COMP_DIR) + install -m 644 dahdi-bash-completion $(DESTDIR)$(BASH_COMP_FILE) + +install-libs: libs + $(INSTALL) -d -m 755 $(DESTDIR)/$(LIB_DIR) + $(INSTALL) -m 755 $(LTZ_A) $(DESTDIR)$(LIB_DIR)/ + $(INSTALL) -m 755 $(LTZ_SO) $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) +ifeq (,$(DESTDIR)) + if [ `id -u` = 0 ]; then \ + /sbin/ldconfig || : ;\ + fi +endif + rm -f $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER) + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + # Overwrite the 1.0 links out there. dahdi-tools 2.0.0 installed + # 1.0 links but dahdi-tools changed them to 2.0 in order to explicitly + # break applications linked with zaptel. But, this also meant that + # applications linked with libtonezone.so.1.0 broke when dahdi-tools + # 2.1.0 was installed. + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1.0 + $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ + $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1 +ifneq (no,$(USE_SELINUX)) + ifeq (,$(DESTDIR)) + /sbin/restorecon -v $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) + endif +endif + $(INSTALL) -d -m 755 $(DESTDIR)/$(INC_DIR) + $(INSTALL) -m 644 tonezone.h $(DESTDIR)$(INC_DIR)/ + +install-utils-subdirs: + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir install; \ + done + +install-tests: tests +ifneq (,$(TEST_BINS)) + install -d $(DESTDIR)$(BIN_DIR) + install $(TEST_BINS) $(DESTDIR)$(BIN_DIR)/ +endif + +config: +ifneq (,$(COPY_INITD)) + $(COPY_INITD) +endif +ifeq (,$(wildcard $(DESTDIR)$(RCCONF_FILE))) + $(INSTALL) -D -m 644 init.conf.sample $(DESTDIR)$(RCCONF_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(MODULES_FILE))) + $(INSTALL) -D -m 644 modules.sample $(DESTDIR)$(MODULES_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(GENCONF_FILE))) + $(INSTALL) -D -m 644 xpp/genconf_parameters $(DESTDIR)$(GENCONF_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(MODPROBE_FILE))) + $(INSTALL) -D -m 644 modprobe.conf.sample $(DESTDIR)$(MODPROBE_FILE) +endif +ifeq (,$(wildcard $(DESTDIR)$(BLACKLIST_FILE))) + $(INSTALL) -D -m 644 blacklist.sample $(DESTDIR)$(BLACKLIST_FILE) +endif + $(INSTALL) -d $(DESTDIR)$(UDEVRULES_DIR) + $(INSTALL) -D -m 644 dahdi.rules $(DESTDIR)$(UDEVRULES_DIR)/ +ifneq (,$(COPY_NETSCR)) + $(COPY_NETSCR) +endif +ifneq (,$(ADD_INITD)) + $(ADD_INITD) +endif + @echo "DAHDI has been configured." + @echo "" + @echo "List of detected DAHDI devices:" + @echo "" + @if [ `xpp/dahdi_hardware | tee /dev/stderr | wc -l` -eq 0 ]; then \ + echo "No hardware found"; \ + else \ + echo ""; \ + echo "run 'dahdi_genconf modules' to load support for only " ;\ + echo "the DAHDI hardware installed in this system. By "; \ + echo "default support for all DAHDI hardware is loaded at "; \ + echo "DAHDI start. "; \ + fi + +update: + @if [ -d .svn ]; then \ + echo "Updating from Subversion..." ; \ + svn update | tee update.out; \ + rm -f .version; \ + if [ `grep -c ^C update.out` -gt 0 ]; then \ + echo ; echo "The following files have conflicts:" ; \ + grep ^C update.out | cut -b4- ; \ + fi ; \ + rm -f update.out; \ + else \ + echo "Not under version control"; \ + fi + +dist: + @./build_tools/make_dist "dahdi-tools" "$(TOOLSVERSION)" + +clean: + rm -f $(BINS) $(TEST_BINS) + rm -f *.o dahdi_cfg tzdriver sethdlc + rm -f $(LTZ_SO) $(LTZ_A) *.lo + @for dir in $(SUBDIRS_UTILS_ALL); do \ + $(MAKE) -C $$dir clean; \ + done + @for dir in $(SUBDIRS_UTILS); do \ + $(MAKE) -C $$dir clean; \ + done + rm -f libtonezone* + rm -f fxotune + rm -f core + rm -f dahdi_cfg-shared fxstest + rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt + rm -f dahdi_pcap + +distclean: dist-clean + +dist-clean: clean + rm -f makeopts + rm -f config.log config.status + rm -f .*.d + +config.status: configure + @CFLAGS="" ./configure + @echo "****" + @echo "**** The configure script was just executed, so 'make' needs to be" + @echo "**** restarted." + @echo "****" + @exit 1 + +.PHONY: distclean dist-clean clean all install programs tests devel data config update install-programs install-libs install-utils-subdirs utils-subdirs prereq dist + +FORCE: + +ifneq ($(wildcard .*.d),) + include .*.d +endif diff --git a/README b/README new file mode 100644 index 0000000..2fadf61 --- /dev/null +++ b/README @@ -0,0 +1,371 @@ +DAHDI Telephony Interface Driver +================================= +Asterisk Development Team +$Revision$, $Date$ + +DAHDI stands for Digium Asterisk Hardware Device Interface. This +package contains the user-space tools to configure the kernel modules +included in the package dahdi-linux. + +Build Requirements +------------------ +This package needs the headers from dahdi-linux. Thus you should install +dahdi-linux before building dahdi-tools. + +Build System +~~~~~~~~~~~~ +GCC and friends. Generally you will need to install the package gcc. +There may be cases where you will need a specific version of gcc to build +kernel modules. + + +Extra Libraries +~~~~~~~~~~~~~~~ +Some libraries are needed for extra utilities that are provided with +DAHDI. + +- libusb is needed for building fpga_load, needed for firmware loading of + the Xorcom Astribank. +- libnewt is needed to build the optional but useful utility dahdi_tool. + + +Installation +~~~~~~~~~~~~ +Note: If using `sudo` to build/install, you may need to add /sbin to your PATH. +---------------------------------- +./configure +make +make install +# To install init scripts and config files: +#make config +---------------------------------- + + +Build Tweaks +~~~~~~~~~~~~ +Partial Build/Install +^^^^^^^^^^^^^^^^^^^^^ +There are some make targets that are provided to build or install just +parts of DAHDI: + +. Build targets: + - make: Build DAHDI user-space programs and libraries. partial + targets of it: + * make 'utilname': builds 'utilname' alone (e.g: `make dahdi_diag`) + * make utils: Build just the programs. + * make libs: Build libtonezone. + * make tests: Build testing binaries. +. Install targets: + - make install: Install everything. Sub-targets of it: + * make install-utils: Installs most things. + * make install-libs: Installs libtonezone. + - make config: install configuration files (overriding existing ones). + - make install-test: Install testing binaries. + + +Installation to a Subtree +^^^^^^^^^^^^^^^^^^^^^^^^^ +The following may be useful when testing the package or when preparing a +package for a binary distribution (such as an rpm package) installing +onto a subtree rather than on the real system. + + make install DESTDIR=targetdir + +This can be useful for any partial install target from the list above. + + +Options For ./configure +^^^^^^^^^^^^^^^^^^^^^^^ +The configure script executes various tests and based on them generates +makeopts. You can pass it --with options and variable settings, for +instance: + + ./configure --without-ncurses CC="gcc-4.10" + +If you just want to recreate the same files without a full detection +run, use: + + ./config.status + +To re-run ./configure with the same parameters it was run with last +time, use: + + ./config.status --recheck + + +Configuration +------------- +Configuration for DAHDI resides under /etc/dahdi . + +/etc/dahdi/system.conf +~~~~~~~~~~~~~~~~~~~~~~ +The main method to configure DAHDI devices is using the utility +*dahdi_cfg*. dahdi_cfg reads data from the configuration file +/etc/dahdi/system.conf , figures out what configuration to send to +channels, and send it to the kernel. + +A sample annotated system.conf is included in this directory and +installed by default. Edit it to suit your configuration. Alternatively +use the script dahdi_genconf to generate one that should work with your +system. Note that while dahdi_genconf will generate a working configuration, +it will not automatically detect hardware echo cancellation modules. These +will have to be enabled manually in system.conf. + +/etc/dahdi/init.conf +~~~~~~~~~~~~~~~~~~~~ +The configuration file of the dahdi init.d script is +/etc/dahdi/init.conf . That file is used to override defaults that are +set at the beginning of the init.d script. + +Reference Configuration +~~~~~~~~~~~~~~~~~~~~~~~ +Sample system.conf +^^^^^^^^^^^^^^^^^^ +include::system.conf.asciidoc[] + + +Sample init.conf +^^^^^^^^^^^^^^^^ +include::init.conf.asciidoc[] + + +Sample genconf_parameters +^^^^^^^^^^^^^^^^^^^^^^^^^ +FIXME: still not properly formatted. + +include::genconf_parameters.asciidoc[] + + +Sample assigned-spans.conf +^^^^^^^^^^^^^^^^^^^^^^^^^^ +include::assigned-spans.conf.asciidoc[] + + +Sample span-types.conf +^^^^^^^^^^^^^^^^^^^^^^ +include::span-types.conf.asciidoc[] + + +Tonezones +~~~~~~~~~ +The file zonedata.c contains the information about the tone zones used +in libtonezone (and hence also in dahdi_cfg). Here is a list of those zones: + +include::tonezones.txt[] + + +DAHDI PERL modules +~~~~~~~~~~~~~~~~~~ +The directory xpp has, in addition to helper utilities for the +Xorcom Astribank, a collection of PERL modules to provide information +related to DAHDI. The PERL modules themselves are under xpp/perl_modules/ . +In xpp/ there are several utilities that use those modules: +- xpp-specific: dahdi_registration, xpp_sync, xpp_blink . +- General: lsdahdi, dahdi_genconf, dahdi_hardware, dahdi_drivers + +The DAHDI PERL modules will currently only be automatically installed if you +happen to install the xpp directory. Those utilities require the PERL modules +to be installed, however they will also look for them in the directory +perl_modules, and thus can be run directly from the DAHDI source tree. For +example: + + ./xpp/dahdi_hardware -v + +To get usage information on a program, you can also use perldoc +(sometimes provided in a package separate from perl itself). For +instance: + + perldoc ./xpp/lsdahdi + +Some of them are specific for the Xorcom Astribank and described in its +documentation. the others are: + +lsdahdi:: + A somewhat glorified `cat /proc/dahdi/*`. +dahdi_genconf:: + Generates configuration based on the existing DAHDI channels and on + /etc/dahdi/genconf_parameters (replaces genzaptelconf as well). +dahdi_drivers:: + A two-liner script (not installed by default) that simply returns the + modules that should be modprobe-d on this system. +dahdi_hardware:: + Uses the information from SysFS and its own knowledge to show + what PCI/USB DAHDI hardware is connected and if it is currently used + by a driver. Shows also some more information for Astribanks from + /proc/xpp . + + +PPP Support +~~~~~~~~~~~ +DAHDI digital cards can provide data channels through PPP as +point-to-point connections. This requires a plug-in to the PPP daemon +that is included in the ppp/ subdirectory. To install it: + +1. Make sure you have the PPP source / headers installed. On Debian: + + apt-get install ppp-dev + +2. Run 'make' on the ppp subdirectory: + + make -C ppp + make -C ppp install + +3. Make sure your kernel has support for both PPP (which is common is + distribution kernels and for HDLC (much less common) - CONFIG_PPP and + CONFIG_HDLC . + + +Initialization +-------------- +This section documents the start up sequence of the DAHDI modules. + +There are generally two options: explicit (using an init script) and +implicit (run from UDEV hook scripts). + +Explicit +~~~~~~~~ +The dahdi init scripts does the following tasks: + +* Loading the module dahdi and any other module listed in + /etc/dahdi/modules. +* For xpp (Astribanks) - some specific initializations. See + README.Astribank. +* Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] after all modules were + loaded. +* A number of other tools may need to be run: +** link:doc/fxotune.8.html[fxotune] +** dahdihpec_enable + +Only at this point Asterisk (or any other user of DAHDI) can be run. + + +Implicit +~~~~~~~~ +(Also known as "hot-plug" or "pinned-spans". This requires: + +* dahdi >= 2.8.0 +* Setting the module parameter auto_assign_spans of dahdi to 0 +* (Recommended) Asterisk >= 12 - which supports "dahdi create channels". + +When a device driver of a DAHDI device finishes initialization, it +creates a dahdi_device kernel object. A dahdi_device represents a single +DAHDI device (such as a PCI card) and may have several spans. If the +value of auto_assign_spans is 1 when dahdi_device is created, spans are +assigned automatically - each new span gets the first available span +number and range of channels. However if it is set to 0, spans will not +get assigned, and user space programs need to assign them. The +low-level interface for doing so is explained in the section "Span +Assignment" in the README of DAHDI-Linux. + +New Devices +^^^^^^^^^^^ +When a kernel object is created or destroyed, the kernel sends an event +to user space. Those events are normally handled by udevd. Configurations +for udevd ("udev rules") may be placed in /etc/udev/rules.d or +/lib/udev/rules.d. This package installs rules that instruct udevd to +run the script `/usr/share/dahdi/dahdi_handle_device` on each new +device, which runs all the scripts in `/usr/share/dahdi/handle_device.d`. +Those scripts will: + +* If `/etc/dahdi/span-types.conf` exists, apply it to the device. It is + used for E1/T1/J1 settings. See + <<_sample_span_types_conf,sample span-types.conf>>. + +* If `/etc/dahdi/assigned-spans.conf` exists, assign the span according + to it (if it is not specified there: don't assign it). + used for E1/T1/J1 settings. See + <<_sample_assigned_spans_conf,sample assigned-spans.conf>>. + +* But if that file does not exist, assign the span to the first + available place. + +This script mainly uses the commands +link:doc/dahdi_span_types.8.html[dahdi_span_types] and +link:doc/dahdi_span_assignments.8.html[dahdi_span_assignments]. + +DAHDI devices are listed under `/sys/bus/dahdi_devices/devices`. + +If you want to disable running this script, add the following line to +`/etc/dahdi/init.conf`: +............................. +DAHDI_UDEV_DISABLE_DEVICES=yes +............................. + + +New Spans +^^^^^^^^^ +Once a span is assigned, a kernel object will appear for it. It will be +listed under its device. As a new kernel object was created, an event is +sent to udev. + +The standard DAHDI udev rules instruct udevd to run the script +`/usr/share/dahdi/dahdi_span_config` which runs all the scripts in +`/usr/share/dahdi/span_config.d`. Those script configures the new +span: + +* If system.conf does not exist, generates a temporary configuration + for the span using link:doc/dahdi_genconf.8.html[dahdi_genconf + system]. + +* Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] on the new span (using `-S` + and -C`). + +* Runs `asterisk -rx 'dahdi create channels'` to add the new channels + and spans to Asterisk (if they were configured in advance). + +If you want to disable running this script, add the following line to +`/etc/dahdi/init.conf`: +............................. +DAHDI_UDEV_DISABLE_SPANS=yes +............................. + + +New Channels +^^^^^^^^^^^^ +DAHDI channels have their own representation in the kernel. The standard +udev rules that dahdi-tools includes for them, however, don't run a +script for each device. Each DAHDI channel creates a block device file +at /dev/dahdi/chan/'span'/'rel-chan', where 'span' and 'rel-chan' are +each three-digit numbers (e.g: 035). 'span' is the span number and +'rel-chan' is the channel number relative to the span. + +The udev rules generate the following extra symlinks under /dev/dahdi: + +* /dev/dahdi/'num' - the channel number. As it was originally (but + continues beyond 250). +* /dev/dahdi/devices/'hardware_id'/'rel-span'/'rel-chan' - if the DAHDI + device has a hardware ID field, provide listing of the device's span + and channels. +* /dev/dahdi/devices/@'hardware_id'/'rel-span'/'rel-chan' - likewise for + the connector field. It has a "@" prefix. + + +include::UPGRADE.txt[] + + +License +------- +This package is distributed under the terms of the GNU General Public License +Version 2, except for some components which are distributed under the terms of +the GNU Lesser General Public License Version 2.1. Both licenses are included +in this directory, and each file is clearly marked as to which license applies. + +If you wish to use the DAHDI drivers in an application for which the license +terms are not appropriate (e.g. a proprietary embedded system), licenses under +more flexible terms can be readily obtained through Digium, Inc. at reasonable +cost. + + +Reporting Bugs +-------------- +Please report bug and patches to the Asterisk bug tracker at +http://bugs.digium.com/[] in the "DAHDI" category. + + +Links +----- +- http://asterisk.org/[] - The Asterisk PBX +- http://voip-info.org/[] +- http://voip-info.org/wiki/view/DAHDI[] +- http://docs.tzafrir.org.il/dahdi-tools/README.html[Up-to-date HTML version + of this file] diff --git a/UPGRADE.txt b/UPGRADE.txt new file mode 100644 index 0000000..cd694de --- /dev/null +++ b/UPGRADE.txt @@ -0,0 +1,102 @@ +Upgrade Notes +------------- + +Information for upgrading from Zaptel 1.2 or 1.4 to DAHDI 2.0 + +Upgrading from Zaptel to DAHDI is fairly straightforward; install this +package using the installation instructions, and then reconfigure and +rebuild Asterisk; Asterisk 1.4 releases later than 1.4.21, and all +releases of Asterisk 1.6, will automatically use DAHDI in preference +to Zaptel, even if Zaptel is still installed on the system. + +Important notes about upgrading: + +The Zaptel package, which included both kernel modules and userspace +tools for configuring and managing the modules, has been split into +two packages: + +* dahdi-linux: kernel modules +* dahdi-tools: userspace tools + +In addition, there is a dahdi-linux-complete package that contains both +dahdi-linux and dahdi-tools for simplified installation. + +NOTE: The dahdi-linux and dahdi-tools packages have *separate* +version numbers; they will not be released 'in sync', and it is +perfectly acceptable to use (for example) dahdi-tools 2.0.6 with +dahdi-linux 2.0.11. The dahdi-linux-complete package version number will +always include *both* of these version numbers so that you will know +what is included in it. + + +DAHDI-Linux +~~~~~~~~~~~ +Module Names +^^^^^^^^^^^^ +The primary kernel modules have changed names; the new names are: + + zaptel.ko -> dahdi.ko + ztd-eth.ko -> dahdi_dynamic_eth.ko + ztd-loc.ko -> dahdi_dynamic_loc.ko + ztdummy.ko -> dahdi_dummy.ko + ztdynamic.ko -> dahdi_dynamic.ko + zttranscode.ko -> dahdi_transcode.ko + +* The kernel modules for card drivers have *not* changed names, + although the wcusb and torisa drivers are no longer included. + +* This package no longer includes the 'menuselect' utility for + choosing which modules to build; all modules that can be built are + built automatically. + + +Echo Canceller Modules +^^^^^^^^^^^^^^^^^^^^^^ +It is no longer possible and needed to select a software echo canceler +at compile time to build into dahdi.ko; all four included echo +cancelers (MG2, KB1, SEC and SEC2) are built as loadable modules. +If the Digium HPEC binary object file has been placed into the +proper directory the HPEC module will be built as well. + +Any or all of these modules can be loaded at the same time, and the echo +canceler to be used on the system's channels can be configured using +the dahdi_cfg tool from the dahdi-tools package. + +IMPORTANT: It is *mandatory* to configure an echo canceler for the system's +channels using dahdi_cfg. There is *no* default echo canceler with DAHDI, not +even hardware echo cancellation modules. See +<<_echo_cancellers,section on echo cancellers>> in sample system.conf. + + +DAHDI-Tools +~~~~~~~~~~~ +Many tool names have changed: + + ztcfg -> dahdi_cfg + ztmonitor -> dahdi_monitor + ztscan -> dahdi_scan + ztspeed -> dahdi_speed + zttest -> dahdi_test + zttool -> dahdi_tool + zapconf -> dahdi_genconf (deprecates genzaptelconf) + +* The system configuration file has moved from /etc/zaptel.conf to + <<_sample_system_conf,/etc/dahdi/system.conf>>. + +* The dahdi_cfg tool can now be used to select an echo canceler on a + channel-by-channel basis in the system configuration file; see + system.conf.sample for examples of how to do this. + +* The configuration for XPP init_card_* scripts is done now + in /etc/dahdi/xpp.conf and uses a simple syntax (example included). + For PRI modules, the 'pri_protocol' setting, determines how + to configure it (E1/T1). + +* In Astribank PRI modules, the LED behaviour represents which ports + are *CLOCK MASTER* (red color) and which are *CLOCK SLAVE* (green color). + Usually (but not always), this corresponds to the NT/TE settings in Asterisk. + +* The /etc/sysconfig/zaptel (or /etc/default/zaptel file, depending + on your distribution) is now split into two separate files: + /etc/dahdi/modules control which modules are loaded and module options are + set via /etc/modprobe.d/dahdi. diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..587445e --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,1113 @@ +# Various support functions for configure.ac in asterisk +# + +# Helper function to check for gcc attributes. +# AST_GCC_ATTRIBUTE([attribute name]) + +AC_DEFUN([AST_GCC_ATTRIBUTE], +[ +AC_MSG_CHECKING(for compiler 'attribute $1' support) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([static void __attribute__(($1)) *test(void *muffin, ...) {}], + []), + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]), + AC_MSG_RESULT(no)) +] +CFLAGS="$saved_CFLAGS" +) + +# Helper function to setup variables for a package. +# $1 -> the package name. Used in configure.ac and also as a prefix +# for the variables ($1_DIR, $1_INCLUDE, $1_LIB) in makeopts +# $3 -> option name, used in --with-$3 or --without-$3 when calling configure. +# $2 and $4 are just text describing the package (short and long form) + +# AST_EXT_LIB_SETUP([package], [short description], [configure option name], [long description]) + +AC_DEFUN([AST_EXT_LIB_SETUP], +[ + $1_DESCRIP="$2" + $1_OPTION="$3" + AC_ARG_WITH([$3], AC_HELP_STRING([--with-$3=PATH],[use $2 files in PATH $4]), + [ + case ${withval} in + n|no) + USE_$1=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} $1" + ;; + *) + $1_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} $1" + ;; + esac + ]) + PBX_$1=0 + AC_SUBST([$1_LIB]) + AC_SUBST([$1_INCLUDE]) + AC_SUBST([$1_DIR]) + AC_SUBST([PBX_$1]) +]) + +# Check whether any of the mandatory modules are not present, and +# print error messages in case. The mandatory list is built using +# --with-* arguments when invoking configure. + +AC_DEFUN([AST_CHECK_MANDATORY], +[ + AC_MSG_CHECKING([for mandatory modules: ${ac_mandatory_list}]) + err=0; + for i in ${ac_mandatory_list}; do + eval "a=\${PBX_$i}" + if test "x${a}" = "x1" ; then continue; fi + if test ${err} = "0" ; then AC_MSG_RESULT(fail) ; fi + AC_MSG_RESULT() + eval "a=\${${i}_OPTION}" + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** The $i installation appears to be missing or broken.]) + AC_MSG_NOTICE([*** Either correct the installation, or run configure]) + AC_MSG_NOTICE([*** including --without-${a}.]) + err=1 + done + if test $err = 1 ; then exit 1; fi + AC_MSG_RESULT(ok) +]) + +# The next three functions check for the availability of a given package. +# AST_C_DEFINE_CHECK looks for the presence of a #define in a header file, +# AST_C_COMPILE_CHECK can be used for testing for various items in header files, +# AST_EXT_LIB_CHECK looks for a symbol in a given library, or at least +# for the presence of a header file. +# AST_EXT_TOOL_CHECK looks for a symbol in using $1-config to determine CFLAGS and LIBS +# +# They are only run if PBX_$1 != 1 (where $1 is the package), +# so you can call them multiple times and stop at the first matching one. +# On success, they both set PBX_$1 = 1, set $1_INCLUDE and $1_LIB as applicable, +# and also #define HAVE_$1 1 and #define HAVE_$1_VERSION ${last_argument} +# in autoconfig.h so you can tell which test succeeded. +# They should be called after AST_EXT_LIB_SETUP($1, ...) + +# Check if a given macro is defined in a certain header. + +# AST_C_DEFINE_CHECK([package], [macro name], [header file], [version]) +AC_DEFUN([AST_C_DEFINE_CHECK], +[ + if test "x${PBX_$1}" != "x1"; then + AC_MSG_CHECKING([for $2 in $3]) + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include <$3>], + [#if defined($2) + int foo = 0; + #else + int foo = bar; + #endif + 0 + ])], + [ AC_MSG_RESULT(yes) + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) + ], + [ AC_MSG_RESULT(no) ] + ) + CPPFLAGS="${saved_cppflags}" + fi + AC_SUBST(PBX_$1) +]) + + +# Check if a given expression will compile using a certain header. + +# AST_C_COMPILE_CHECK([package], [expression], [header file], [version]) +AC_DEFUN([AST_C_COMPILE_CHECK], +[ + if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + AC_MSG_CHECKING([if "$2" compiles using $3]) + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include <$3>], + [ $2; ] + )], + [ AC_MSG_RESULT(yes) + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) + ], + [ AC_MSG_RESULT(no) ] + ) + CPPFLAGS="${saved_cppflags}" + fi +]) + + +# Check for existence of a given package ($1), either looking up a function +# in a library, or, if no function is supplied, only check for the +# existence of the header files. + +# AST_EXT_LIB_CHECK([package], [library], [function], [header], +# [extra libs], [extra cflags], [version]) +AC_DEFUN([AST_EXT_LIB_CHECK], +[ +if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + pbxlibdir="" + # if --with-$1=DIR has been specified, use it. + if test "x${$1_DIR}" != "x"; then + if test -d ${$1_DIR}/lib; then + pbxlibdir="-L${$1_DIR}/lib" + else + pbxlibdir="-L${$1_DIR}" + fi + fi + pbxfuncname="$3" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_$1_FOUND=yes + else + AC_CHECK_LIB([$2], [${pbxfuncname}], [AST_$1_FOUND=yes], [AST_$1_FOUND=no], ${pbxlibdir} $5) + fi + + # now check for the header. + if test "${AST_$1_FOUND}" = "yes"; then + $1_LIB="${pbxlibdir} -l$2 $5" + # if --with-$1=DIR has been specified, use it. + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + $1_INCLUDE="${$1_INCLUDE} $6" + if test "x$4" = "x" ; then # no header, assume found + $1_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE} $6" + AC_CHECK_HEADER([$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0]) + CPPFLAGS="${saved_cppflags}" + fi + if test "x${$1_HEADER_FOUND}" = "x0" ; then + $1_LIB="" + $1_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + $1_LIB="" + fi + PBX_$1=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + AC_DEFINE_UNQUOTED([HAVE_$1], 1, [Define this to indicate the ${$1_DESCRIP} library]) + AC_DEFINE_UNQUOTED([HAVE_$1_VERSION], [$7], [Define to indicate the ${$1_DESCRIP} library version]) + fi + fi +fi +]) + + +# Check for a package using $2-config. Similar to AST_EXT_LIB_CHECK, +# but use $2-config to determine cflags and libraries to use. +# $3 and $4 can be used to replace --cflags and --libs in the request + +# AST_EXT_TOOL_CHECK([package], [tool name], [--cflags], [--libs], [includes], [expression]) +AC_DEFUN([AST_EXT_TOOL_CHECK], +[ + if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + PBX_$1=0 + AC_CHECK_TOOL(CONFIG_$1, $2-config, No) + if test ! "x${CONFIG_$1}" = xNo; then + if test x"$3" = x ; then A=--cflags ; else A="$3" ; fi + $1_INCLUDE=$(${CONFIG_$1} $A) + if test x"$4" = x ; then A=--libs ; else A="$4" ; fi + $1_LIB=$(${CONFIG_$1} $A) + if test x"$5" != x ; then + saved_cppflags="${CPPFLAGS}" + if test "x${$1_DIR}" != "x"; then + $1_INCLUDE="-I${$1_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" + + saved_ldflags="${LDFLAGS}" + LDFLAGS="${$1_LIB}" + + AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( [ $5 ], + [ $6; ] + )], + [ PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) + ], + [] + ) + CPPFLAGS="${saved_cppflags}" + LDFLAGS="${saved_ldflags}" + else + PBX_$1=1 + AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 libraries.]) + fi + fi + fi +]) + +AC_DEFUN([AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK([for GNU make], [ac_cv_GNU_MAKE], + ac_cv_GNU_MAKE='Not Found' ; + ac_cv_GNU_MAKE_VERSION_MAJOR=0 ; + ac_cv_GNU_MAKE_VERSION_MINOR=0 ; + for a in make gmake gnumake ; do + if test -z "$a" ; then continue ; fi ; + if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then + ac_cv_GNU_MAKE=$a ; + ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'` + ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2` + break; + fi + done ; +) ; +if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then + AC_MSG_ERROR( *** Please install GNU make. It is required to build Asterisk!) + exit 1 +fi +AC_SUBST([GNU_MAKE], [$ac_cv_GNU_MAKE]) +]) + +AC_DEFUN( +[AST_CHECK_PWLIB], [ +PWLIB_INCDIR= +PWLIB_LIBDIR= +AC_LANG_PUSH([C++]) +if test "${PWLIBDIR:-unset}" != "unset" ; then + AC_CHECK_HEADER(${PWLIBDIR}/version.h, HAS_PWLIB=1, ) +fi +if test "${HAS_PWLIB:-unset}" = "unset" ; then + if test "${OPENH323DIR:-unset}" != "unset"; then + AC_CHECK_HEADER(${OPENH323DIR}/../pwlib/version.h, HAS_PWLIB=1, ) + fi + if test "${HAS_PWLIB:-unset}" != "unset" ; then + PWLIBDIR="${OPENH323DIR}/../pwlib" + else + AC_CHECK_HEADER(${HOME}/pwlib/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + PWLIBDIR="${HOME}/pwlib" + else + AC_CHECK_HEADER(/usr/local/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin) + if test "${PTLIB_CONFIG:-unset}" = "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make) + fi + PWLIB_INCDIR="/usr/local/include" + PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/local/lib64" + else + PWLIB_LIBDIR="/usr/local/lib" + fi + fi + PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` + PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" + else + AC_CHECK_HEADER(/usr/include/ptlib.h, HAS_PWLIB=1, ) + if test "${HAS_PWLIB:-unset}" != "unset" ; then + AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make) + PWLIB_INCDIR="/usr/include" + PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/lib64" + else + PWLIB_LIBDIR="/usr/lib" + fi + fi + PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` + PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" + fi + fi + fi + fi +fi + +#if test "${HAS_PWLIB:-unset}" = "unset" ; then +# echo "Cannot find pwlib - please install or set PWLIBDIR and try again" +# exit +#fi + +if test "${HAS_PWLIB:-unset}" != "unset" ; then + if test "${PWLIBDIR:-unset}" = "unset" ; then + if test "${PTLIB_CONFIG:-unset}" != "unset" ; then + PWLIBDIR=`$PTLIB_CONFIG --prefix` + else + echo "Cannot find ptlib-config - please install and try again" + exit + fi + fi + + if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then + PWLIBDIR="/usr/share/pwlib" + PWLIB_INCDIR="/usr/include" + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/lib64" + else + PWLIB_LIBDIR="/usr/lib" + fi + fi + if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then + PWLIBDIR="/usr/local/share/pwlib" + PWLIB_INCDIR="/usr/local/include" + if test "x$LIB64" != "x"; then + PWLIB_LIBDIR="/usr/local/lib64" + else + PWLIB_LIBDIR="/usr/local/lib" + fi + fi + + if test "${PWLIB_INCDIR:-unset}" = "unset"; then + PWLIB_INCDIR="${PWLIBDIR}/include" + fi + if test "${PWLIB_LIBDIR:-unset}" = "unset"; then + PWLIB_LIBDIR="${PWLIBDIR}/lib" + fi + + AC_SUBST([PWLIBDIR]) + AC_SUBST([PWLIB_INCDIR]) + AC_SUBST([PWLIB_LIBDIR]) +fi + AC_LANG_POP([C++]) +]) + + +AC_DEFUN( +[AST_CHECK_OPENH323_PLATFORM], [ +PWLIB_OSTYPE= +case "$host_os" in + linux*) PWLIB_OSTYPE=linux ; + ;; + freebsd* ) PWLIB_OSTYPE=FreeBSD ; + ;; + openbsd* ) PWLIB_OSTYPE=OpenBSD ; + ENDLDLIBS="-lossaudio" ; + ;; + netbsd* ) PWLIB_OSTYPE=NetBSD ; + ENDLDLIBS="-lossaudio" ; + ;; + solaris* | sunos* ) PWLIB_OSTYPE=solaris ; + ;; + darwin* ) PWLIB_OSTYPE=Darwin ; + ;; + beos*) PWLIB_OSTYPE=beos ; + STDCCFLAGS="$STDCCFLAGS -D__BEOS__" + ;; + cygwin*) PWLIB_OSTYPE=cygwin ; + ;; + mingw*) PWLIB_OSTYPE=mingw ; + STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ; + ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ; + ;; + * ) PWLIB_OSTYPE="$host_os" ; + AC_MSG_WARN("OS $PWLIB_OSTYPE not recognized - proceed with caution!") ; + ;; +esac + +PWLIB_MACHTYPE= +case "$host_cpu" in + x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86 + ;; + + x86_64) PWLIB_MACHTYPE=x86_64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ; + P_64BIT=1 ; + ;; + + sparc ) PWLIB_MACHTYPE=sparc ; + ;; + + powerpc ) PWLIB_MACHTYPE=ppc ; + ;; + + ppc ) PWLIB_MACHTYPE=ppc ; + ;; + + powerpc64 ) PWLIB_MACHTYPE=ppc64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + ppc64 ) PWLIB_MACHTYPE=ppc64 ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + ia64) PWLIB_MACHTYPE=ia64 ; + P_64BIT=1 ; + ;; + + s390x) PWLIB_MACHTYPE=s390x ; + P_64BIT=1 ; + LIB64=1 ; + ;; + + s390) PWLIB_MACHTYPE=s390 ; + ;; + + * ) PWLIB_MACHTYPE="$host_cpu"; + AC_MSG_WARN("CPU $PWLIB_MACHTYPE not recognized - proceed with caution!") ;; +esac + +PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}" + +AC_SUBST([PWLIB_PLATFORM]) +]) + + +AC_DEFUN( +[AST_CHECK_OPENH323], [ +OPENH323_INCDIR= +OPENH323_LIBDIR= +AC_LANG_PUSH([C++]) +if test "${OPENH323DIR:-unset}" != "unset" ; then + AC_CHECK_HEADER(${OPENH323DIR}/version.h, HAS_OPENH323=1, ) +fi +if test "${HAS_OPENH323:-unset}" = "unset" ; then + AC_CHECK_HEADER(${PWLIBDIR}/../openh323/version.h, OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1, ) + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="${PWLIBDIR}/../openh323" + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR}/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(${OPENH323DIR}/include/h323.h, , OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}", [#include ]) + CPPFLAGS="${saved_cppflags}" + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I${HOME}/openh323/include -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(${HOME}/openh323/include/h323.h, HAS_OPENH323=1, ) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="${HOME}/openh323" + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(/usr/local/include/openh323/h323.h, HAS_OPENH323=1, ) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="/usr/local/share/openh323" + OPENH323_INCDIR="/usr/local/include/openh323" + if test "x$LIB64" != "x"; then + OPENH323_LIBDIR="/usr/local/lib64" + else + OPENH323_LIBDIR="/usr/local/lib" + fi + else + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}" + AC_CHECK_HEADER(/usr/include/openh323/h323.h, HAS_OPENH323=1, , [#include ]) + CPPFLAGS="${saved_cppflags}" + if test "${HAS_OPENH323:-unset}" != "unset" ; then + OPENH323DIR="/usr/share/openh323" + OPENH323_INCDIR="/usr/include/openh323" + if test "x$LIB64" != "x"; then + OPENH323_LIBDIR="/usr/lib64" + else + OPENH323_LIBDIR="/usr/lib" + fi + fi + fi + fi + fi +fi + +if test "${HAS_OPENH323:-unset}" != "unset" ; then + if test "${OPENH323_INCDIR:-unset}" = "unset"; then + OPENH323_INCDIR="${OPENH323DIR}/include" + fi + if test "${OPENH323_LIBDIR:-unset}" = "unset"; then + OPENH323_LIBDIR="${OPENH323DIR}/lib" + fi + + OPENH323_LIBDIR="`cd ${OPENH323_LIBDIR}; pwd`" + OPENH323_INCDIR="`cd ${OPENH323_INCDIR}; pwd`" + OPENH323DIR="`cd ${OPENH323DIR}; pwd`" + + AC_SUBST([OPENH323DIR]) + AC_SUBST([OPENH323_INCDIR]) + AC_SUBST([OPENH323_LIBDIR]) +fi + AC_LANG_POP([C++]) +]) + + +AC_DEFUN( +[AST_CHECK_PWLIB_VERSION], [ + if test "${HAS_$2:-unset}" != "unset"; then + $2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | cut -f2 -d ' ' | sed -e 's/"//g'` + $2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.` + $2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.` + $2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.` + let $2_VER=${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER} + let $2_REQ=$4*10000+$5*100+$6 + + AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323) + if test ${$2_VER} -lt ${$2_REQ}; then + AC_MSG_RESULT(no) + unset HAS_$2 + else + AC_MSG_RESULT(yes) + fi + fi +]) + + +AC_DEFUN( +[AST_CHECK_PWLIB_BUILD], [ + if test "${HAS_$2:-unset}" != "unset"; then + AC_MSG_CHECKING($1 installation validity) + + saved_cppflags="${CPPFLAGS}" + saved_libs="${LIBS}" + if test "${$2_LIB:-unset}" != "unset"; then + LIBS="${LIBS} ${$2_LIB} $7" + else + LIBS="${LIBS} -L${$2_LIBDIR} -l${PLATFORM_$2} $7" + fi + CPPFLAGS="${CPPFLAGS} -I${$2_INCDIR} $6" + + AC_LANG_PUSH([C++]) + + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([$4],[$5])], + [ AC_MSG_RESULT(yes) + ac_cv_lib_$2="yes" + ], + [ AC_MSG_RESULT(no) + ac_cv_lib_$2="no" + ] + ) + + AC_LANG_POP([C++]) + + LIBS="${saved_libs}" + CPPFLAGS="${saved_cppflags}" + + if test "${ac_cv_lib_$2}" = "yes"; then + if test "${$2_LIB:-undef}" = "undef"; then + if test "${$2_LIBDIR}" != "" -a "${$2_LIBDIR}" != "/usr/lib"; then + $2_LIB="-L${$2_LIBDIR} -l${PLATFORM_$2}" + else + $2_LIB="-l${PLATFORM_$2}" + fi + fi + if test "${$2_INCDIR}" != "" -a "${$2_INCDIR}" != "/usr/include"; then + $2_INCLUDE="-I${$2_INCDIR}" + fi + PBX_$2=1 + AC_DEFINE([HAVE_$2], 1, [$3]) + fi + fi +]) + +AC_DEFUN( +[AST_CHECK_OPENH323_BUILD], [ + if test "${HAS_OPENH323:-unset}" != "unset"; then + AC_MSG_CHECKING(OpenH323 build option) + OPENH323_SUFFIX= + prefixes="h323_${PWLIB_PLATFORM}_ h323_ openh323" + for pfx in $prefixes; do + files=`ls -l ${OPENH323_LIBDIR}/lib${pfx}*.so* 2>/dev/null` + libfile= + if test -n "$files"; then + for f in $files; do + if test -f $f -a ! -L $f; then + libfile=`basename $f` + break; + fi + done + fi + if test -n "$libfile"; then + OPENH323_PREFIX=$pfx + break; + fi + done + if test "${libfile:-unset}" != "unset"; then + OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/lib${OPENH323_PREFIX}\(@<:@^.@:>@*\)\..*/\1/'"` + fi + case "${OPENH323_SUFFIX}" in + n) + OPENH323_BUILD="notrace";; + r) + OPENH323_BUILD="opt";; + d) + OPENH323_BUILD="debug";; + *) + if test "${OPENH323_PREFIX:-undef}" = "openh323"; then + notrace=`eval "grep NOTRACE ${OPENH323DIR}/openh323u.mak | grep = | sed -e 's/@<:@A-Z0-9_@:>@*@<:@ @:>@*=@<:@ @:>@*//'"` + if test "x$notrace" = "x"; then + notrace="0" + fi + if test "$notrace" -ne 0; then + OPENH323_BUILD="notrace" + else + OPENH323_BUILD="opt" + fi + OPENH323_LIB="-l${OPENH323_PREFIX}" + else + OPENH323_BUILD="notrace" + fi + ;; + esac + AC_MSG_RESULT(${OPENH323_BUILD}) + + AC_SUBST([OPENH323_SUFFIX]) + AC_SUBST([OPENH323_BUILD]) + fi +]) + + +# AST_FUNC_FORK +# ------------- +AN_FUNCTION([fork], [AST_FUNC_FORK]) +AN_FUNCTION([vfork], [AST_FUNC_FORK]) +AC_DEFUN([AST_FUNC_FORK], +[AC_REQUIRE([AC_TYPE_PID_T])dnl +AC_CHECK_HEADERS(vfork.h) +AC_CHECK_FUNCS(fork vfork) +if test "x$ac_cv_func_fork" = xyes; then + _AST_FUNC_FORK +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp* | *-*-uclinux* | *-*-linux-uclibc* ) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + AC_MSG_WARN([result $ac_cv_func_fork_works guessed because of cross compilation]) +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + _AC_FUNC_VFORK +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + AC_MSG_WARN([result $ac_cv_func_vfork_works guessed because of cross compilation]) +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + AC_DEFINE(HAVE_WORKING_VFORK, 1, [Define to 1 if `vfork' works.]) +else + AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.]) +fi +if test "x$ac_cv_func_fork_works" = xyes; then + AC_DEFINE(HAVE_WORKING_FORK, 1, [Define to 1 if `fork' works.]) +fi +])# AST_FUNC_FORK + + +# _AST_FUNC_FORK +# ------------- +AC_DEFUN([_AST_FUNC_FORK], + [AC_CACHE_CHECK(for working fork, ac_cv_func_fork_works, + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], + [ + /* By Ruediger Kuhlmann. */ + return fork () < 0; + ])], + [ac_cv_func_fork_works=yes], + [ac_cv_func_fork_works=no], + [ac_cv_func_fork_works=cross])])] +)# _AST_FUNC_FORK + +# AST_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AST_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([AST_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) # AST_PROG_EGREP + +# AST_PROG_SED +# ----------- +# Check for a fully functional sed program that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([AST_PROG_SED], +[AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED, + [dnl ac_script should not contain more than 99 commands (for HP-UX sed), + dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed. + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" | sed 99q >conftest.sed + $as_unset ac_script || ac_script= + _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed], + [_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED], + ["$ac_path_SED" -f conftest.sed])])]) + SED="$ac_cv_path_SED" + AC_SUBST([SED])dnl + rm -f conftest.sed +])# AST_PROG_SED + +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException + +AC_DEFUN([ACX_PTHREAD], +[ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/assigned-spans.conf.sample b/assigned-spans.conf.sample new file mode 100644 index 0000000..6f83aac --- /dev/null +++ b/assigned-spans.conf.sample @@ -0,0 +1,57 @@ +# +# /etc/dahdi/assigned-spans.conf: +# +# This file assigns span and channel numbers to dahdi devices +# +# Built as a table keyed by : +# .... +# +# Where: +# * The field may be either: +# hardware_id +# @location +# devpath (in sysfs) +# * Shell-style globbing is allowed for the field +# * There may one or more of +# * Each is composed as: +# :: +# +# Examples: + +# Astribank with two spans: +# FXS * 8 channels + 4 digital inputs 2 digital outputs +# FXO * 8 channels +#usb:QA-1 1:1:1 +#usb:QA-1 2:2:15 + +# Same Astribank in one-liner +#usb:QA-1 1:1:1 2:2:15 + +# Astribank with 4*PRI spans and 3*FXS*8 spans +# Note that channels are NOT globally contigous +# each span get its own 50 numbers. Also, skip +# Channel number 250... +#usb:INT03165 1:1:1 # E1 +#usb:INT03165 2:2:51 # E1 +#usb:INT03165 3:3:151 # E1 +#usb:INT03165 4:4:201 # E1 +#usb:INT03165 5:5:301 # FXS * 8 channels +#usb:INT03165 6:6:351 # FXS * 8 channels +#usb:INT03165 7:7:401 # FXS * 8 channels + +# Alternatively -- all in one-line +#usb:INT03165 1:1:1 2:2:51 3:3:151 4:4:201 5:5:301 6:6:351 7:7:401 + +# Astribank with 4*BRI without hardware_id :-( +# We use the location on the bus (ie: where it is physically +# located). Note the '@' prefix that indicate the location key. +#@usb-0000:00:1d.7-3 1:1:50 +#@usb-0000:00:1d.7-3 2:2:100 +#@usb-0000:00:1d.7-3 3:3:150 +#@usb-0000:00:1d.7-3 4:4:200 + +# Same configuration with globbing: +#/sys/*/usb1/1-6/* 1:1:50 +#/sys/*/usb1/1-6/* 2:2:100 +#/sys/*/usb1/1-6/* 3:3:150 +#/sys/*/usb1/1-6/* 4:4:200 diff --git a/autoconfig.h.in b/autoconfig.h.in new file mode 100644 index 0000000..67aef05 --- /dev/null +++ b/autoconfig.h.in @@ -0,0 +1,114 @@ +/* autoconfig.h.in. Generated from configure.ac by autoheader. */ + +/* Define if your system has the DAHDI headers. */ +#undef HAVE_DAHDI + +/* Define if your system has the DAHDI23 headers. */ +#undef HAVE_DAHDI23 + +/* Define DAHDI23 headers version */ +#undef HAVE_DAHDI23_VERSION + +/* Define DAHDI headers version */ +#undef HAVE_DAHDI_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_SOUNDCARD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define this to indicate the ${NEWT_DESCRIP} library */ +#undef HAVE_NEWT + +/* Define to indicate the ${NEWT_DESCRIP} library version */ +#undef HAVE_NEWT_VERSION + +/* Define to 1 if you have the `semtimedop' function. */ +#undef HAVE_SEMTIMEDOP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOUNDCARD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define this to indicate the ${USB_DESCRIP} library */ +#undef HAVE_USB + +/* Define to indicate the ${USB_DESCRIP} library version */ +#undef HAVE_USB_VERSION + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/bittest.h b/bittest.h new file mode 100644 index 0000000..c9b9eb2 --- /dev/null +++ b/bittest.h @@ -0,0 +1,17 @@ +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +static int bit_next(int prev) +{ + return (prev + 1) % 256; +} diff --git a/blacklist.sample b/blacklist.sample new file mode 100644 index 0000000..f054e28 --- /dev/null +++ b/blacklist.sample @@ -0,0 +1,23 @@ +# blacklist all the drivers by default in order to ensure that +# /etc/init.d/dahdi installs them in the correct order so that the spans are +# ordered consistently. + +blacklist wct4xxp +blacklist wcte12xp +blacklist wcte13xp +blacklist wct1xxp +blacklist wcte11xp +blacklist wctdm24xxp +blacklist wcfxo +blacklist wctdm +blacklist wctc4xxp +blacklist wcb4xxp +blacklist wcaxx +blacklist wcte43x + +# Some mISDN drivers may try to attach to cards supported by DAHDI. If you +# have a card which is *not* supported by DAHDI but supported by one of the +# below drivers you should feel free to remove it from the blacklist below. +blacklist hfcmulti +blacklist netjet +blacklist hfcpci diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..570d66c --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +check_for_app() { + $1 --version 2>&1 >/dev/null + if [ $? != 0 ] + then + echo "Please install $1 and run bootstrap.sh again!" + exit 1 + fi +} + +# On FreeBSD and OpenBSD, multiple autoconf/automake versions have different names. +# On linux, envitonment variables tell which one to use. + +uname -s | grep -q BSD +if [ $? = 0 ] ; then # BSD case + case `uname -sr` in + 'FreeBSD 4'*) # FreeBSD 4.x has a different naming + MY_AC_VER=259 + MY_AM_VER=19 + ;; + *) + MY_AC_VER=-2.62 + MY_AM_VER=-1.9 + ;; + esac +else # linux case + MY_AC_VER= + MY_AM_VER= + AUTOCONF_VERSION=2.60 + AUTOMAKE_VERSION=1.9 + export AUTOCONF_VERSION + export AUTOMAKE_VERSION +fi + +check_for_app autoconf${MY_AC_VER} +check_for_app autoheader${MY_AC_VER} +check_for_app automake${MY_AM_VER} +check_for_app aclocal${MY_AM_VER} + +echo "Generating the configure script ..." + +aclocal${MY_AM_VER} +autoconf${MY_AC_VER} +autoheader${MY_AC_VER} +automake${MY_AM_VER} --add-missing --copy 2>/dev/null + +exit 0 diff --git a/build_tools/dahdi_svn_tarball b/build_tools/dahdi_svn_tarball new file mode 100755 index 0000000..7667951 --- /dev/null +++ b/build_tools/dahdi_svn_tarball @@ -0,0 +1,90 @@ +#!/bin/sh + +# upload_dahdi: upload a dahdi tarball to updates.xorcom.com +# + +set -e + +BRANCH_NAME=1.4 +REV=HEAD +DAHDI_BASE=http://svn.digium.com/svn/dahdi +TARBALLS_DIR=$PWD + +me=`basename $0` + +say() { + echo "$me: $@" +} + +usage() { + echo >&2 "$0: Generate snapshot from DAHDI SVN" + echo >&2 ' ($Id$)' + echo >&2 "" + echo >&2 "$0 [-r REV] [-2] [-s]" + echo >&2 "$0 <-h | --help>: This message" + echo >&2 "" + echo >&2 "Options:" + echo >&2 " -2 --dahdi12: Use Asterisk 1.2. Implies -u." + echo >&2 " -r --rev REV: extract xpp-dahdi from this revision ($REV)." + echo >&2 " -s --show: Just show versions. Do nothing" + +} + +opt_showonly=no + +options=`getopt -o 2hr:s --long dahdi12,help,rev:,revision:,show -- "$@"` +if [ $? != 0 ] ; then echo >&2 "Terminating..." ; exit 1 ; fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$options" + +while true ; do + case "$1" in + -2|--dahdi12) BRANCH_NAME=1.2;; + -s|--show) opt_showonly=yes ;; + -r|--rev|--revision) REV="$2"; shift ;; + -h|--help) usage; exit 0;; + --) shift ; break ;; + esac + shift; +done + +BRANCH=branches/$BRANCH_NAME +DAHDI_URL=$DAHDI_BASE/$BRANCH + +set -e + +# Get the name of the "previous version" for this release. +# The idea is to look at the latest tag for that branhch. Tags are +# global, and hence we filter tag names by branch name. +# +# Note: this strips any minor version number. +# e.g: if last releast was 1.4.5.1, this will still return 1.4.5 . Here +# we rely on the fact that the revision number will be added. +dahdi_ver=`svn ls -r $REV $DAHDI_BASE/tags | grep "^$BRANCH_NAME" \ + | sed -e "s/\($BRANCH_NAME\.[0-9]\+\)[/.-].*/\1/" \ + | sort -nu -t . -k 3 | tail -n 1` + +real_rev=`svn info -r $REV $DAHDI_URL \ + | awk '/^Last Changed Rev: /{print $4}'` + +ver_full="$dahdi_ver.9.svn.$real_rev" +tar_name="dahdi-$ver_full" +tar_ball_full="$TARBALLS_DIR/$tar_name.tar.gz" + +say "Version: $ver_full (ver: $dahdi_ver, rev: $real_rev)" +say "Tarball: $tar_ball_full" + +if [ "$opt_showonly" = 'yes' ]; then + exit 0; +fi + +DAHDI_CHECKOUT_DIR=`mktemp -d dahdi_checkout_dir_XXXXXX` + +# Package a tarball from the subversion, using 'make dist': +svn export -q -r $REV $DAHDI_URL $DAHDI_CHECKOUT_DIR/$tar_name +echo "$ver_full" >$DAHDI_CHECKOUT_DIR/$tar_name/.version +tar cz -C $DAHDI_CHECKOUT_DIR -f $tar_ball_full $tar_name + +rm -rf $DAHDI_CHECKOUT_DIR + diff --git a/build_tools/dahdi_sysfs_copy b/build_tools/dahdi_sysfs_copy new file mode 100755 index 0000000..3460bb9 --- /dev/null +++ b/build_tools/dahdi_sysfs_copy @@ -0,0 +1,142 @@ +#! /usr/bin/perl +# +# Written by Oron Peled +# Copyright (C) 2012, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +#dahdi_sysfs_copy: Short perl script to copy dahdi related sysfs trees +# into a designated directory. +# +# $Id: $ +# +use strict; +use warnings; + +use File::Path qw(mkpath); +use File::Copy; +use Cwd qw(realpath); + +my $destdir = shift || die "Usage: $0 \n"; + +my %symlinks; +my %walk_ups; +my %inode_cash; + +# Starting points for recursion +my @toplevels = qw( + /sys/bus/dahdi_devices + /sys/bus/astribanks + /sys/class/dahdi + ); + +# Loop prevention (by inode number lookup) +sub seen { + my $ino = shift || die; + my $path = shift || die; + if(defined $inode_cash{$ino}) { + #print STDERR "DEBUG($ino): $path\n"; + return 1; + } + $inode_cash{$ino}++; + return 0; +} + +# Walk up a path and copy readable attributes from any +# directory level. +sub walk_up { + my $path = shift || die; + my $curr = $path; + # Walk up + for (my $curr = $path; $curr; $curr =~ s'/?[^/]+$'') { + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($curr); + next if seen($ino, $curr); # Skip visited directories + # Scan directory + opendir(my $d, $curr) || die "Failed opendir($curr): $!\n"; + my @entries = readdir $d; + foreach my $entry (@entries) { + next if $entry =~ /^[.][.]?$/; + my $file = "$curr/$entry"; + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($file); + # Copy file + if (-f _ && ($mode & 0004)) { # The '-r _' is buggy + copy($file, "$destdir$file") || + die "Failed to copy '$file': $!\n"; + } + } + closedir $d; + } +} + +# Handle a given path (directory,symlink,regular-file) +sub handle_path { + my $path = shift || die; + my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($path); + # Save attributes before recursion starts + my $isdir = -d _; + my $islink = -l _; + my $isreadable = $mode & 00004; # The '-r _' was buggy + return if seen($ino, $path); # Loop prevention + my $dest = "$destdir/$path"; + if ($isdir) { + mkpath("$dest"); + scan_directory($path); + } elsif ($islink) { + # We follow links (the seen() protect us from loops) + my $target = readlink($path) || + die "Failed readlink($path): $!\n"; + my $follow = $target; + if ($target !~ m{^/}) { # fix relative symlinks + my $dir = $path; + $dir =~ s,/[^/]*$,,; + $follow = realpath("$dir/$target"); + } + # Save symlink details, so we create them after all + # destination tree (subdirectories, files) is ready + die "Duplicate entry '$dest'\n" if exists $symlinks{$dest}; + $symlinks{$dest} = "$target"; + # Now follow symlink + handle_path($follow); + $walk_ups{$follow}++; + } elsif ($isreadable) { + copy($path, "$dest") || + die "Failed to copy '$path': $!\n"; + } +} + +# Scan a given directory (calling handle_path for recursion) +sub scan_directory { + my $dir = shift || die; + my $entry; + opendir(my $d, $dir) || die "Failed opendir($dir): $!\n"; + my @dirs = readdir $d; + foreach my $entry (@dirs) { + next if $entry =~ /^[.][.]?$/; + handle_path("$dir/$entry"); + } + closedir $d; +} + +# Filter out non-existing toplevels +my @scan = grep { lstat($_) } @toplevels; + +# Recurse all trees, creating subdirectories and copying files +foreach my $path (@scan) { + handle_path($path); +} + +# Now, that all sub-directories were created, we can +# create the wanted symlinks +for my $dest (keys %symlinks) { + my $link = $symlinks{$dest}; + die "Missing link for '$dest'\n" unless defined $link; + unlink $dest if -l $dest; + symlink($link,$dest) || + die "Failed symlink($link,$dest): $!\n"; +} + +# Walk up directories that were symlink destinations +# and fill their attributes +foreach my $dir (keys %walk_ups) { + walk_up($dir); +} diff --git a/build_tools/dump_sys_state b/build_tools/dump_sys_state new file mode 100755 index 0000000..12e864f --- /dev/null +++ b/build_tools/dump_sys_state @@ -0,0 +1,76 @@ +#!/bin/sh + +# dump_sys_state: dump some /sys and /proc files to a directory. +# $Id$ +# +# Written by Tzafrir Cohen +# Copyright (C) 2009, Xorcom +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA + +# The DAHDI-perl modules will use such a dump instead of the files from +# the real system if DAHDI_VIRT_TOP is set to the root. +# +# ./build_tools/dump_sys_state my_sys_state +# +# # And then later: +# DAHDI_VIRT_TOP="$PWD/my_sys_state" dahdi_genconf + +mydir=`dirname $0` +dahdi_sysfs_copy="$mydir/dahdi_sysfs_copy" + +# Give usage message on expected texts + +if [ "$#" -ne 0 ]; then + echo >&2 "Usage: $0" + exit 1 +fi + +id="sys_dump.`hostname`_`date +%F_%H.%M.%S`" +tarball="$id.tar.gz" + +tmpdir=`mktemp -td 'dahdi_dump.XXXXXX'` +echo -n >&2 "Creating ... " +trap "[ -d '$tmpdir' ] && rm -rf '$tmpdir'" 0 1 2 15 + +topdir="$tmpdir/$id" + +if [ -r /proc/bus/usb/devices ]; then + mkdir -p "$topdir/proc/bus/usb" + cp -a /proc/bus/usb/devices "$topdir/proc/bus/usb/" +fi + +if [ -d /proc/dahdi ]; then + mkdir -p "$topdir/proc/dahdi" + if find /proc/dahdi -type f >/dev/null; then + cp -a /proc/dahdi/* "$topdir/proc/dahdi/" + fi +fi + +if [ -d /proc/xpp ]; then + mkdir -p "$topdir/proc/xpp" + if find /proc/xpp -type f >/dev/null; then + cp -a /proc/xpp/* "$topdir/proc/xpp/" + find "$topdir/proc/xpp" -type f -name command -exec rm -f '{}' ';' + fi +fi + +"$dahdi_sysfs_copy" "$topdir" +echo -n >&2 "tarball ... " +( cd "$tmpdir" && tar czf - . ) > "$tarball"; +echo >&2 "ready in '$tarball'" diff --git a/build_tools/make_dist b/build_tools/make_dist new file mode 100755 index 0000000..6c9d453 --- /dev/null +++ b/build_tools/make_dist @@ -0,0 +1,26 @@ +#! /bin/sh + +if [ "$#" -ne 2 ]; then + echo >&2 "Usage: $0 " + exit 1 +fi +package="$1" +version="$2" +tarball_prefix="$package-$version" +echo "I: Making dist tarball for $tarball_prefix" +tarball_name="$tarball_prefix.tar.gz" + +tmp_work_dir=".tmp" +tmp_version_dir="$tmp_work_dir/$tarball_prefix" + +if [ "$DESTDIR" != '' ]; then + destdir="$DESTDIR/" +fi +output="$destdir$tarball_name" + +mkdir -p "$tmp_version_dir" +git archive --format tar HEAD | tar xf - -C "$tmp_version_dir" +echo "$version" > "$tmp_version_dir/.version" +tar czf "$output" -C "$tmp_work_dir" "$tarball_prefix" +rm -rf "$tmp_work_dir" +echo "I: tarball is ready: '$output'" diff --git a/build_tools/make_firmware_object.in b/build_tools/make_firmware_object.in new file mode 100755 index 0000000..1c301a4 --- /dev/null +++ b/build_tools/make_firmware_object.in @@ -0,0 +1,11 @@ +#!/bin/sh -e + +# make an object file from a raw binary firmware file +# arguments: +# 1 - firmware file +# 2 - output file + +bfdname=@BDFNAME@ +bfdarch=@BDFARCH@ + +objcopy -I binary ${1} -B ${bfdarch} -O ${bfdname} ${2} --rename-section .data=.rodata,alloc,load,data,contents,readonly diff --git a/build_tools/make_tree b/build_tools/make_tree new file mode 100755 index 0000000..e69de29 diff --git a/build_tools/make_version b/build_tools/make_version new file mode 100755 index 0000000..319842b --- /dev/null +++ b/build_tools/make_version @@ -0,0 +1,122 @@ +#!/bin/sh + +if [ -f ${1}/.version ]; then + cat ${1}/.version +elif [ -f ${1}/.svnrevision ]; then + echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}/.svnrevision` +elif [ -d ${1}/.svn ]; then + PARTS=`LANG=C svn info ${1} | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/${2}/:: | sed -e 's:/: :g'` + BRANCH=0 + TEAM=0 + + REV=`svnversion -c ${1} | cut -d: -f2` + + if [ "${PARTS}" = "trunk" ] + then + echo SVN-'trunk'-r${REV} + exit 0 + fi + + for PART in $PARTS + do + if [ ${BRANCH} != 0 ] + then + RESULT="${RESULT}-${PART}" + break + fi + + if [ ${TEAM} != 0 ] + then + RESULT="${RESULT}-${PART}" + continue + fi + + if [ "${PART}" = "branches" ] + then + BRANCH=1 + RESULT="branch" + continue + fi + + if [ "${PART}" = "tags" ] + then + BRANCH=1 + RESULT="tag" + continue + fi + + if [ "${PART}" = "team" ] + then + TEAM=1 + continue + fi + done + + echo SVN-${RESULT##-}-r${REV} +elif [ -d ${1}/.git ]; then + # If the first log commit messages indicates that this is checked into + # subversion, we'll just use the SVN- form of the revision. + MODIFIED="" + SVN_REV=`git log --pretty=full -1 | grep -F "git-svn-id:" | sed -e "s/.*\@\([^\s]*\)\s.*/\1/g"` + if [ -z "$SVN_REV" ]; then + VERSION=`git describe --tags --dirty=M 2> /dev/null | sed -e "s/^v\([0-9]\)/\1/"` + if [ $? -ne 0 ]; then + if [ "`git ls-files -m | wc -l`" != "0" ]; then + MODIFIED="M" + fi + # Some older versions of git do not support all the above + # options. + VERSION=GIT-`git rev-parse --short --verify HEAD`${MODIFIED} + fi + echo ${VERSION} + else + PARTS=`LANG=C git log --pretty=full | grep -F "git-svn-id:" | head -1 | awk '{print $2;}' | sed -e s:^.*/svn/$2/:: | sed -e 's:/: :g' | sed -e 's/@.*$//g'` + BRANCH=0 + TEAM=0 + + if [ "`git ls-files -m | wc -l`" != "0" ]; then + MODIFIED="M" + fi + + if [ "${PARTS}" = "trunk" ]; then + echo SVN-'trunk'-r${SVN_REV}${MODIFIED} + exit 0 + fi + + for PART in $PARTS + do + if [ ${BRANCH} != 0 ]; then + RESULT="${RESULT}-${PART}" + break + fi + + if [ ${TEAM} != 0 ]; then + RESULT="${RESULT}-${PART}" + continue + fi + + if [ "${PART}" = "branches" ]; then + BRANCH=1 + RESULT="branch" + continue + fi + + if [ "${PART}" = "tags" ]; then + BRANCH=1 + RESULT="tag" + continue + fi + + if [ "${PART}" = "team" ]; then + TEAM=1 + continue + fi + done + + echo SVN-${RESULT##-}-r${SVN_REV}${MODIFIED} + fi +else + # Use the directory information in the absence of any other version + # information + pwd -P +fi diff --git a/build_tools/make_version_c b/build_tools/make_version_c new file mode 100755 index 0000000..7382f3f --- /dev/null +++ b/build_tools/make_version_c @@ -0,0 +1,10 @@ +#!/bin/sh +cat << END +/* + * version.c + * Automatically generated + */ + +const char dahdi_tools_version[] = "DAHDI Tools Version - ${TOOLSVERSION}"; + +END diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in new file mode 100644 index 0000000..e69de29 diff --git a/build_tools/test_kernel_git b/build_tools/test_kernel_git new file mode 100755 index 0000000..59c196d --- /dev/null +++ b/build_tools/test_kernel_git @@ -0,0 +1,80 @@ +#!/bin/sh + +set -e + +GIT_URL=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git +CONF_FILE=build_tools/git_test.conf + +usage() { + me=`basename $0` + echo "$me: test building Zaptel vs. kernel from git" + echo "Usage:" + echo " $me checkout Pull a kernel version into " + echo " $me update Update (pull) the kernel tree." + echo " $me setver Set the kernel version" + echo " $me test Test-build" + echo "" + echo " $me versions [pattern] List available versions." +} + +# Set a variable in $CONF_FILE +# The format of CONF_FILE is assumed to be: +# VAR=value +# in shell syntax. "value" may be quoted. +# "value should not contain a '|' character. +set_var() { + var="$1" + val="$2" + if grep -q "^$var=" $CONF_FILE 2>/dev/null; then + sed -i -e "s|^$var=.*|$var=\"$val\"|" $CONF_FILE + else + echo "$var=\"$val\"" >>$CONF_FILE + fi +} + +if [ -r "$CONF_FILE" ]; then . "$CONF_FILE"; fi + +if echo "$CONF_FILE" | grep -qv '^/'; then + # make CONF_FILE an absolute path: + CONF_FILE="$PWD/$CONF_FILE" +fi + +command="$1" + +case "$command" in + checkout) + kernel_dir="$2" + cd "$kernel_dir" + git clone $GIT_URL + set_var kernel_dir "$kernel_dir/linux-2.6" + ;; + update) + cd "$kernel_dir" + git pull + ;; + versions) + cd "$kernel_dir" + git tag -l $2 | cut -c2- + ;; + setver) + kernel_ver="$2" + tag="v$kernel_ver" + cd "$kernel_dir" + git-reset --hard "$tag" + make defconfig prepare + set_var kernel_ver "$kernel_ver" + ;; + test) + # you can pass extra parameters to the make command in + # two ways: + # 1. Set th value of MAKE_PARAMS in git_test.conf . + # 2. Any extra command-line parameter. + shift + make KSRC="$kernel_dir" KVERS=$kernel_ver $MAKE_PARAMS "$@" + ;; + *) + echo "$0: no such command $command. Aborting." + usage + exit 1 + ;; +esac diff --git a/build_tools/uninstall-modules b/build_tools/uninstall-modules new file mode 100755 index 0000000..a654c21 --- /dev/null +++ b/build_tools/uninstall-modules @@ -0,0 +1,41 @@ +#!/bin/sh +# uninstall-modules +# +# Remove all the modules passed in on the command line from the modules +# directory. This script is called by the makefile. + +KERNEL_MODULES_DIR=$1 +shift +MODULES="$*" + +usage() { + echo "$0: Used to delete kernel modules from the modules directory." + echo "" + echo "Usage:" + echo " $0 MODULES_BASE_DIR mod1 [mod2 [...]]" + echo "" + echo " MODULES_BASE_DIR - typically /lib/modules/KVERS" + echo " modN - (optionally partial) module name to remove." +} + +if [ -z "$KERNEL_MODULES_DIR" ]; then + echo "Missing kernel module directory." + usage + exit 1; +fi + +if [ -z "$MODULES" ]; then + echo "Missing one or more modules to delete." + usage + exit 1; +fi +for mod in $MODULES; do + BASE=`basename $mod` + for file in `cat $KERNEL_MODULES_DIR/modules.dep | cut -d : -f 1 | grep "$BASE$"`; do + if [ -e "$file" ]; then + #echo "Deleting $file." + rm -f $file + fi + done +done +exit 0 diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..f32079a --- /dev/null +++ b/config.guess @@ -0,0 +1,1526 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..6759825 --- /dev/null +++ b/config.sub @@ -0,0 +1,1658 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-16' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..aa23527 --- /dev/null +++ b/configure @@ -0,0 +1,6470 @@ +#! /bin/sh +# From configure.ac Revision. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for dahdi 2.8.0. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +# +# "dahdi-tools" +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and www.asterisk.org +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='dahdi' +PACKAGE_TARNAME='dahdi' +PACKAGE_VERSION='2.8.0' +PACKAGE_STRING='dahdi 2.8.0' +PACKAGE_BUGREPORT='www.asterisk.org' +PACKAGE_URL='' + +ac_unique_file="dahdi_cfg.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +PPPD_VERSION +ASCIIDOC +USE_SELINUX +PBX_HDLC +PBX_DAHDI23 +PBX_USB +USB_DIR +USB_INCLUDE +USB_LIB +PBX_NEWT +NEWT_DIR +NEWT_INCLUDE +NEWT_LIB +PBX_DAHDI +DAHDI_DIR +DAHDI_INCLUDE +DAHDI_LIB +DAHDI_DECLARATION_AFTER_STATEMENT +DAHDI_DEVMODE +DOWNLOAD +FETCH +WGET +LN +HOSTCC +BDFARCH +BDFNAME +GNU_MAKE +LN_S +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +LD +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dev_mode +with_dahdi +with_newt +with_usb +with_selinux +with_ppp +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures dahdi 2.8.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/dahdi] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of dahdi 2.8.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-dev-mode Turn on developer mode + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-dahdi=PATH use DAHDI files in PATH + --with-newt=PATH use newt files in PATH + --with-usb=PATH use usb files in PATH + --with-selinux enable (with) / disable (without) SELinux + --with-ppp=PATH Use PPP support from PATH + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +dahdi configure 2.8.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. + +"dahdi-tools" +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------- ## +## Report this to www.asterisk.org ## +## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by dahdi $as_me 2.8.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# check existence of the package + + + + + +ac_default_prefix=/usr +if test ${sysconfdir} = '${prefix}/etc'; then + sysconfdir=/etc +fi +if test ${mandir} = '${prefix}/man'; then + mandir=/usr/share/man +fi + +if test ${localstatedir} = '${prefix}/var'; then + localstatedir=/var +fi + +# specify output header file +ac_config_headers="$ac_config_headers autoconfig.h" + + +# This needs to be before any macros that use the C compiler +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + + +for ac_header in sys/soundcard.h linux/soundcard.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. +set dummy ${ac_tool_prefix}ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LD="${ac_tool_prefix}ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD=$ac_cv_prog_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LD"; then + ac_ct_LD=$LD + # Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LD"; then + ac_cv_prog_ac_ct_LD="$ac_ct_LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LD="ld" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LD=$ac_cv_prog_ac_ct_LD +if test -n "$ac_ct_LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LD" >&5 +$as_echo "$ac_ct_LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LD" = x; then + LD="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LD=$ac_ct_LD + fi +else + LD="$ac_cv_prog_LD" +fi + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU make" >&5 +$as_echo_n "checking for GNU make... " >&6; } +if ${ac_cv_GNU_MAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_GNU_MAKE='Not Found' ; + ac_cv_GNU_MAKE_VERSION_MAJOR=0 ; + ac_cv_GNU_MAKE_VERSION_MINOR=0 ; + for a in make gmake gnumake ; do + if test -z "$a" ; then continue ; fi ; + if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then + ac_cv_GNU_MAKE=$a ; + ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'` + ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2` + break; + fi + done ; + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_GNU_MAKE" >&5 +$as_echo "$ac_cv_GNU_MAKE" >&6; } ; +if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then + as_fn_error $? "*** Please install GNU make. It is required to build Asterisk!" "$LINENO" 5 + exit 1 +fi +GNU_MAKE=$ac_cv_GNU_MAKE + + + +test_obj=conftest.o +if ac_fn_c_try_compile "$LINENO"; then : + + BDFNAME=`LANG=C objdump -f $test_obj | grep -e "$test_obj:" | sed "s/.*file format \(.*\)/\1/"` + BDFARCH=`LANG=C objdump -f $test_obj | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"` + +fi +rm -f core conftest.err conftest.$ac_objext + + + +# Set the default value of HOSTCC from CC if --host was not provided: +HOSTCC=${HOSTCC:=${CC}} + + +# Extract the first word of "grep", so it can be a program name with args. +set dummy grep; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GREP in + [\\/]* | ?:[\\/]*) + ac_cv_path_GREP="$GREP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GREP" && ac_cv_path_GREP=":" + ;; +esac +fi +GREP=$ac_cv_path_GREP +if test -n "$GREP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GREP" >&5 +$as_echo "$GREP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "sh", so it can be a program name with args. +set dummy sh; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SHELL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SHELL in + [\\/]* | ?:[\\/]*) + ac_cv_path_SHELL="$SHELL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SHELL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SHELL" && ac_cv_path_SHELL=":" + ;; +esac +fi +SHELL=$ac_cv_path_SHELL +if test -n "$SHELL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHELL" >&5 +$as_echo "$SHELL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "ln", so it can be a program name with args. +set dummy ln; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LN in + [\\/]* | ?:[\\/]*) + ac_cv_path_LN="$LN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LN" && ac_cv_path_LN=":" + ;; +esac +fi +LN=$ac_cv_path_LN +if test -n "$LN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 +$as_echo "$LN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Extract the first word of "wget", so it can be a program name with args. +set dummy wget; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WGET+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WGET in + [\\/]* | ?:[\\/]*) + ac_cv_path_WGET="$WGET" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WGET" && ac_cv_path_WGET=":" + ;; +esac +fi +WGET=$ac_cv_path_WGET +if test -n "$WGET"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5 +$as_echo "$WGET" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "${WGET}" != ":" ; then + DOWNLOAD=${WGET} +else + # Extract the first word of "fetch", so it can be a program name with args. +set dummy fetch; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_FETCH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $FETCH in + [\\/]* | ?:[\\/]*) + ac_cv_path_FETCH="$FETCH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_FETCH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_FETCH" && ac_cv_path_FETCH=":" + ;; +esac +fi +FETCH=$ac_cv_path_FETCH +if test -n "$FETCH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FETCH" >&5 +$as_echo "$FETCH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + DOWNLOAD=${FETCH} +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Check whether --enable-dev-mode was given. +if test "${enable_dev_mode+set}" = set; then : + enableval=$enable_dev_mode; case "${enableval}" in + y|ye|yes) DAHDI_DEVMODE=yes ;; + n|no) DAHDI_DEVMODE=no ;; + *) as_fn_error $? "bad value ${enableval} for --enable-dev-mode" "$LINENO" 5 ;; + esac +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wdeclaration-after-statement support" >&5 +$as_echo_n "checking for -Wdeclaration-after-statement support... " >&6; } +if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + DAHDI_DECLARATION_AFTER_STATEMENT= +fi + + + + DAHDI_DESCRIP="DAHDI" + DAHDI_OPTION="dahdi" + +# Check whether --with-dahdi was given. +if test "${with_dahdi+set}" = set; then : + withval=$with_dahdi; + case ${withval} in + n|no) + USE_DAHDI=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} DAHDI" + ;; + *) + DAHDI_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} DAHDI" + ;; + esac + +fi + + PBX_DAHDI=0 + + + + + + + NEWT_DESCRIP="newt" + NEWT_OPTION="newt" + +# Check whether --with-newt was given. +if test "${with_newt+set}" = set; then : + withval=$with_newt; + case ${withval} in + n|no) + USE_NEWT=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} NEWT" + ;; + *) + NEWT_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} NEWT" + ;; + esac + +fi + + PBX_NEWT=0 + + + + + + + USB_DESCRIP="usb" + USB_OPTION="usb" + +# Check whether --with-usb was given. +if test "${with_usb+set}" = set; then : + withval=$with_usb; + case ${withval} in + n|no) + USE_USB=no + ;; + y|ye|yes) + ac_mandatory_list="${ac_mandatory_list} USB" + ;; + *) + USB_DIR="${withval}" + ac_mandatory_list="${ac_mandatory_list} USB" + ;; + esac + +fi + + PBX_USB=0 + + + + + + + + if test "x${PBX_DAHDI}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DAHDI_CODE in dahdi/user.h" >&5 +$as_echo_n "checking for DAHDI_CODE in dahdi/user.h... " >&6; } + saved_cppflags="${CPPFLAGS}" + if test "x${DAHDI_DIR}" != "x"; then + DAHDI_INCLUDE="-I${DAHDI_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${DAHDI_INCLUDE}" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(DAHDI_CODE) + int foo = 0; + #else + int foo = bar; + #endif + 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_DAHDI=1 + +$as_echo "#define HAVE_DAHDI 1" >>confdefs.h + + +$as_echo "#define HAVE_DAHDI_VERSION /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="${saved_cppflags}" + fi + + +DAHDI23_DIR="${DAHDI_DIR}" + + if test "x${PBX_DAHDI23}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DAHDI_CONFIG_NTTE in dahdi/user.h" >&5 +$as_echo_n "checking for DAHDI_CONFIG_NTTE in dahdi/user.h... " >&6; } + saved_cppflags="${CPPFLAGS}" + if test "x${DAHDI23_DIR}" != "x"; then + DAHDI23_INCLUDE="-I${DAHDI23_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${DAHDI23_INCLUDE}" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(DAHDI_CONFIG_NTTE) + int foo = 0; + #else + int foo = bar; + #endif + 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_DAHDI23=1 + +$as_echo "#define HAVE_DAHDI23 1" >>confdefs.h + + +$as_echo "#define HAVE_DAHDI23_VERSION /**/" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="${saved_cppflags}" + fi + + + +if test "x${PBX_NEWT}" != "x1" -a "${USE_NEWT}" != "no"; then + pbxlibdir="" + # if --with-NEWT=DIR has been specified, use it. + if test "x${NEWT_DIR}" != "x"; then + if test -d ${NEWT_DIR}/lib; then + pbxlibdir="-L${NEWT_DIR}/lib" + else + pbxlibdir="-L${NEWT_DIR}" + fi + fi + pbxfuncname="newtBell" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_NEWT_FOUND=yes + else + as_ac_Lib=`$as_echo "ac_cv_lib_newt_${pbxfuncname}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lnewt" >&5 +$as_echo_n "checking for ${pbxfuncname} in -lnewt... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnewt ${pbxlibdir} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ${pbxfuncname} (); +int +main () +{ +return ${pbxfuncname} (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + AST_NEWT_FOUND=yes +else + AST_NEWT_FOUND=no +fi + + fi + + # now check for the header. + if test "${AST_NEWT_FOUND}" = "yes"; then + NEWT_LIB="${pbxlibdir} -lnewt " + # if --with-NEWT=DIR has been specified, use it. + if test "x${NEWT_DIR}" != "x"; then + NEWT_INCLUDE="-I${NEWT_DIR}/include" + fi + NEWT_INCLUDE="${NEWT_INCLUDE} " + if test "xnewt.h" = "x" ; then # no header, assume found + NEWT_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${NEWT_INCLUDE} " + ac_fn_c_check_header_mongrel "$LINENO" "newt.h" "ac_cv_header_newt_h" "$ac_includes_default" +if test "x$ac_cv_header_newt_h" = xyes; then : + NEWT_HEADER_FOUND=1 +else + NEWT_HEADER_FOUND=0 +fi + + + CPPFLAGS="${saved_cppflags}" + fi + if test "x${NEWT_HEADER_FOUND}" = "x0" ; then + NEWT_LIB="" + NEWT_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + NEWT_LIB="" + fi + PBX_NEWT=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + +cat >>confdefs.h <<_ACEOF +#define HAVE_NEWT 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HAVE_NEWT_VERSION /**/ +_ACEOF + + fi + fi +fi + + +if test "x${PBX_USB}" != "x1" -a "${USE_USB}" != "no"; then + pbxlibdir="" + # if --with-USB=DIR has been specified, use it. + if test "x${USB_DIR}" != "x"; then + if test -d ${USB_DIR}/lib; then + pbxlibdir="-L${USB_DIR}/lib" + else + pbxlibdir="-L${USB_DIR}" + fi + fi + pbxfuncname="usb_init" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_USB_FOUND=yes + else + as_ac_Lib=`$as_echo "ac_cv_lib_usb_${pbxfuncname}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lusb" >&5 +$as_echo_n "checking for ${pbxfuncname} in -lusb... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb ${pbxlibdir} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ${pbxfuncname} (); +int +main () +{ +return ${pbxfuncname} (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + AST_USB_FOUND=yes +else + AST_USB_FOUND=no +fi + + fi + + # now check for the header. + if test "${AST_USB_FOUND}" = "yes"; then + USB_LIB="${pbxlibdir} -lusb " + # if --with-USB=DIR has been specified, use it. + if test "x${USB_DIR}" != "x"; then + USB_INCLUDE="-I${USB_DIR}/include" + fi + USB_INCLUDE="${USB_INCLUDE} " + if test "xusb.h" = "x" ; then # no header, assume found + USB_HEADER_FOUND="1" + else # check for the header + saved_cppflags="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${USB_INCLUDE} " + ac_fn_c_check_header_mongrel "$LINENO" "usb.h" "ac_cv_header_usb_h" "$ac_includes_default" +if test "x$ac_cv_header_usb_h" = xyes; then : + USB_HEADER_FOUND=1 +else + USB_HEADER_FOUND=0 +fi + + + CPPFLAGS="${saved_cppflags}" + fi + if test "x${USB_HEADER_FOUND}" = "x0" ; then + USB_LIB="" + USB_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + USB_LIB="" + fi + PBX_USB=1 + # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED + +cat >>confdefs.h <<_ACEOF +#define HAVE_USB 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HAVE_USB_VERSION /**/ +_ACEOF + + fi + fi +fi + + +for ac_func in semtimedop +do : + ac_fn_c_check_func "$LINENO" "semtimedop" "ac_cv_func_semtimedop" +if test "x$ac_cv_func_semtimedop" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SEMTIMEDOP 1 +_ACEOF + +fi +done + + +PBX_HDLC=0 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h" >&5 +$as_echo_n "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_HDLC=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if test $PBX_HDLC = 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h" >&5 +$as_echo_n "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ +#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_HDLC=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +if test "x${PBX_HDLC}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc." >&5 +$as_echo "$as_me: GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc." >&6;} +fi + + + + +# Check whether --with-selinux was given. +if test "${with_selinux+set}" = set; then : + withval=$with_selinux; USE_SELINUX=$withval +else + if test ! -x /usr/sbin/sestatus; then + USE_SELINUX=no; + elif /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"; then + USE_SELINUX=yes + fi + + +fi + + + + + +# for asciidoc before ver. 7, the backend must be stated explicitly: +ASCIIDOC='asciidoc' +asciidoc_ver=`asciidoc --version 2>&1 | awk '/^asciidoc /{print $2}' | cut -d. -f 1 | head -n 1` +if test "$asciidoc_ver" != '' && test $asciidoc_ver -lt 7; then + ASCIIDOC="asciidoc -b xhtml" +fi + + + +# Check whether --with-ppp was given. +if test "${with_ppp+set}" = set; then : + withval=$with_ppp; +else + with_ppp=check + +fi + +# somebody will fix that +default_ppp_path=/usr + +case "$with_ppp" in + yes|check) ppp_path="$default_ppp_path";; + no) ppp_path='' ;; + *) ppp_path="$with_ppp" ;; +esac + +level_file="$ppp_path/include/pppd/patchlevel.h" +PPP_VERSION= +if test "$ppp_path" != '' && test -r "$level_file"; then + PPPD_VERSION=`awk -F '"' '/VERSION/ { print $$2; }' $level_file` +fi + +case "$with_ppp" in + check|no) :;; + *) + # If we asked explicitly for ppp support + if test "$PPPD_VERSION" = ''; then + # but have not detected it + as_fn_error $? "failed to find pppd/patchlevel.h: no ppp support." "$LINENO" 5 + fi + ;; +esac + +if test "x${PBX_DAHDI}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Building this package requires DAHDI support. *** " >&5 +$as_echo "$as_me: *** Building this package requires DAHDI support. *** " >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Please install the dahdi-linux package. ***" >&5 +$as_echo "$as_me: *** Please install the dahdi-linux package. ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + exit 1 +fi + +if test "x${PBX_DAHDI23}" != "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Building this package requires DAHDI support (>= 2.3) *** " >&5 +$as_echo "$as_me: *** Building this package requires DAHDI support (>= 2.3) *** " >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Please install a recent dahdi-linux package. ***" >&5 +$as_echo "$as_me: *** Please install a recent dahdi-linux package. ***" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: ***" >&5 +$as_echo "$as_me: ***" >&6;} + exit 1 +fi + + + +ac_config_files="$ac_config_files makeopts" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by dahdi $as_me 2.8.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +dahdi config.status 2.8.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "autoconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS autoconfig.h" ;; + "makeopts") CONFIG_FILES="$CONFIG_FILES makeopts" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: *** dahdi-tools build successfully configured ***" >&5 +$as_echo "$as_me: *** dahdi-tools build successfully configured ***" >&6;} diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4fa396b --- /dev/null +++ b/configure.ac @@ -0,0 +1,217 @@ +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) + +m4_define([TOOLSVERSION], + m4_bpatsubst(m4_esyscmd([build_tools/make_version . dahdi/tools]), + [\([0-9.]*\)\(\w\|\W\)*], + [\1])) +AC_INIT(dahdi, TOOLSVERSION, www.asterisk.org) + +# check existence of the package +AC_CONFIG_SRCDIR([dahdi_cfg.c]) + +AC_COPYRIGHT("dahdi-tools") +AC_REVISION($Revision$) + +ac_default_prefix=/usr +if test ${sysconfdir} = '${prefix}/etc'; then + sysconfdir=/etc +fi +if test ${mandir} = '${prefix}/man'; then + mandir=/usr/share/man +fi + +if test ${localstatedir} = '${prefix}/var'; then + localstatedir=/var +fi + +# specify output header file +AC_CONFIG_HEADER(autoconfig.h) + +# This needs to be before any macros that use the C compiler +AC_GNU_SOURCE + +AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h]) + +AC_CHECK_TOOL([LD], [ld]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AST_CHECK_GNU_MAKE + +test_obj=conftest.o +AC_COMPILE_IFELSE(AC_LANG_SOURCE(),[ + BDFNAME=`LANG=C objdump -f $test_obj | grep -e "$test_obj:" | sed "s/.*file format \(.*\)/\1/"` + BDFARCH=`LANG=C objdump -f $test_obj | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"` +],[]) +AC_SUBST(BDFNAME) +AC_SUBST(BDFARCH) + +# Set the default value of HOSTCC from CC if --host was not provided: +HOSTCC=${HOSTCC:=${CC}} +AC_SUBST(HOSTCC) + +AC_PATH_PROG([GREP], [grep], :) +AC_PATH_PROG([SHELL], [sh], :) +AC_PATH_PROG([LN], [ln], :) + +AC_PATH_PROG([WGET], [wget], :) +if test "${WGET}" != ":" ; then + DOWNLOAD=${WGET} +else + AC_PATH_PROG([FETCH], [fetch], [:]) + DOWNLOAD=${FETCH} +fi +AC_SUBST(DOWNLOAD) + +AC_LANG(C) + +AC_ARG_ENABLE(dev-mode, + [ --enable-dev-mode Turn on developer mode], + [case "${enableval}" in + y|ye|yes) DAHDI_DEVMODE=yes ;; + n|no) DAHDI_DEVMODE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-dev-mode) ;; + esac]) +AC_SUBST(DAHDI_DEVMODE) + +AC_MSG_CHECKING(for -Wdeclaration-after-statement support) +if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then + AC_MSG_RESULT(yes) + DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement +else + AC_MSG_RESULT(no) + DAHDI_DECLARATION_AFTER_STATEMENT= +fi +AC_SUBST(DAHDI_DECLARATION_AFTER_STATEMENT) + +AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi]) +AST_EXT_LIB_SETUP([NEWT], [newt], [newt]) +AST_EXT_LIB_SETUP([USB], [usb], [usb]) + +AST_C_DEFINE_CHECK([DAHDI], [DAHDI_CODE], [dahdi/user.h]) +DAHDI23_DIR="${DAHDI_DIR}" +AST_C_DEFINE_CHECK([DAHDI23], [DAHDI_CONFIG_NTTE], [dahdi/user.h]) +AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h]) +AST_EXT_LIB_CHECK([USB], [usb], [usb_init], [usb.h]) + +AC_CHECK_FUNCS([semtimedop]) + +PBX_HDLC=0 +AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h]) +AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [#include ], + [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0])], + [AC_MSG_RESULT(yes) + PBX_HDLC=1], + [AC_MSG_RESULT(no)] +) +if test $PBX_HDLC = 0; then + AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h]) + AC_COMPILE_IFELSE( + [ AC_LANG_PROGRAM( [ + #include + #include ], + [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 + int foo = 0; + #else + int foo = bar; + #endif + 0])], + [AC_MSG_RESULT(yes) + PBX_HDLC=1], + [AC_MSG_RESULT(no)] + ) +fi + +if test "x${PBX_HDLC}" != "x1"; then + AC_MSG_NOTICE([GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc.]) +fi + +AC_SUBST(PBX_HDLC) + +AC_ARG_WITH(selinux, + [AS_HELP_STRING([--with-selinux], + [enable (with) / disable (without) SELinux])], + [USE_SELINUX=$withval], + [ if test ! -x /usr/sbin/sestatus; then + USE_SELINUX=no; + elif /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"; then + USE_SELINUX=yes + fi + ] +) + + +AC_SUBST(USE_SELINUX) + +# for asciidoc before ver. 7, the backend must be stated explicitly: +ASCIIDOC='asciidoc' +asciidoc_ver=`asciidoc --version 2>&1 | awk '/^asciidoc /{print $2}' | cut -d. -f 1 | head -n 1` +if test "$asciidoc_ver" != '' && test $asciidoc_ver -lt 7; then + ASCIIDOC="asciidoc -b xhtml" +fi +AC_SUBST(ASCIIDOC) + +AC_ARG_WITH(ppp, + [AS_HELP_STRING([--with-ppp=PATH],[Use PPP support from PATH])], + [], + [with_ppp=check] + ) +# somebody will fix that +default_ppp_path=/usr + +case "$with_ppp" in + yes|check) ppp_path="$default_ppp_path";; + no) ppp_path='' ;; + *) ppp_path="$with_ppp" ;; +esac + +level_file="$ppp_path/include/pppd/patchlevel.h" +PPP_VERSION= +if test "$ppp_path" != '' && test -r "$level_file"; then + PPPD_VERSION=`awk -F '"' '/VERSION/ { print $$2; }' $level_file` +fi + +case "$with_ppp" in + check|no) :;; + *) + # If we asked explicitly for ppp support + if test "$PPPD_VERSION" = ''; then + # but have not detected it + AC_MSG_ERROR(failed to find pppd/patchlevel.h: no ppp support.) + fi + ;; +esac + +if test "x${PBX_DAHDI}" != "x1"; then + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** Building this package requires DAHDI support. *** ]) + AC_MSG_NOTICE([*** Please install the dahdi-linux package. ***]) + AC_MSG_NOTICE([***]) + exit 1 +fi + +if test "x${PBX_DAHDI23}" != "x1"; then + AC_MSG_NOTICE([***]) + AC_MSG_NOTICE([*** Building this package requires DAHDI support (>= 2.3) *** ]) + AC_MSG_NOTICE([*** Please install a recent dahdi-linux package. ***]) + AC_MSG_NOTICE([***]) + exit 1 +fi + +AC_SUBST(PPPD_VERSION) + +AC_CONFIG_FILES([makeopts]) +AC_OUTPUT + +AC_MSG_NOTICE(*** dahdi-tools build successfully configured ***) diff --git a/dahdi-bash-completion b/dahdi-bash-completion new file mode 100644 index 0000000..d98074a --- /dev/null +++ b/dahdi-bash-completion @@ -0,0 +1,133 @@ +# Check for bash +[ -z "$BASH_VERSION" ] && return + +__dahdi_span_assignments() { + local cur prev has_cmd i + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + has_cmd=0 + for (( i=0; i < COMP_CWORD; i++)); do + case "${COMP_WORDS[$i]}" in + add | auto | dumpconfig | list | remove) + has_cmd=1 + break + ;; + esac + done + case "$prev" in + -k | --key) COMPREPLY=( $(compgen -W 'devpath hwid location' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-h -k -n -v --help --key --dry-run --verbose' -- $cur ) ) + ;; + *) + if [ "$has_cmd" = 1 ]; then + COMPREPLY=( ${COMPREPLY[@]} $(shopt -s nullglob; \ + echo /sys/bus/dahdi_devices/devices/* ) ) + else + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + 'add auto dumpconfig list remove' -- $cur) ) + fi + ;; + esac + ;; + esac +} + +complete -F __dahdi_span_assignments dahdi_span_assignments + +__dahdi_span_types() { + local cur prev has_cmd i + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + has_cmd=0 + for (( i=0; i < COMP_CWORD; i++)); do + case "${COMP_WORDS[$i]}" in + dumpconfig | list | set) + has_cmd=1 + break + ;; + esac + done + case "$prev" in + -k | --key) COMPREPLY=( $(compgen -W 'devpath hwid location' -- $cur) ) ;; + --line-type) COMPREPLY=( $(compgen -W 'E1 J1 T1' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-h -k -n -v --help --key --dry-run --line-type --verbose' -- $cur ) ) + ;; + *) + if [ "$has_cmd" = 1 ]; then + # FIXME: check if devices are settable? + COMPREPLY=( ${COMPREPLY[@]} $( \ + grep -l '[EJT]1' /sys/devices/pci0000:00/0000:00:10.4/usb1/1-1/xbus-00/*/spantype 2>/dev/null | sed -e 's|/spantype||') ) + else + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + 'dumpconfig list set' -- $cur) ) + fi + ;; + esac + ;; + esac +} + +complete -F __dahdi_span_types dahdi_span_types + + +__dahdi_genconf() { + local cur + COMPREPLY=() + prev=${COMP_WORDS[COMP_CWORD-1]} + cur=${COMP_WORDS[COMP_CWORD]} + + case "$prev" in + --line-type) COMPREPLY=( $(compgen -W 'E1 J1 T1' -- $cur) ) ;; + *) + case "$cur" in + -*) COMPREPLY+=( $(compgen -W '-F -v -V --freepbx --version --verbose --line-type' -- $cur ) ) ;; + *) + COMPREPLY+=( $(compgen -W "$( perl -e 'my $file = "\u$ARGV[0]"; + # Complete module name. Translate the case of the + # first letter + my @pats = map {"$_/Dahdi/Config/Gen/$file*.pm"} @INC; + foreach (@pats) { + foreach(glob) { + s|.*/||; + s|.pm$||; + s|^(.)|lc($1)|e; + print "$_ " + } + }')" -- $cur ) ) + ;; + esac + ;; + esac +} + +complete -F __dahdi_genconf dahdi_genconf + +__dahdi_cfg() { + local cur prev + COMPREPLY=() + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + -c) COMPREPLY=( $(compgen -f -- $cur) ) ;; + -S) COMPREPLY=( $(ls -d /sys/bus/dahdi_spans/devices/* 2>/dev/null | sed -e 's/.*-//') ) ;; + # FIXME: A similar completion for -C (-) + *) + COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \ + '-c -C -f -h -s -S -t -v ' -- $cur ) ) + ;; + esac +} + +# Disable until -c works properly +#complete -F __dahdi_cfg dahdi_cfg diff --git a/dahdi.init b/dahdi.init new file mode 100755 index 0000000..68420c7 --- /dev/null +++ b/dahdi.init @@ -0,0 +1,343 @@ +#!/bin/sh +# +# dahdi This shell script takes care of loading and unloading \ +# DAHDI Telephony interfaces +# chkconfig: 2345 9 92 +# description: The DAHDI drivers allow you to use your linux \ +# computer to accept incoming data and voice interfaces +# +# config: /etc/dahdi/init.conf + +### BEGIN INIT INFO +# Provides: dahdi +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Should-Start: $network $syslog +# Should-Stop: $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: DAHDI kernel modules +# Description: dahdi - load and configure DAHDI modules +### END INIT INFO + +initdir=/etc/init.d + +# Don't edit the following values. Edit /etc/dahdi/init.conf instead. + +DAHDI_CFG=/usr/sbin/dahdi_cfg +DAHDI_CFG_CMD=${DAHDI_CFG_CMD:-"$DAHDI_CFG"} # e.g: for a custom system.conf location + +FXOTUNE=/usr/sbin/fxotune + +# The default syncer Astribank. Usually set automatically to a sane +# value by xpp_sync(1) if you have an Astribank. You can set this to an +# explicit Astribank (e.g: 01). +XPP_SYNC=auto + +# The maximal timeout (seconds) to wait for udevd to finish generating +# device nodes after the modules have loaded and before running dahdi_cfg. +DAHDI_DEV_TIMEOUT=20 + +# A list of modules to unload when stopping. +# All of their dependencies will be unloaded as well. +DAHDI_UNLOAD_MODULES="dahdi" + +# +# Determine which kind of configuration we're using +# +system=redhat # assume redhat +if [ -f /etc/debian_version ]; then + system=debian +fi + +if [ -f /etc/gentoo-release ]; then + system=debian +fi + +if [ -f /etc/SuSE-release -o -f /etc/novell-release ] +then + system=debian +fi + +# Source function library. +if [ $system = redhat ]; then + . $initdir/functions || exit 0 +fi + +DAHDI_MODULES_FILE="/etc/dahdi/modules" + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +if [ $system = redhat ]; then + LOCKFILE=/var/lock/subsys/dahdi +fi + +# recursively unload a module and its dependencies, if possible. +# where's modprobe -r when you need it? +# inputs: module to unload. +# returns: the result from +unload_module() { + module="$1" + line=`lsmod 2>/dev/null | grep "^$1 "` + if [ "$line" = '' ]; then return; fi # module was not loaded + + set -- $line + # $1: the original module, $2: size, $3: refcount, $4: deps list + mods=`echo $4 | tr , ' '` + ec_modules="" + # xpp_usb keeps the xpds below busy if an xpp hardware is + # connected. Hence must be removed before them: + case "$module" in xpd_*) mods="xpp_usb $mods";; esac + + for mod in $mods; do + case "$mod" in + dahdi_echocan_*) + ec_modules="$mod $ec_modules" + ;; + *) + # run in a subshell, so it won't step over our vars: + (unload_module $mod) + ;; + esac + done + # Now that all the other dependencies are unloaded, we can unload the + # dahdi_echocan modules. The drivers that register spans may keep + # references on the echocan modules before they are unloaded. + for mod in $ec_modules; do + (unload_module $mod) + done + rmmod $module +} + +unload_modules() { + for module in $DAHDI_UNLOAD_MODULES; do + unload_module $module + done +} + +# In (xpp) hotplug mode, the init script is also executed from the +# hotplug hook. In that case it should not attempt to loade modules. +# +# This function only retunrs false (1) if we're in hotplug mode and +# coming from the hotplug hook script. +hotplug_should_load_modules() { + if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" != '' ] + then + return 1 + fi + return 0 +} + +# In (xpp) hotplug mode: quit after we loaded modules. +# +# In hotplug mode, the main run should end here, whereas the rest of the +# script should be finished by the instance running from the hook. +# Note that we only get here if there are actually Astribanks on the +# system (otherwise noone will trigger the run of the hotplug hook +# script). +hotplug_exit_after_load() { + if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' ] + then + exit 0 + fi +} + +# Initialize the Xorcom Astribank (xpp/) using perl utiliites: +xpp_startup() { + if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then + aas_param='/sys/module/dahdi/parameters/auto_assign_spans' + aas=`cat "$aas_param" 2>/dev/null` + if [ "$aas" = 0 ]; then + echo 1>&2 "Don't wait for Astribanks (use Asterisk hotplug-support)" + return 0 + fi + fi + # do nothing if there are no astribank devices: + if ! /usr/share/dahdi/waitfor_xpds; then return 0; fi + + hotplug_exit_after_load +} + + +hpec_start() { + # HPEC license found + if ! echo /var/lib/digium/licenses/HPEC-*.lic | grep -v '\*' | grep -q .; then + return + fi + + # dahdihpec_enable not installed in /usr/sbin + if [ ! -f /usr/sbin/dahdihpec_enable ]; then + echo -n "Running dahdihpec_enable: Failed" + echo -n "." + echo " The dahdihpec_enable binary is not installed in /usr/sbin." + return + fi + + # dahdihpec_enable not set executable + if [ ! -x /usr/sbin/dahdihpec_enable ]; then + echo -n "Running dahdihpec_enable: Failed" + echo -n "." + echo " /usr/sbin/dahdihpec_enable is not set as executable." + return + fi + + # dahdihpec_enable properly installed + if [ $system = debian ]; then + echo -n "Running dahdihpec_enable: " + /usr/sbin/dahdihpec_enable 2> /dev/null + elif [ $system = redhat ]; then + action "Running dahdihpec_enable: " /usr/sbin/dahdihpec_enable + fi + if [ $? = 0 ]; then + echo -n "done" + echo "." + else + echo -n "Failed" + echo -n "." + echo " This can be caused if you had already run dahdihpec_enable, or if your HPEC license is no longer valid." + fi +} + +shutdown_dynamic() { + if ! grep -q ' DYN/' /proc/dahdi/* 2>/dev/null; then return; fi + + # we should only get here if we have dynamic spans. Right? + $DAHDI_CFG_CMD -s +} + +load_modules() { + # Some systems, e.g. Debian Lenny, add here -b, which will break + # loading of modules blacklisted in modprobe.d/* + unset MODPROBE_OPTIONS + modules=`sed -e 's/#.*$//' $DAHDI_MODULES_FILE 2>/dev/null` + #if [ "$modules" = '' ]; then + # what? + #fi + echo "Loading DAHDI hardware modules:" + modprobe dahdi + for line in $modules; do + if [ $system = debian ]; then + echo -n " ${line}: " + if modprobe $line 2> /dev/null; then + echo -n "done" + else + echo -n "error" + fi + elif [ $system = redhat ]; then + action " ${line}: " modprobe $line + fi + done + echo "" +} + +# Make sure that either dahdi is loaded or modprobe-able +dahdi_modules_loadable() { + modinfo dahdi >/dev/null 2>&1 || lsmod | grep -q -w ^dahdi +} + +if [ ! -x "$DAHDI_CFG" ]; then + echo "dahdi_cfg not executable" + exit 0 +fi + +RETVAL=0 + +# See how we were called. +case "$1" in + start) + if ! dahdi_modules_loadable; then + echo "No DAHDI modules on the system. Not starting" + exit 0 + fi + if hotplug_should_load_modules; then + load_modules + fi + + TMOUT=$DAHDI_DEV_TIMEOUT # max secs to wait + + while [ ! -d /dev/dahdi ] ; do + sleep 1 + TMOUT=`expr $TMOUT - 1` + if [ $TMOUT -eq 0 ] ; then + echo "Error: missing /dev/dahdi!" + exit 1 + fi + done + + xpp_startup + + # Assign all spans that weren't handled via udev + /etc/dahdi/assigned-spans.conf + /usr/share/dahdi/dahdi_auto_assign_compat + + if [ $system = debian ]; then + echo -n "Running dahdi_cfg: " + $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" + echo "." + elif [ $system = redhat ]; then + action "Running dahdi_cfg: " $DAHDI_CFG_CMD + fi + RETVAL=$? + + if [ "$LOCKFILE" != '' ]; then + [ $RETVAL -eq 0 ] && touch $LOCKFILE + fi + + if [ -x "$FXOTUNE" ] && [ -r /etc/fxotune.conf ]; then + # Allowed to fail if e.g. Asterisk already uses channels: + $FXOTUNE -s || : + fi + + # Do not try to call xpp_sync if there are no Astribank devices + # installed. + if test -e /sys/bus/astribanks; then + # Set the right Astribanks ticker: + LC_ALL=C xpp_sync "$XPP_SYNC" + fi + + hpec_start + ;; + stop) + # Unload drivers + #shutdown_dynamic # FIXME: needs test from someone with dynamic spans + echo -n "Unloading DAHDI hardware modules: " + if unload_modules; then + echo "done" + else + echo "error" + fi + if [ "$LOCKFILE" != '' ]; then + [ $RETVAL -eq 0 ] && rm -f $LOCKFILE + fi + ;; + unload) + unload_modules + ;; + restart|force-reload) + $0 stop + $0 start + ;; + reload) + if [ $system = debian ]; then + echo -n "Rerunning dahdi_cfg: " + $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" + echo "." + elif [ $system = redhat ]; then + action "Rerunning dahdi_cfg: " $DAHDI_CFG_CMD + fi + RETVAL=$? + ;; + status) + if [ -d /proc/dahdi ]; then + /usr/sbin/lsdahdi + RETVAL=0 + else + RETVAL=3 + fi + ;; + *) + echo "Usage: dahdi {start|stop|restart|status|reload|unload}" + exit 1 +esac + +exit $RETVAL + diff --git a/dahdi.rules b/dahdi.rules new file mode 100644 index 0000000..f5eef2e --- /dev/null +++ b/dahdi.rules @@ -0,0 +1,18 @@ + +ACTION!="add", GOTO="dahdi_add_end" + +# DAHDI devices with ownership/permissions for running as non-root +SUBSYSTEM=="dahdi", OWNER="asterisk", GROUP="asterisk", MODE="0660" + +# Backward compat names: /dev/dahdi/ +SUBSYSTEM=="dahdi_channels", SYMLINK+="dahdi/%m" + +# Add persistant names as well +SUBSYSTEM=="dahdi_channels", ATTRS{hardware_id}!="", SYMLINK+="dahdi/devices/%s{hardware_id}/%s{local_spanno}/%n" +SUBSYSTEM=="dahdi_channels", ATTRS{location}!="", SYMLINK+="dahdi/devices/@%s{location}/%s{local_spanno}/%n" + +LABEL="dahdi_add_end" + +# hotplug scripts +SUBSYSTEM=="dahdi_devices", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_handle_device" +SUBSYSTEM=="dahdi_spans", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_span_config" diff --git a/dahdi.xml b/dahdi.xml new file mode 100644 index 0000000..f071f5d --- /dev/null +++ b/dahdi.xml @@ -0,0 +1,26 @@ + + + + + no + + + hdlc + + + + + no + + + + + + + + + + + libnewt + + diff --git a/dahdi_cfg.c b/dahdi_cfg.c new file mode 100644 index 0000000..30add83 --- /dev/null +++ b/dahdi_cfg.c @@ -0,0 +1,1961 @@ +/* + * Configuration program for DAHDI Telephony Interface + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "tonezone.h" +#include "dahdi_tools_version.h" + +#define CONFIG_FILENAME "/etc/dahdi/system.conf" +#define MASTER_DEVICE "/dev/dahdi/ctl" + +#define NUM_SPANS DAHDI_MAX_SPANS + +#define NUM_TONES 15 + +/*! A sanity check for the timing parameter of the span. + * + * Note that each driver using it is still responsible for validating + * that value. + */ +#define MAX_TIMING 255 + +/* Assume no more than 1024 dynamics */ +#define NUM_DYNAMIC 1024 + +static int lineno=0; + +static FILE *cf; + +static char *filename=CONFIG_FILENAME; + +int rxtones[NUM_TONES + 1],rxtags[NUM_TONES + 1],txtones[NUM_TONES + 1]; +int bursttime = 0, debouncetime = 0, invertcor = 0, exttone = 0, corthresh = 0; +int txgain = 0, rxgain = 0, deemp = 0, preemp = 0; + +int corthreshes[] = {3125,6250,9375,12500,15625,18750,21875,25000,0} ; + +static int toneindex = 1; + +#define DEBUG_READER (1 << 0) +#define DEBUG_PARSER (1 << 1) +#define DEBUG_APPLY (1 << 2) +static int debug = 0; + +static int errcnt = 0; + +static int deftonezone = -1; + +static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS]; + +static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS]; + +static int current_span = 0; +static int only_span = 0; +static int restrict_channels = 0; +static int selected_channels[DAHDI_MAX_CHANNELS]; +static int chan2span[DAHDI_MAX_CHANNELS]; +static int declared_spans[DAHDI_MAX_SPANS]; + +static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS]; + +static struct dahdi_dynamic_span zds[NUM_DYNAMIC]; + +static const char *sig[DAHDI_MAX_CHANNELS]; /* Signalling */ + +static int slineno[DAHDI_MAX_CHANNELS]; /* Line number where signalling specified */ + +static int fiftysixkhdlc[DAHDI_MAX_CHANNELS]; + +static int spans=0; + +static int dry_run = 0; + +static int verbose = 0; + +static int force = 0; + +static int stopmode = 0; + +static int numdynamic = 0; + +static char zonestoload[DAHDI_TONE_ZONE_MAX][10]; + +static int numzones = 0; + +static int fd = -1; + +static const char *lbostr[] = { +"0 db (CSU)/0-133 feet (DSX-1)", +"133-266 feet (DSX-1)", +"266-399 feet (DSX-1)", +"399-533 feet (DSX-1)", +"533-655 feet (DSX-1)", +"-7.5db (CSU)", +"-15db (CSU)", +"-22.5db (CSU)" +}; + +static const char *laws[] = { + "Default", + "Mu-law", + "A-law" +}; + +static bool _are_all_spans_assigned(const char *device_path) +{ + char attribute[1024]; + int res; + FILE *fp; + int span_count; + DIR *dirp; + struct dirent *dirent; + + snprintf(attribute, sizeof(attribute) - 1, + "%s/span_count", device_path); + fp = fopen(attribute, "r"); + if (NULL == fp) { + fprintf(stderr, "Failed to open '%s'.\n", attribute); + return false; + } + res = fscanf(fp, "%d", &span_count); + fclose(fp); + + if (EOF == res) { + fprintf(stderr, "Failed to read '%s'.\n", attribute); + return false; + } + + dirp = opendir(device_path); + while (span_count) { + dirent = readdir(dirp); + if (NULL == dirent) + break; + if (!strncmp("span-", dirent->d_name, 5)) { + --span_count; + } + } + closedir(dirp); + return (span_count > 0) ? false : true; +} + +/** + * are_all_spans_assigned - Look in sysfs to see if all spans for a device are assigned. + * + * Returns true if there are $span_count child spans of all devices, or false + * otherwise. + */ +static bool are_all_spans_assigned(void) +{ + DIR *dirp; + struct dirent *dirent; + bool res = true; + char device_path[1024]; + + dirp = opendir("/sys/bus/dahdi_devices/devices"); + if (!dirp) { + /* If we cannot open dahdi_devices, either dahdi isn't loaded, + * or we're using an older version of DAHDI that doesn't use + * sysfs. */ + return true; + } + + while (true && res) { + + dirent = readdir(dirp); + if (NULL == dirent) + break; + + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + continue; + + snprintf(device_path, sizeof(device_path)-1, + "/sys/bus/dahdi_devices/devices/%s", dirent->d_name); + res = _are_all_spans_assigned(device_path); + } + + closedir(dirp); + errno = 0; + return res; +} + +static bool wait_for_all_spans_assigned(unsigned long timeout_sec) +{ + bool all_assigned = are_all_spans_assigned(); + unsigned int timeout = 10*timeout_sec; + + while (!all_assigned && --timeout) { + usleep(100000); + all_assigned = are_all_spans_assigned(); + } + + return all_assigned; +} + +static const char *sigtype_to_str(const int sig) +{ + switch (sig) { + case 0: + return "Unused"; + case DAHDI_SIG_EM: + return "E & M"; + case DAHDI_SIG_EM_E1: + return "E & M E1"; + case DAHDI_SIG_FXSLS: + return "FXS Loopstart"; + case DAHDI_SIG_FXSGS: + return "FXS Groundstart"; + case DAHDI_SIG_FXSKS: + return "FXS Kewlstart"; + case DAHDI_SIG_FXOLS: + return "FXO Loopstart"; + case DAHDI_SIG_FXOGS: + return "FXO Groundstart"; + case DAHDI_SIG_FXOKS: + return "FXO Kewlstart"; + case DAHDI_SIG_CAS: + return "CAS / User"; + case DAHDI_SIG_DACS: + return "DACS"; + case DAHDI_SIG_DACS_RBS: + return "DACS w/RBS"; + case DAHDI_SIG_CLEAR: + return "Clear channel"; + case DAHDI_SIG_SLAVE: + return "Slave channel"; + case DAHDI_SIG_HDLCRAW: + return "Raw HDLC"; + case DAHDI_SIG_HDLCNET: + return "Network HDLC"; + case DAHDI_SIG_HDLCFCS: + return "HDLC with FCS check"; + case DAHDI_SIG_HARDHDLC: + return "Hardware assisted D-channel"; + case DAHDI_SIG_MTP2: + return "MTP2"; + default: + return "Unknown"; + } +} + +static void clear_fields() +{ + + memset(rxtones,0,sizeof(rxtones)); + memset(rxtags,0,sizeof(rxtags)); + memset(txtones,0,sizeof(txtones)); + bursttime = 0; + debouncetime = 0; + invertcor = 0; + exttone = 0; + txgain = 0; + rxgain = 0; + deemp = 0; + preemp = 0; +} + +static int error(char *fmt, ...) __attribute__ ((format(printf, 1, 2))); + +static int error(char *fmt, ...) +{ + int res; + static int shown=0; + va_list ap; + if (!shown) { + fprintf(stderr, "Notice: Configuration file is %s\n", filename); + shown++; + } + res = fprintf(stderr, "line %d: ", lineno); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + errcnt++; + return res; +} + +static char *trim(char *buf) +{ + size_t len; + + while (*buf && (*buf < 33)) { + buf++; + } + + len = strlen(buf); + + while (len && buf[len-1] < 33) { + buf[--len] = '\0'; + } + + return buf; +} + +static int skip_channel(int x) +{ + int spanno = chan2span[x]; + + if (restrict_channels) { + if (!selected_channels[x]) + return 1; + /* sanity check */ + if (only_span) { + if (spanno != 0 && only_span != spanno) { + fprintf(stderr, + "Only span %d. Skip selected channel %d from span %d\n", + only_span, x, spanno); + return 1; + } + } + } else { + if (only_span && !declared_spans[only_span]) { + fprintf(stderr, + "Error: analog span %d given to '-S', without '-C' restriction.\n", + only_span); + exit(1); + } + if (only_span && only_span != spanno) + return 1; + } + return 0; +} + +static int parseargs(char *input, char *output[], int maxargs, char sep) +{ + char *c; + int pos=0; + c = input; + output[pos++] = c; + while(*c) { + while(*c && (*c != sep)) c++; + if (*c) { + *c = '\0'; + c++; + while(*c && (*c < 33)) c++; + if (*c) { + if (pos >= maxargs) + return -1; + output[pos] = c; + trim(output[pos]); + pos++; + output[pos] = NULL; + /* Return error if we have too many */ + } else + return pos; + } + } + return pos; +} + +int dspanconfig(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int chans; + int timing; + res = parseargs(args, realargs, 4, ','); + if (res != 4) { + error("Incorrect number of arguments to 'dynamic' (should be ,
,, )\n"); + return -1; + } + res = sscanf(realargs[2], "%d", &chans); + if ((res == 1) && (chans < 1)) + res = -1; + if (res != 1) { + error("Invalid number of channels '%s', should be a number > 0.\n", realargs[2]); + return -1; + } + + res = sscanf(realargs[3], "%d", &timing); + if ((res == 1) && (timing < 0)) + res = -1; + if (res != 1) { + error("Invalid timing '%s', should be a number > 0.\n", realargs[3]); + return -1; + } + + + dahdi_copy_string(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); + dahdi_copy_string(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); + zds[numdynamic].numchans = chans; + zds[numdynamic].timing = timing; + + numdynamic++; + return 0; +} + +int spanconfig(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int argc; + int span; + int timing; + int i; + argc = res = parseargs(args, realargs, 9, ','); + if ((res < 5) || (res > 9)) { + error("Incorrect number of arguments to 'span' (should be ,,,,[, crc4 | yellow [, yellow]])\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &span); + if (res != 1) { + error("Span number should be a valid span number, not '%s'\n", realargs[0]); + return -1; + } + current_span = span; + declared_spans[span] = 1; + res = sscanf(realargs[1], "%d", &timing); + if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) { + error("Timing should be a number from 0 to %d, not '%s'\n", + MAX_TIMING, realargs[1]); + return -1; + } + res = sscanf(realargs[2], "%d", &lc[spans].lbo); + if (res != 1) { + error("Line build-out (LBO) should be a number from 0 to 7 (usually 0) not '%s'\n", realargs[2]); + return -1; + } + if ((lc[spans].lbo < 0) || (lc[spans].lbo > 7)) { + error("Line build-out should be in the range 0 to 7, not %d\n", lc[spans].lbo); + return -1; + } + if (!strcasecmp(realargs[3], "d4")) { + lc[spans].lineconfig |= DAHDI_CONFIG_D4; + lc[spans].lineconfig &= ~DAHDI_CONFIG_ESF; + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + } else if (!strcasecmp(realargs[3], "esf")) { + lc[spans].lineconfig |= DAHDI_CONFIG_ESF; + lc[spans].lineconfig &= ~DAHDI_CONFIG_D4; + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + } else if (!strcasecmp(realargs[3], "ccs")) { + lc[spans].lineconfig |= DAHDI_CONFIG_CCS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); + } else if (!strcasecmp(realargs[3], "cas")) { + lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); + } else { + error("Framing(T1)/Signalling(E1) must be one of 'd4', 'esf', 'cas' or 'ccs', not '%s'\n", realargs[3]); + return -1; + } + if (!strcasecmp(realargs[4], "ami")) { + lc[spans].lineconfig &= ~(DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_HDB3); + lc[spans].lineconfig |= DAHDI_CONFIG_AMI; + } else if (!strcasecmp(realargs[4], "b8zs")) { + lc[spans].lineconfig |= DAHDI_CONFIG_B8ZS; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3); + } else if (!strcasecmp(realargs[4], "hdb3")) { + lc[spans].lineconfig |= DAHDI_CONFIG_HDB3; + lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS); + } else { + error("Coding must be one of 'ami', 'b8zs' or 'hdb3', not '%s'\n", realargs[4]); + return -1; + } + for (i = 5; i < argc; i++) { + if (!strcasecmp(realargs[i], "yellow")) + lc[spans].lineconfig |= DAHDI_CONFIG_NOTOPEN; + else if (!strcasecmp(realargs[i], "crc4")) + lc[spans].lineconfig |= DAHDI_CONFIG_CRC4; + else if (!strcasecmp(realargs[i], "nt")) + lc[spans].lineconfig |= DAHDI_CONFIG_NTTE; + else if (!strcasecmp(realargs[i], "te")) + lc[spans].lineconfig &= ~DAHDI_CONFIG_NTTE; + else if (!strcasecmp(realargs[i], "term")) + lc[spans].lineconfig |= DAHDI_CONFIG_TERM; + else { + error("Remaining arguments may be any of: 'yellow', 'crc4', 'nt', 'te', 'term', not '%s'\n", realargs[i]); + return -1; + } + + } + lc[spans].span = span; + lc[spans].sync = timing; + /* Valid span */ + spans++; + return 0; +} + +int apply_channels(int chans[], char *argstr) +{ + char *args[DAHDI_MAX_CHANNELS+1]; + char *range[3]; + int res,x, res2,y; + int chan; + int start, finish; + char argcopy[256]; + res = parseargs(argstr, args, DAHDI_MAX_CHANNELS, ','); + if (res < 0) { + error("Too many arguments... Max is %d\n", DAHDI_MAX_CHANNELS); + return -1; + } + for (x=0;x-.\n", args[x]); + return -1; + } + res2 =sscanf(range[0], "%d", &start); + if (res2 != 1) { + error("Syntax error. Start of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); + return -1; + } else if ((start < 1) || (start >= DAHDI_MAX_CHANNELS)) { + error("Start of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, start); + return -1; + } + res2 =sscanf(range[1], "%d", &finish); + if (res2 != 1) { + error("Syntax error. End of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); + return -1; + } else if ((finish < 1) || (finish >= DAHDI_MAX_CHANNELS)) { + error("end of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, finish); + return -1; + } + if (start > finish) { + error("Range '%s' should start before it ends\n", args[x]); + return -1; + } + for (y=start;y<=finish;y++) + chans[y]=1; + } else { + /* It's a single channel */ + res2 =sscanf(args[x], "%d", &chan); + if (res2 != 1) { + error("Syntax error. Channel should be a number from 1 to %d, not '%s'\n", DAHDI_MAX_CHANNELS - 1, args[x]); + return -1; + } else if ((chan < 1) || (chan >= DAHDI_MAX_CHANNELS)) { + error("Channel must be between 1 and %d (not '%d')\n", DAHDI_MAX_CHANNELS - 1, chan); + return -1; + } + chans[chan]=1; + } + } + return res; +} + +int parse_idle(int *i, char *s) +{ + char a,b,c,d; + if (s) { + if (sscanf(s, "%c%c%c%c", &a,&b,&c,&d) == 4) { + if (((a == '0') || (a == '1')) && ((b == '0') || (b == '1')) && ((c == '0') || (c == '1')) && ((d == '0') || (d == '1'))) { + *i = 0; + if (a == '1') + *i |= DAHDI_ABIT; + if (b == '1') + *i |= DAHDI_BBIT; + if (c == '1') + *i |= DAHDI_CBIT; + if (d == '1') + *i |= DAHDI_DBIT; + return 0; + } + } + } + error("CAS Signalling requires idle definition in the form ':xxxx' at the end of the channel definition, where xxxx represent the a, b, c, and d bits\n"); + return -1; +} + +static int parse_channel(char *channel, int *startchan) +{ + if (!channel || (sscanf(channel, "%d", startchan) != 1) || + (*startchan < 1)) { + error("DACS requires a starting channel in the form ':x' where x is the channel\n"); + return -1; + } + return 0; +} + +static int chanconfig(char *keyword, char *args) +{ + int chans[DAHDI_MAX_CHANNELS]; + int res = 0; + int x; + int master=0; + int dacschan = 0; + char *idle; + int is_digital; + bzero(chans, sizeof(chans)); + strtok(args, ":"); + idle = strtok(NULL, ":"); + if (!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) { + res = parse_channel(idle, &dacschan); + } + if (!res) + res = apply_channels(chans, args); + if (res <= 0) + return -1; + for (x=1;x= DAHDI_TONE_ZONE_MAX) { + error("Too many tone zones specified\n"); + return 0; + } + dahdi_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0])); + return 0; +} + +static int defaultzone(char *keyword, char *args) +{ + struct tone_zone *z; + if (!(z = tone_zone_find(args))) { + error("No such tone zone known: %s\n", args); + return 0; + } + deftonezone = z->zone; + return 0; +} + +#if 0 +static int unimplemented(char *keyword, char *args) +{ + fprintf(stderr, "Warning: '%s' is not yet implemented\n", keyword); + return 0; +} +#endif + + +/* Radio functions */ + +int ctcss(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int rxtone; + int rxtag; + int txtone; + int isdcs = 0; + res = parseargs(args, realargs, 3, ','); + if (res != 3) { + error("Incorrect number of arguments to 'ctcss' (should be ,,)\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + res = sscanf(realargs[1], "%d", &rxtag); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid rxtag '%s', should be a number > 0.\n", realargs[1]); + return -1; + } + if ((*realargs[2] == 'D') || (*realargs[2] == 'd')) + { + realargs[2]++; + isdcs = 0x8000; + } + res = sscanf(realargs[2], "%d", &txtone); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid txtone '%s', should be a number > 0.\n", realargs[2]); + return -1; + } + + if (toneindex >= NUM_TONES) + { + error("Cannot specify more then %d CTCSS tones\n",NUM_TONES); + return -1; + } + rxtones[toneindex] = rxtone; + rxtags[toneindex] = rxtag; + txtones[toneindex] = txtone | isdcs; + toneindex++; + return 0; +} + +int dcsrx(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int rxtone; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'dcsrx' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + rxtones[0] = rxtone; + return 0; +} + +int tx(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int txtone; + int isdcs = 0; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'tx' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'D') || (*realargs[0] == 'd')) + { + realargs[0]++; + isdcs = 0x8000; + } + res = sscanf(realargs[0], "%d", &txtone); + if ((res == 1) && (txtone < 1)) + res = -1; + if (res != 1) { + error("Invalid tx (tone) '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + txtones[0] = txtone | isdcs; + return 0; +} + +int debounce_time(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'debouncetime' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + debouncetime = val; + return 0; +} + +int burst_time(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'bursttime' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + bursttime = val; + return 0; +} + +int tx_gain(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'txgain' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + txgain = val; + return 0; +} + +int rx_gain(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'rxgain' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + rxgain = val; + return 0; +} + +int de_emp(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'de-emp' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + deemp = val; + return 0; +} + +int pre_emp(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'pre_emp' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + + preemp = val; + return 0; +} + +int invert_cor(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'invertcor' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + } + invertcor = (val > 0); + return 0; +} + +int ext_tone(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'exttone' (should be )\n"); + return -1; + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else if ((*realargs[0] == 'i') || (*realargs[0] == 'I')) val = 2; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (val > 2) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + } + exttone = val; + return 0; +} + +int cor_thresh(char *keyword, char *args) +{ + static char *realargs[10]; + int res; + int val; + int x = 0; + res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'corthresh' (should be )\n"); + return -1; + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + for(x = 0; corthreshes[x]; x++) + { + if (corthreshes[x] == val) break; + } + if (!corthreshes[x]) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + return -1; + } + corthresh = x + 1; + return 0; +} + +static int rad_chanconfig(char *keyword, char *args) +{ + int chans[DAHDI_MAX_CHANNELS]; + int res = 0; + int x,i,n; + struct dahdi_radio_param p; + int chanfd; + + toneindex = 1; + bzero(chans, sizeof(chans)); + res = apply_channels(chans, args); + if (res <= 0) + return -1; + for (x=1;x 1) { + printf("\nChannel map:\n\n"); + for (x=1;x -- Use instead of " CONFIG_FILENAME "\n" + " -d [level] -- Generate debugging output. (Default level is 1.)\n" + " -f -- Always reconfigure every channel\n" + " -h -- Generate this help statement\n" + " -s -- Shutdown spans only\n" + " -t -- Test mode only, do not apply\n" + " -C -- Only configure specified channels\n" + " -S -- Only configure specified span\n" + " -v -- Verbose (more -v's means more verbose)\n" + ,c); + exit(exitcode); +} + +static int chan_restrict(char *str) +{ + if (apply_channels(selected_channels, str) < 0) + return 0; + restrict_channels = 1; + return 1; +} + +static int span_restrict(char *str) +{ + long spanno; + char *endptr; + + spanno = strtol(str, &endptr, 10); + if (endptr == str) { + fprintf(stderr, "Missing valid span number after '-S'\n"); + return 0; + } + if (*endptr != '\0') { + fprintf(stderr, "Extra garbage after span number in '-S'\n"); + return 0; + } + only_span = spanno; + return 1; +} + +static const char *SEM_NAME = "dahdi_cfg"; +static sem_t *lock = SEM_FAILED; + +static void signal_handler(int signal) +{ + if (SEM_FAILED != lock) { + sem_unlink(SEM_NAME); + } + /* The default handler should have been restored before this handler was + * called, so we can let the "normal" processing finish the cleanup. */ + raise(signal); +} + +int main(int argc, char *argv[]) +{ + int c; + char *buf; + char *key, *value; + int x,found; + int exit_code = 0; + struct sigaction act; + + while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) { + switch(c) { + case 'c': + filename=optarg; + break; + case 'h': + usage(argv[0], 0); + break; + case '?': + usage(argv[0], 1); + break; + case 'v': + verbose++; + break; + case 'f': + force++; + break; + case 't': + dry_run = 1; + break; + case 's': + stopmode = 1; + break; + case 'C': + if (!chan_restrict(optarg)) + usage(argv[0], 1); + break; + case 'S': + if (!span_restrict(optarg)) + usage(argv[0], 1); + break; + case 'd': + if (optarg) + debug = atoi(optarg); + else + debug = 1; + break; + } + } + + if (verbose) { + fprintf(stderr, "%s\n", dahdi_tools_version); + } + + if (!restrict_channels && !only_span) { + bool all_assigned = wait_for_all_spans_assigned(5); + + if (!all_assigned) { + fprintf(stderr, + "Timeout waiting for all spans to be assigned.\n"); + } + } + + if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); + if (fd < 0) { + error("Unable to open master device '%s'\n", MASTER_DEVICE); + goto finish; + } + if (strcmp(filename, "-") == 0) + cf = fdopen(STDIN_FILENO, "r"); + else + cf = fopen(filename, "r"); + if (cf) { + while((buf = readline())) { + if (*buf == 10) /* skip new line */ + continue; + + if (debug & DEBUG_READER) + fprintf(stderr, "Line %d: %s\n", lineno, buf); + + if ((value = strchr(buf, '='))) { + *value++ = '\0'; + value = trim(value); + key = trim(buf); + } + + if (!value || !*value || !*key) { + error("Syntax error. Should be =\n"); + continue; + } + + if (debug & DEBUG_PARSER) + fprintf(stderr, "Keyword: [%s], Value: [%s]\n", key, value); + + found = 0; + for (x = 0; x < sizeof(handlers) / sizeof(handlers[0]); x++) { + if (!strcasecmp(key, handlers[x].keyword)) { + found++; + handlers[x].func(key, value); + break; + } + } + + if (!found) + error("Unknown keyword '%s'\n", key); + } + if (debug & DEBUG_READER) + fprintf(stderr, "\n"); + /* fclose(cf); // causes seg fault (double free) */ + } else { + error("Unable to open configuration file '%s'\n", filename); + } + +finish: + if (errcnt) { + fprintf(stderr, "\n%d error(s) detected\n\n", errcnt); + exit(1); + } + if (verbose) { + printconfig(fd); + } + + if (dry_run) + exit(0); + + if (debug & DEBUG_APPLY) { + printf("About to open Master device\n"); + fflush(stdout); + } + + sigemptyset(&act.sa_mask); + act.sa_handler = signal_handler; + act.sa_flags = SA_RESETHAND; + + if (sigaction(SIGTERM, &act, NULL) == -1) { + perror("Failed to install SIGTERM handler."); + exit(1); + } + if (sigaction(SIGINT, &act, NULL) == -1) { + perror("Failed to install SIGINT handler."); + exit(1); + } + + lock = sem_open(SEM_NAME, O_CREAT, O_RDWR, 1); + if (SEM_FAILED == lock) { + perror("Unable to create 'dahdi_cfg' mutex"); + exit_code = 1; + goto release_sem; + } + + if (-1 == sem_wait(lock)) { + perror("Failed to wait for 'dahdi_cfg' mutex"); + exit_code = 1; + goto unlink_sem; + } + + if (!restrict_channels && !only_span) { + for (x=0;x> 16; + + if (cc[x].sigtype != current_state.sigtype) { + needupdate++; + if (verbose > 1) + printf("Changing signalling on channel %d from %s to %s\n", + cc[x].chan, sigtype_to_str(current_state.sigtype), + sigtype_to_str(cc[x].sigtype)); + } + + if ((cc[x].deflaw != DAHDI_LAW_DEFAULT) && (cc[x].deflaw != current_state.curlaw)) { + needupdate++; + if (verbose > 1) + printf("Changing law on channel %d from %s to %s\n", + cc[x].chan, laws[current_state.curlaw], + laws[cc[x].deflaw]); + } + + if (cc[x].master != master) { + needupdate++; + if (verbose > 1) + printf("Changing master of channel %d from %d to %d\n", + cc[x].chan, master, + cc[x].master); + } + + if (cc[x].idlebits != current_state.idlebits) { + needupdate++; + if (verbose > 1) + printf("Changing idle bits of channel %d from %d to %d\n", + cc[x].chan, current_state.idlebits, + cc[x].idlebits); + } + } + + if (needupdate && ioctl(fd, DAHDI_CHANCONFIG, &cc[x])) { + fprintf(stderr, "DAHDI_CHANCONFIG failed on channel %d: %s (%d)\n", x, strerror(errno), errno); + if (errno == EINVAL) { + /* give helpful suggestions on signaling errors */ + fprintf(stderr, "Selected signaling not " + "supported\n"); + fprintf(stderr, "Possible causes:\n"); + switch(cc[x].sigtype) { + case DAHDI_SIG_FXOKS: + case DAHDI_SIG_FXOLS: + case DAHDI_SIG_FXOGS: + fprintf(stderr, "\tFXO signaling is " + "being used on a FXO interface" + " (use a FXS signaling variant" + ")\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_FXSKS: + case DAHDI_SIG_FXSLS: + case DAHDI_SIG_FXSGS: + fprintf(stderr, "\tFXS signaling is " + "being used on a FXS interface" + " (use a FXO signaling variant" + ")\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_EM: + fprintf(stderr, "\te&m signaling is " + "being used on a E1 line (use" + " e&me1)\n"); + break; + case DAHDI_SIG_EM_E1: + fprintf(stderr, "\te&me1 signaling is " + "being used on a T1 line (use " + "e&m)\n"); + fprintf(stderr, "\tRBS signaling is " + "being used on a E1 CCS span" + "\n"); + break; + case DAHDI_SIG_HARDHDLC: + fprintf(stderr, "\thardhdlc is being " + "used on a TE12x (use dchan)\n" + ); + break; + case DAHDI_SIG_HDLCFCS: + fprintf(stderr, "\tdchan is being used" + " on a BRI span (use hardhdlc)" + "\n"); + break; + default: + break; + } + fprintf(stderr, "\tSignaling is being assigned" + " to channel 16 of an E1 CAS span\n"); + } + close(fd); + exit_code = 1; + goto release_sem; + } + + ae[x].chan = x; + if (verbose) { + printf("Setting echocan for channel %d to %s\n", ae[x].chan, ae[x].echocan[0] ? ae[x].echocan : "none"); + } + + if (ioctl(fd, DAHDI_ATTACH_ECHOCAN, &ae[x])) { + fprintf(stderr, "DAHDI_ATTACH_ECHOCAN failed on channel %d: %s (%d)\n", x, strerror(errno), errno); + close(fd); + exit_code = 1; + goto release_sem; + } + } + if (0 == numzones) { + /* Default to the us zone if one wasn't specified. */ + dahdi_copy_string(zonestoload[numzones++], "us", sizeof(zonestoload[0])); + deftonezone = 0; + } + + for (x=0;x -1) { + if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) { + fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno); + close(fd); + exit_code = 1; + goto release_sem; + } + } + for (x=0;x + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +int main(int argc, char *argv[]) +{ + int fd; + int chan; + if ((argc < 2) || (sscanf(argv[1], "%d", &chan) != 1)) { + fprintf(stderr, "Usage: dahdi_diag \n"); + exit(1); + } + fd = open("/dev/dahdi/ctl", O_RDWR); + if (fd < 0) { + perror("open(/dev/dahdi/ctl"); + exit(1); + } + if (ioctl(fd, DAHDI_CHANDIAG, &chan)) { + perror("ioctl(DAHDI_CHANDIAG)"); + exit(1); + } + exit(0); +} diff --git a/dahdi_maint.c b/dahdi_maint.c new file mode 100644 index 0000000..6777510 --- /dev/null +++ b/dahdi_maint.c @@ -0,0 +1,254 @@ +/* + * Performance and Maintenance utility + * + * Written by Russ Meyerriecks + * + * Copyright (C) 2009-2010 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#define DAHDI_CTL "/dev/dahdi/ctl" + +extern char *optarg; +extern int optind; + +void display_help(char *argv0, int exitcode) +{ + char *c; + c = strrchr(argv0, '/'); + if (!c) + c = argv0; + else + c++; + fprintf(stderr, "%s\n\n", dahdi_tools_version); + fprintf(stderr, "Usage: %s -s \n", c); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -h, --help display help\n"); + fprintf(stderr, " -s, --span specify the span\n"); + fprintf(stderr, " -l, --loopback \n"\ + "\t\tlocalhost - loop back towards host\n"\ + "\t\tnetworkline - network line loopback\n"\ + "\t\tnetworkpayload - network payload loopback\n"\ + "\t\tloopup - transmit loopup signal\n"\ + "\t\tloopdown - transmit loopdown signal\n"\ + "\t\toff - end loopback mode\n"); + fprintf(stderr, " -i, --insert "\ + "\n\t\tinsert an error of a specific type\n"); + fprintf(stderr, " -r, --reset "\ + "reset the error counters\n\n"); + fprintf(stderr, "Examples: \n"); + fprintf(stderr, "Enable network line loopback\n"); + fprintf(stderr, " dahdi_maint -s 1 --loopback networkline\n"); + fprintf(stderr, "Disable network line loopback\n"); + fprintf(stderr, " dahdi_maint -s 1 --loopback off\n\n"); + + exit(exitcode); +} + +int main(int argc, char *argv[]) +{ + static int ctl = -1; + int res; + + int doloopback = 0; + char *larg = NULL; + int span = 1; + int iflag = 0; + char *iarg = NULL; + int gflag = 0; + int c; + int rflag = 0; + + struct dahdi_maintinfo m; + struct dahdi_spaninfo s; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"loopback", required_argument, 0, 'l'}, + {"span", required_argument, 0, 's'}, + {"insert", required_argument, 0, 'i'}, + {"reset", no_argument, 0, 'r'}, + {0, 0, 0, 0} + }; + int option_index = 0; + + if (argc < 2) { /* no options */ + display_help(argv[0], 1); + } + + while ((c = getopt_long(argc, argv, "hj:l:p:s:i:g:r", + long_options, &option_index)) != -1) { + switch (c) { + case 'h': + display_help(argv[0], 0); + break; + case 'l': /* loopback */ + larg = optarg; + doloopback = 1; + break; + case 's': /* specify a span */ + span = atoi(optarg); + break; + case 'i': /* insert an error */ + iarg = optarg; + iflag = 1; + break; + case 'g': /* generate psuedo random sequence */ + gflag = 1; + break; + case 'r': /* reset the error counters */ + rflag = 1; + break; + } + } + + ctl = open(DAHDI_CTL, O_RDWR); + if (ctl < 0) { + fprintf(stderr, "Unable to open %s\n", DAHDI_CTL); + return -1; + } + + if (!(doloopback || iflag || gflag || rflag)) { + s.spanno = span; + res = ioctl(ctl, DAHDI_SPANSTAT, &s); + if (res || ((__u32)-1 == s.fecount)) + printf("Error counters not supported by the driver"\ + " for this span\n"); + printf("Span %d:\n", span); + printf(">Framing Errors : %d:\n", s.fecount); + printf(">CRC Errors : %d:\n", s.crc4count); + printf(">Code Violations : %d:\n", s.cvcount); + printf(">E-bit Count : %d:\n", s.ebitcount); + printf(">General Errored Seconds : %d:\n", s.errsec); + + return 0; + } + + m.spanno = span; + + if (doloopback) { + if (!strcasecmp(larg, "localhost")) { + printf("Span %d: local host loopback ON\n", span); + m.command = DAHDI_MAINT_LOCALLOOP; + } else if (!strcasecmp(larg, "networkline")) { + printf("Span %d: network line loopback ON\n", span); + m.command = DAHDI_MAINT_NETWORKLINELOOP; + } else if (!strcasecmp(larg, "networkpayload")) { + printf("Span %d: network payload loopback ON\n", span); + m.command = DAHDI_MAINT_NETWORKPAYLOADLOOP; + } else if (!strcasecmp(larg, "loopup")) { + printf("Span %d: transmitting loopup signal\n", span); + m.command = DAHDI_MAINT_LOOPUP; + } else if (!strcasecmp(larg, "loopdown")) { + printf("Span %d: transmitting loopdown signal\n", span); + m.command = DAHDI_MAINT_LOOPDOWN; + } else if (!strcasecmp(larg, "off")) { + printf("Span %d: loopback OFF\n", span); + m.command = DAHDI_MAINT_NONE; + } else { + display_help(argv[0], 1); + } + + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("This type of looping not supported by the"\ + " driver for this span\n"); + return 1; + } + + /* Leave the loopup/loopdown signal on the line for + * five seconds according to AT&T TR 54016 + */ + if ((m.command == DAHDI_MAINT_LOOPUP) || + (m.command == DAHDI_MAINT_LOOPDOWN)) { + sleep(5); + m.command = DAHDI_MAINT_NONE; + ioctl(ctl, DAHDI_MAINT, &m); + } + } + + if (iflag) { + if (!strcasecmp(iarg, "fas")) { + m.command = DAHDI_MAINT_FAS_DEFECT; + printf("Inserting a single FAS defect\n"); + } else if (!strcasecmp(iarg, "multi")) { + m.command = DAHDI_MAINT_MULTI_DEFECT; + printf("Inserting a single multiframe defect\n"); + } else if (!strcasecmp(iarg, "crc")) { + m.command = DAHDI_MAINT_CRC_DEFECT; + printf("Inserting a single CRC defect\n"); + } else if (!strcasecmp(iarg, "cas")) { + m.command = DAHDI_MAINT_CAS_DEFECT; + printf("Inserting a single CAS defect\n"); + } else if (!strcasecmp(iarg, "prbs")) { + m.command = DAHDI_MAINT_PRBS_DEFECT; + printf("Inserting a single PRBS defect\n"); + } else if (!strcasecmp(iarg, "bipolar")) { + m.command = DAHDI_MAINT_BIPOLAR_DEFECT; + printf("Inserting a single bipolar defect\n"); +#ifdef DAHDI_MAINT_ALARM_SIM + } else if (!strcasecmp(iarg, "sim")) { + m.command = DAHDI_MAINT_ALARM_SIM; + printf("Incrementing alarm simulator\n"); +#endif + } else { + display_help(argv[0], 1); + } + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) + printf("This type of error injection is not supported"\ + " by the driver for this span\n"); + } + + if (gflag) { + printf("Enabled the Pseudo-Random Binary Sequence Generation"\ + " and Monitor\n"); + m.command = DAHDI_MAINT_PRBS; + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("Pseudo-random binary sequence generation is"\ + " not supported by the driver for this span\n"); + } + } + + if (rflag) { + printf("Resetting error counters for span %d\n", span); + m.command = DAHDI_RESET_COUNTERS; + res = ioctl(ctl, DAHDI_MAINT, &m); + if (res) { + printf("Resetting error counters is not supported by"\ + " the driver for this span\n"); + } + } + + return 0; +} diff --git a/dahdi_monitor.c b/dahdi_monitor.c new file mode 100644 index 0000000..79f46dd --- /dev/null +++ b/dahdi_monitor.c @@ -0,0 +1,785 @@ +/* + * Monitor a DAHDI Channel + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" +#include "wavformat.h" +#include "autoconfig.h" + +#ifdef HAVE_SYS_SOUNDCARD_H +# include +#else +# ifdef HAVE_LINUX_SOUNDCARD_H +# include +# else +# error "Your installation appears to be missing soundcard.h which is needed to continue." +# endif +#endif + +/* +* defines for file handle numbers +*/ +#define MON_BRX 0 /*!< both channels if multichannel==1 or receive otherwise */ +#define MON_TX 1 /*!< transmit channel */ +#define MON_PRE_BRX 2 /*!< same as MON_BRX but before echo cancellation */ +#define MON_PRE_TX 3 /*!< same as MON_TX but before echo cancellation */ +#define MON_STEREO 4 /*!< stereo mix of rx/tx streams */ +#define MON_PRE_STEREO 5 /*!< stereo mix of rx/tx before echo can. This is exactly what is fed into the echo can */ + +#define BLOCK_SIZE 240 + +#define BUFFERS 4 + +#define FRAG_SIZE 8 + +#define MAX_OFH 6 + +/* Put the ofh (output file handles) outside the main loop in case we ever add a + * signal handler. + */ +static FILE *ofh[MAX_OFH]; +static int run = 1; + +static int stereo; +static int verbose; + +/* handler to catch ctrl-c */ +void cleanup_and_exit(int signal) +{ + fprintf(stderr, "cntrl-c pressed\n"); + run = 0; /* stop reading */ +} + +int filename_is_wav(char *filename) +{ + if (NULL != strstr(filename, ".wav")) + return 1; + return 0; +} + +/* + * Fill the wav header with default info + * num_chans - 0 = mono; 1 = stereo + */ +void wavheader_init(struct wavheader *wavheader, int num_chans) +{ + memset(wavheader, 0, sizeof(struct wavheader)); + + memcpy(&wavheader->riff_chunk_id, "RIFF", 4); + memcpy(&wavheader->riff_type, "WAVE", 4); + + memcpy(&wavheader->fmt_chunk_id, "fmt ", 4); + wavheader->fmt_data_size = 16; + wavheader->fmt_compression_code = 1; + wavheader->fmt_num_channels = num_chans; + wavheader->fmt_sample_rate = 8000; + wavheader->fmt_avg_bytes_per_sec = 16000; + wavheader->fmt_block_align = 2; + wavheader->fmt_significant_bps = 16; + + memcpy(&wavheader->data_chunk_id, "data", 4); +} + +int audio_open(void) +{ + int fd; + int speed = 8000; + int fmt = AFMT_S16_LE; + int fragsize = (BUFFERS << 16) | (FRAG_SIZE); + struct audio_buf_info ispace, ospace; + fd = open("/dev/dsp", O_WRONLY); + if (fd < 0) { + fprintf(stderr, "Unable to open /dev/dsp: %s\n", strerror(errno)); + return -1; + } + /* Step 1: Signed linear */ + if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0) { + fprintf(stderr, "ioctl(SETFMT) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + /* Step 2: Make non-stereo */ + if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) { + fprintf(stderr, "ioctl(STEREO) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + if (stereo != 0) { + fprintf(stderr, "Can't turn stereo off :(\n"); + } + /* Step 3: Make 8000 Hz */ + if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { + fprintf(stderr, "ioctl(SPEED) failed: %s\n", strerror(errno)); + close(fd); + return -1; + } + if (speed != 8000) { + fprintf(stderr, "Warning: Requested 8000 Hz, got %d\n", speed); + } + if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) { + fprintf(stderr, "Sound card won't let me set fragment size to %u %u-byte buffers (%x)\n" + "so sound may be choppy: %s.\n", BUFFERS, (1 << FRAG_SIZE), fragsize, strerror(errno)); + } + bzero(&ispace, sizeof(ispace)); + bzero(&ospace, sizeof(ospace)); + + if (ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace)) { + /* They don't support block size stuff, so just return but notify the user */ + fprintf(stderr, "Sound card won't let me know the input buffering...\n"); + } + if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace)) { + /* They don't support block size stuff, so just return but notify the user */ + fprintf(stderr, "Sound card won't let me know the output buffering...\n"); + } + fprintf(stderr, "New input space: %d of %d %d byte fragments (%d bytes left)\n", + ispace.fragments, ispace.fragstotal, ispace.fragsize, ispace.bytes); + fprintf(stderr, "New output space: %d of %d %d byte fragments (%d bytes left)\n", + ospace.fragments, ospace.fragstotal, ospace.fragsize, ospace.bytes); + return fd; +} + +int pseudo_open(void) +{ + int fd; + int x = 1; + fd = open("/dev/dahdi/pseudo", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open pseudo channel: %s\n", strerror(errno)); + return -1; + } + if (ioctl(fd, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set linear mode: %s\n", strerror(errno)); + close(fd); + return -1; + } + x = BLOCK_SIZE; + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &x)) { + fprintf(stderr, "unable to set sane block size: %s\n", strerror(errno)); + close(fd); + return -1; + } + return fd; +} + +#define barlen 35 +#define baroptimal 3250 +//define barlevel 200 +#define barlevel ((baroptimal/barlen)*2) +#define maxlevel (barlen*barlevel) + +void draw_barheader() +{ + char bar[barlen + 4]; + + memset(bar, '-', sizeof(bar)); + memset(bar, '<', 1); + memset(bar + barlen + 2, '>', 1); + memset(bar + barlen + 3, '\0', 1); + + memcpy(bar + (barlen / 2), "(RX)", 4); + printf("%s", bar); + + memcpy(bar + (barlen / 2), "(TX)", 4); + printf(" %s\n", bar); +} + +void draw_bar(int avg, int max) +{ + char bar[barlen+5]; + + memset(bar, ' ', sizeof(bar)); + + max /= barlevel; + avg /= barlevel; + if (avg > barlen) + avg = barlen; + if (max > barlen) + max = barlen; + + if (avg > 0) + memset(bar, '#', avg); + if (max > 0) + memset(bar + max, '*', 1); + + bar[barlen+1] = '\0'; + printf("%s", bar); + fflush(stdout); +} + +void visualize(short *tx, short *rx, int cnt) +{ + int x; + float txavg = 0; + float rxavg = 0; + static int txmax = 0; + static int rxmax = 0; + static int sametxmax = 0; + static int samerxmax = 0; + static int txbest = 0; + static int rxbest = 0; + float ms; + static struct timeval last; + struct timeval tv; + + gettimeofday(&tv, NULL); + ms = (tv.tv_sec - last.tv_sec) * 1000.0 + (tv.tv_usec - last.tv_usec) / 1000.0; + for (x = 0; x < cnt; x++) { + txavg += abs(tx[x]); + rxavg += abs(rx[x]); + } + txavg = abs(txavg / cnt); + rxavg = abs(rxavg / cnt); + + if (txavg > txbest) + txbest = txavg; + if (rxavg > rxbest) + rxbest = rxavg; + + /* Update no more than 10 times a second */ + if (ms < 100) + return; + + /* Save as max levels, if greater */ + if (txbest > txmax) { + txmax = txbest; + sametxmax = 0; + } + if (rxbest > rxmax) { + rxmax = rxbest; + samerxmax = 0; + } + + memcpy(&last, &tv, sizeof(last)); + + /* Clear screen */ + printf("\r "); + draw_bar(rxbest, rxmax); + printf(" "); + draw_bar(txbest, txmax); + if (verbose) + printf(" Rx: %5d (%5d) Tx: %5d (%5d)", rxbest, rxmax, txbest, txmax); + txbest = 0; + rxbest = 0; + + /* If we have had the same max hits for x times, clear the values */ + sametxmax++; + samerxmax++; + if (sametxmax > 6) { + txmax = 0; + sametxmax = 0; + } + if (samerxmax > 6) { + rxmax = 0; + samerxmax = 0; + } +} + +int main(int argc, char *argv[]) +{ + int afd = -1; + int pfd[4] = {-1, -1, -1, -1}; + short buf_brx[BLOCK_SIZE * 2]; + short buf_tx[BLOCK_SIZE * 4]; + short stereobuf[BLOCK_SIZE * 4]; + int res_brx, res_tx; + int visual = 0; + int multichannel = 0; + int ossoutput = 0; + int preecho = 0; + int savefile = 0; + int stereo_output = 0; + int limit = 0; + int readcount = 0; + int x, chan; + struct dahdi_confinfo zc; + int opt; + extern char *optarg; + struct wavheader wavheaders[MAX_OFH]; /* we have one for each potential filehandle */ + unsigned int bytes_written[MAX_OFH] = {0}; + int file_is_wav[MAX_OFH] = {0}; + int i; + + if ((argc < 2) || (atoi(argv[1]) < 1)) { + fprintf(stderr, "Usage: dahdi_monitor [-v[v]] [-m] [-o] [-l limit] [-f FILE | -s FILE | -r FILE1 -t FILE2] [-F FILE | -S FILE | -R FILE1 -T FILE2]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -v: Visual mode. Implies -m.\n"); + fprintf(stderr, " -vv: Visual/Verbose mode. Implies -m.\n"); + fprintf(stderr, " -l LIMIT: Stop after reading LIMIT bytes\n"); + fprintf(stderr, " -m: Separate rx/tx streams.\n"); + fprintf(stderr, " -o: Output audio via OSS. Note: Only 'normal' combined rx/tx streams are output via OSS.\n"); + fprintf(stderr, " -f FILE: Save combined rx/tx stream to mono FILE. Cannot be used with -m.\n"); + fprintf(stderr, " -r FILE: Save rx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -t FILE: Save tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -s FILE: Save stereo rx/tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -F FILE: Save combined pre-echocanceled rx/tx stream to FILE. Cannot be used with -m.\n"); + fprintf(stderr, " -R FILE: Save pre-echocanceled rx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -T FILE: Save pre-echocanceled tx stream to FILE. Implies -m.\n"); + fprintf(stderr, " -S FILE: Save pre-echocanceled stereo rx/tx stream to FILE. Implies -m.\n"); + fprintf(stderr, "Examples:\n"); + fprintf(stderr, "Save a stream to a file\n"); + fprintf(stderr, " dahdi_monitor 1 -f stream.raw\n"); + fprintf(stderr, "Visualize an rx/tx stream and save them to separate files.\n"); + fprintf(stderr, " dahdi_monitor 1 -v -r streamrx.raw -t streamtx.raw\n"); + fprintf(stderr, "Play a combined rx/tx stream via OSS and save it to a file\n"); + fprintf(stderr, " dahdi_monitor 1 -o -f stream.raw\n"); + fprintf(stderr, "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n"); + fprintf(stderr, " dahdi_monitor 1 -f stream.raw -F streampreecho.raw\n"); + fprintf(stderr, "Save a normal rx/tx stream and a 'preecho' rx/tx stream to separate files\n"); + fprintf(stderr, " dahdi_monitor 1 -m -r streamrx.raw -t streamtx.raw -R streampreechorx.raw -T streampreechotx.raw\n"); + exit(1); + } + + chan = atoi(argv[1]); + + while ((opt = getopt(argc, argv, "vmol:f:r:t:s:F:R:T:S:")) != -1) { + switch (opt) { + case '?': + exit(EXIT_FAILURE); + case 'v': + if (visual) + verbose = 1; + visual = 1; + multichannel = 1; + break; + case 'm': + multichannel = 1; + break; + case 'o': + ossoutput = 1; + break; + case 'l': + if (sscanf(optarg, "%d", &limit) != 1 || limit < 0) + limit = 0; + fprintf(stderr, "Will stop reading after %d bytes\n", limit); + break; + case 'f': + if (multichannel) { + fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing combined stream to %s\n", optarg); + file_is_wav[MON_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_BRX]) { + wavheader_init(&wavheaders[MON_BRX], 1); + if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + savefile = 1; + break; + case 'F': + if (multichannel) { + fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo combined stream to %s\n", optarg); + file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_BRX]) { + wavheader_init(&wavheaders[MON_PRE_BRX], 1); + if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + savefile = 1; + break; + case 'r': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing receive stream to %s\n", optarg); + file_is_wav[MON_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_BRX]) { + wavheader_init(&wavheaders[MON_BRX], 1); + if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + break; + case 'R': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_BRX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo receive stream to %s\n", optarg); + file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_BRX]) { + wavheader_init(&wavheaders[MON_PRE_BRX], 1); + if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + break; + case 't': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_TX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_TX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing transmit stream to %s\n", optarg); + file_is_wav[MON_TX] = filename_is_wav(optarg); + if (file_is_wav[MON_TX]) { + wavheader_init(&wavheaders[MON_TX], 1); + if (fwrite(&wavheaders[MON_TX], 1, sizeof(struct wavheader), ofh[MON_TX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + break; + case 'T': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_TX]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_TX] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo transmit stream to %s\n", optarg); + file_is_wav[MON_PRE_TX] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_TX]) { + wavheader_init(&wavheaders[MON_PRE_TX], 1); + if (fwrite(&wavheaders[MON_PRE_TX], 1, sizeof(struct wavheader), ofh[MON_PRE_TX]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + break; + case 's': + if (!multichannel && ofh[MON_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_STEREO]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_STEREO] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing stereo stream to %s\n", optarg); + file_is_wav[MON_STEREO] = filename_is_wav(optarg); + if (file_is_wav[MON_STEREO]) { + wavheader_init(&wavheaders[MON_STEREO], 2); + if (fwrite(&wavheaders[MON_STEREO], 1, sizeof(struct wavheader), ofh[MON_STEREO]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + multichannel = 1; + savefile = 1; + stereo_output = 1; + break; + case 'S': + if (!multichannel && ofh[MON_PRE_BRX]) { + fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); + exit(EXIT_FAILURE); + } + if (ofh[MON_PRE_STEREO]) { + fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); + exit(EXIT_FAILURE); + } + if ((ofh[MON_PRE_STEREO] = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Writing pre-echo stereo stream to %s\n", optarg); + file_is_wav[MON_PRE_STEREO] = filename_is_wav(optarg); + if (file_is_wav[MON_PRE_STEREO]) { + wavheader_init(&wavheaders[MON_PRE_STEREO], 2); + if (fwrite(&wavheaders[MON_PRE_STEREO], 1, sizeof(struct wavheader), ofh[MON_PRE_STEREO]) != sizeof(struct wavheader)) { + fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); + exit(EXIT_FAILURE); + } + } + preecho = 1; + multichannel = 1; + savefile = 1; + stereo_output = 1; + break; + } + } + + if (ossoutput) { + if (multichannel) { + printf("Multi-channel audio is enabled. OSS output will be disabled.\n"); + ossoutput = 0; + } else { + /* Open audio */ + if ((afd = audio_open()) < 0) { + printf("Cannot open audio ...\n"); + ossoutput = 0; + } + } + } + if (!ossoutput && !multichannel && !savefile) { + fprintf(stderr, "Nothing to do with the stream(s) ...\n"); + exit(1); + } + + /* Open Pseudo device */ + if ((pfd[MON_BRX] = pseudo_open()) < 0) + exit(1); + if (multichannel && ((pfd[MON_TX] = pseudo_open()) < 0)) + exit(1); + if (preecho) { + if ((pfd[MON_PRE_BRX] = pseudo_open()) < 0) + exit(1); + if (multichannel && ((pfd[MON_PRE_TX] = pseudo_open()) < 0)) + exit(1); + } + /* Conference them */ + if (multichannel) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + /* Two pseudo's, one for tx, one for rx */ + zc.confmode = DAHDI_CONF_MONITOR; + if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORTX; + if (ioctl(pfd[MON_TX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + /* Two pseudo's, one for tx, one for rx */ + zc.confmode = DAHDI_CONF_MONITOR_RX_PREECHO; + if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITOR_TX_PREECHO; + if (ioctl(pfd[MON_PRE_TX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } + } else { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORBOTH; + if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = chan; + zc.confmode = DAHDI_CONF_MONITORBOTH_PREECHO; + if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } + } + if (signal(SIGINT, cleanup_and_exit) == SIG_ERR) { + fprintf(stderr, "Error registering signal handler: %s\n", strerror(errno)); + } + if (visual) { + printf("\nVisual Audio Levels.\n"); + printf("--------------------\n"); + printf(" Use chan_dahdi.conf file to adjust the gains if needed.\n\n"); + printf("( # = Audio Level * = Max Audio Hit )\n"); + draw_barheader(); + } + /* Now, copy from pseudo to audio */ + while (run) { + res_brx = read(pfd[MON_BRX], buf_brx, sizeof(buf_brx)); + if (res_brx < 1) + break; + readcount += res_brx; + if (ofh[MON_BRX]) + bytes_written[MON_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_BRX]); + + if (multichannel) { + res_tx = read(pfd[MON_TX], buf_tx, res_brx); + if (res_tx < 1) + break; + if (ofh[MON_TX]) + bytes_written[MON_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_TX]); + + if (stereo_output && ofh[MON_STEREO]) { + for (x = 0; x < res_tx; x++) { + stereobuf[x*2] = buf_brx[x]; + stereobuf[x*2+1] = buf_tx[x]; + } + bytes_written[MON_STEREO] += fwrite(stereobuf, 1, res_tx*2, ofh[MON_STEREO]); + } + + if (visual) { + if (res_brx == res_tx) + visualize((short *)buf_tx, (short *)buf_brx, res_brx/2); + else + printf("Huh? res_tx = %d, res_brx = %d?\n", res_tx, res_brx); + } + } + + if (preecho) { + res_brx = read(pfd[MON_PRE_BRX], buf_brx, sizeof(buf_brx)); + if (res_brx < 1) + break; + if (ofh[MON_PRE_BRX]) + bytes_written[MON_PRE_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_PRE_BRX]); + + if (multichannel) { + res_tx = read(pfd[MON_PRE_TX], buf_tx, res_brx); + if (res_tx < 1) + break; + if (ofh[MON_PRE_TX]) + bytes_written[MON_PRE_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_PRE_TX]); + + if (stereo_output && ofh[MON_PRE_STEREO]) { + for (x = 0; x < res_brx; x++) { + stereobuf[x*2] = buf_brx[x]; + stereobuf[x*2+1] = buf_tx[x]; + } + bytes_written[MON_PRE_STEREO] += fwrite(stereobuf, 1, res_brx * 2, ofh[MON_PRE_STEREO]); + } + } + } + + if (ossoutput && afd) { + if (stereo) { + for (x = 0; x < res_brx; x++) { + buf_tx[x << 1] = buf_tx[(x << 1) + 1] = buf_brx[x]; + } + x = write(afd, buf_tx, res_brx << 1); + } else { + x = write(afd, buf_brx, res_brx); + } + } + + if (limit && readcount >= limit) { + /* bail if we've read too much */ + break; + } + } + /* write filesize info */ + for (i = 0; i < MAX_OFH; i++) { + if (NULL == ofh[i]) + continue; + if (!(file_is_wav[i])) + continue; + + wavheaders[i].riff_chunk_size = (bytes_written[i]) + sizeof(struct wavheader) - 8; /* filesize - 8 */ + wavheaders[i].data_data_size = bytes_written[i]; + + rewind(ofh[i]); + if (fwrite(&wavheaders[i], 1, sizeof(struct wavheader), ofh[i]) != sizeof(struct wavheader)) { + fprintf(stderr, "Failed to write out a full wav header.\n"); + } + fclose(ofh[i]); + } + printf("done cleaning up ... exiting.\n"); + return 0; +} diff --git a/dahdi_pcap.c b/dahdi_pcap.c new file mode 100644 index 0000000..f6fa7fe --- /dev/null +++ b/dahdi_pcap.c @@ -0,0 +1,332 @@ +/* + * Capturing a pcap from the DAHDI interface + * + * Copyright (C) 2011 Torrey Searle + * + * ISDN support added by Horacio Peña + * Command line cleanups by Sverker Abrahamsson + * + * Requirements: + * - pcap development library + * - DAHDI_MIRROR ioctl which isn't enabled by default in dahdi-linux + * To enable this unsupported feature, #define CONFIG_DAHDI_MIRROR + * in dahdi-linux + * - To build this program call the 'make dahdi_pcap' target + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 512 +#define MAX_CHAN 16 +//char ETH_P_LAPD[2] = {0x00, 0x30}; + +struct mtp2_phdr { + u_int8_t sent; + u_int8_t annex_a_used; + u_int16_t link_number; +}; + + +struct lapd_sll_hdr { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; + u_int16_t sll_halen; + u_int8_t sll_addr[8]; + u_int8_t sll_protocol[2]; /* protocol, should be ETH_P_LAPD */ +}; + + +struct chan_fds { + int rfd; + int tfd; + int chan_id; + int proto; + char tx_buf[BLOCK_SIZE * 4]; + int tx_len; + char rx_buf[BLOCK_SIZE * 4]; + int rx_len; +}; + +int make_mirror(long type, int chan) +{ + int res = 0; + int fd = 0; + struct dahdi_bufferinfo bi; + fd = open("/dev/dahdi/pseudo", O_RDONLY); + + memset(&bi, 0, sizeof(bi)); + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 32; + bi.bufsize = BLOCK_SIZE; + + ioctl(fd, DAHDI_SET_BUFINFO, &bi); + + res = ioctl(fd, type, &chan); + + if(res) + { + printf("error setting channel err=%d!\n", res); + return -1; + } + + + return fd; +} + +int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump) +{ + unsigned char buf[BLOCK_SIZE * 4]; + int res = 0; + + struct pcap_pkthdr hdr; + struct mtp2_phdr * mtp2 = (struct mtp2_phdr *)buf; + struct lapd_sll_hdr * lapd = (struct lapd_sll_hdr *)buf; + + unsigned char *dataptr = buf; + int datasize = sizeof(buf); + + if(fd->proto == DLT_LINUX_LAPD) + { + dataptr += sizeof(struct lapd_sll_hdr); + datasize -= sizeof(struct lapd_sll_hdr); + } + else + { + dataptr += sizeof(struct mtp2_phdr); + datasize -= sizeof(struct mtp2_phdr); + } + + memset(buf, 0, sizeof(buf)); + if(is_read) + { + res = read(fd->rfd, dataptr, datasize); + if(fd->rx_len > 0 && res == fd->rx_len && !memcmp(fd->rx_buf, dataptr, res) ) + { + //skipping dup + return 0; + } + + memcpy(fd->rx_buf, dataptr, res); + fd->rx_len = res; + } + else + { + res = read(fd->tfd, dataptr, datasize); + if(fd->tx_len > 0 && res == fd->tx_len && !memcmp(fd->tx_buf, dataptr, res) ) + { + //skipping dup + return 0; + } + + memcpy(fd->tx_buf, dataptr, res); + fd->tx_len = res; + } + + gettimeofday(&hdr.ts, NULL); + + + + + if(res > 0) + { + if(fd->proto == DLT_LINUX_LAPD) + { + hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2; + hdr.len = res+sizeof(struct lapd_sll_hdr)-2; + + lapd->sll_pkttype = 3; + lapd->sll_hatype = 0; + lapd->sll_halen = res; + // lapd->sll_addr = ??? + lapd->sll_protocol[0] = 0x00; + lapd->sll_protocol[1] = 0x30; + + } + else + { + hdr.caplen = res+sizeof(struct mtp2_phdr); + hdr.len = res+sizeof(struct mtp2_phdr); + + if(is_read) + { + mtp2->sent = 0; + mtp2->annex_a_used = 0; + } + else + { + mtp2->sent = 1; + mtp2->annex_a_used = 0; + } + mtp2->link_number = htons(fd->chan_id); + } + pcap_dump((u_char*)dump, &hdr, buf); + pcap_dump_flush(dump); + } + return 1; +} + +void usage() +{ + printf("Usage: dahdi_pcap [OPTIONS]\n"); + printf("Capture packets from DAHDI channels to pcap file\n\n"); + printf("Options:\n"); + printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n"); + printf(" -c, --chan= Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN); + printf(" -f, --file= The pcap file to capture to. Mandatory\n"); + printf(" -h, --help Display this text\n"); +} + +int main(int argc, char **argv) +{ + struct chan_fds chans[MAX_CHAN]; + char *filename = NULL; + int num_chans = 0; + int max_fd = 0; + int proto = DLT_MTP2_WITH_PHDR; + + int i; + int packetcount; + int c; + + while (1) { + int option_index = 0; + static struct option long_options[] = { + {"proto", required_argument, 0, 'p'}, + {"chan", required_argument, 0, 'c'}, + {"file", required_argument, 0, 'f'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "p:c:f:?", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'p': + // Protocol + if(strcasecmp("LAPD", optarg)==0) + { + proto = DLT_LINUX_LAPD; + } + else if(argc > 0 && strcasecmp("MTP2", argv[1])==0) + { + proto = DLT_MTP2_WITH_PHDR; + } + break; + case 'c': + // TODO Should it be possible to override protocol per channel? + // Channels, comma separated list + while(optarg != NULL && num_chans < MAX_CHAN) + { + int chan = atoi(strsep(&optarg, ",")); + + + chans[num_chans].tfd = make_mirror(DAHDI_TXMIRROR, chan); + chans[num_chans].rfd = make_mirror(DAHDI_RXMIRROR, chan); + chans[num_chans].chan_id = chan; + chans[num_chans].proto = proto; + + if(chans[num_chans].tfd > max_fd) + { + max_fd = chans[num_chans].tfd; + } + if(chans[num_chans].rfd > max_fd) + { + max_fd = chans[num_chans].rfd; + } + + num_chans++; + } + max_fd++; + break; + case 'f': + // File to capture to + filename=optarg; + break; + case 'h': + default: + // Usage + usage(); + exit(0); + } + } + if((num_chans == 0) || (filename == NULL)) { + usage(); + exit(0); + } + else + { + printf("Capturing protocol %s on channels ", (proto == DLT_MTP2_WITH_PHDR ? "mtp2":"lapd")); + for(i = 0; i < num_chans; i++) + { + printf("%d", chans[i].chan_id); + if(i + * and Kevin P. Fleming + * Copyright (C) 2007 Digium, Inc. + * + * Based on zttool written by Mark Spencer + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dahdi_tools_version.h" + +static inline int is_digital_span(struct dahdi_spaninfo *s) +{ + return (s->linecompat > 0); +} + +static int get_basechan(unsigned int spanno) +{ + int res; + int basechan; + char filename[256]; + FILE *fp; + + snprintf(filename, sizeof(filename), + "/sys/bus/dahdi_spans/devices/span-%u/basechan", spanno); + fp = fopen(filename, "r"); + if (NULL == fp) { + return -1; + } + res = fscanf(fp, "%d", &basechan); + fclose(fp); + if (EOF == res) { + return -1; + } + return basechan; +} + + +int main(int argc, char *argv[]) +{ + int ctl; + int x, y, z; + struct dahdi_params params; + unsigned int basechan = 1; + int direct_basechan; + struct dahdi_spaninfo s; + char buf[100]; + char alarms[50]; + int filter_count = 0; + int span_filter[DAHDI_MAX_SPANS]; + + if ((ctl = open("/dev/dahdi/ctl", O_RDWR)) < 0) { + fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); + exit(1); + } + + for (x = 1; x < argc && filter_count < DAHDI_MAX_SPANS; x++) { + int s = atoi(argv[x]); + if (s > 0) { + span_filter[filter_count++] = s; + } + } + + for (x = 1; x < DAHDI_MAX_SPANS; x++) { + + memset(&s, 0, sizeof(s)); + s.spanno = x; + if (ioctl(ctl, DAHDI_SPANSTAT, &s)) + continue; + + if (filter_count > 0) { + int match = 0; + for (z = 0; z < filter_count; z++) { + if (x == span_filter[z]) { + match = 1; + break; + } + } + if (!match) { + basechan += s.totalchans; + continue; + } + } + + /* DAHDI-Linux 2.5.x exposes the base channel in sysfs. Let's + * try to look for it there in case there are holes in the span + * numbering. */ + direct_basechan = get_basechan(x); + if (-1 != direct_basechan) { + basechan = direct_basechan; + } + + alarms[0] = '\0'; + if (s.alarms) { + if (s.alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"BLU/"); + if (s.alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "YEL/"); + if (s.alarms & DAHDI_ALARM_RED) { + strcat(alarms, "RED/"); + +/* Extended alarm feature test. Allows compilation with + * versions of dahdi-linux prior to 2.4 + */ +#ifdef DAHDI_ALARM_LFA + if (s.alarms & DAHDI_ALARM_LFA) + strcat(alarms, "LFA/"); +#endif /* ifdef DAHDI_ALARM_LFA */ + } + if (s.alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"LB/"); + if (s.alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"REC/"); + if (s.alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "NOP/"); + if (!strlen(alarms)) + strcat(alarms, "UUU/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else { + if (s.numchans) { +#ifdef DAHDI_ALARM_LFA + /* If we continuously receive framing errors + * but our span is still in service, and we + * are configured for E1 & crc4. We've lost + * crc4-multiframe alignment + */ + if ((s.linecompat & DAHDI_CONFIG_CRC4) && + (s.fecount > 0)) { + struct dahdi_spaninfo t; + memset(&t, 0, sizeof(t)); + t.spanno = x; + sleep(1); + if (ioctl(ctl, DAHDI_SPANSTAT, &t)) + continue; + + /* Test fecount at two separate time + * intervals, if they differ, throw LMFA + */ + if ((t.fecount > s.fecount) && + !t.alarms) { + strcat(alarms, "LMFA/"); + } + } +#endif /* ifdef DAHDI_ALARM_LFA */ + strcat(alarms, "OK"); + } else { + strcpy(alarms, "UNCONFIGURED"); + } + } + + fprintf(stdout, "[%d]\n", x); + fprintf(stdout, "active=yes\n"); + fprintf(stdout, "alarms=%s\n", alarms); + fprintf(stdout, "description=%s\n", s.desc); + fprintf(stdout, "name=%s\n", s.name); + fprintf(stdout, "manufacturer=%s\n", s.manufacturer); + fprintf(stdout, "devicetype=%s\n", s.devicetype); + fprintf(stdout, "location=%s\n", s.location); + fprintf(stdout, "basechan=%d\n", basechan); + fprintf(stdout, "totchans=%d\n", s.totalchans); + fprintf(stdout, "irq=%d\n", s.irq); + y = basechan; + memset(¶ms, 0, sizeof(params)); + params.channo = y; + if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { + basechan += s.totalchans; + continue; + } + + if (is_digital_span(&s)) { + /* this is a digital span */ + fprintf(stdout, "type=digital-%s\n", s.spantype); + fprintf(stdout, "syncsrc=%d\n", s.syncsrc); + fprintf(stdout, "lbo=%s\n", s.lboname); + fprintf(stdout, "coding_opts="); + buf[0] = '\0'; + if (s.linecompat & DAHDI_CONFIG_B8ZS) strcat(buf, "B8ZS,"); + if (s.linecompat & DAHDI_CONFIG_AMI) strcat(buf, "AMI,"); + if (s.linecompat & DAHDI_CONFIG_HDB3) strcat(buf, "HDB3,"); + buf[strlen(buf) - 1] = '\0'; + fprintf(stdout, "%s\n", buf); + fprintf(stdout, "framing_opts="); + buf[0] = '\0'; + if (s.linecompat & DAHDI_CONFIG_ESF) strcat(buf, "ESF,"); + if (s.linecompat & DAHDI_CONFIG_D4) strcat(buf, "D4,"); + if (s.linecompat & DAHDI_CONFIG_CCS) strcat(buf, "CCS,"); + if (s.linecompat & DAHDI_CONFIG_CRC4) strcat(buf, "CRC4,"); + buf[strlen(buf) - 1] = '\0'; + fprintf(stdout, "%s\n", buf); + fprintf(stdout, "coding="); + if (s.lineconfig & DAHDI_CONFIG_B8ZS) fprintf(stdout, "B8ZS"); + else if (s.lineconfig & DAHDI_CONFIG_AMI) fprintf(stdout, "AMI"); + else if (s.lineconfig & DAHDI_CONFIG_HDB3) fprintf(stdout, "HDB3"); + fprintf(stdout, "\n"); + fprintf(stdout, "framing="); + if (s.lineconfig & DAHDI_CONFIG_ESF) fprintf(stdout, "ESF"); + else if (s.lineconfig & DAHDI_CONFIG_D4) fprintf(stdout, "D4"); + else if (s.lineconfig & DAHDI_CONFIG_CCS) fprintf(stdout, "CCS"); + else fprintf(stdout, "CAS"); + if (s.lineconfig & DAHDI_CONFIG_CRC4) fprintf(stdout, "/CRC4"); + fprintf(stdout, "\n"); + } else { + /* this is an analog span */ + fprintf(stdout, "type=analog\n"); + for (y = basechan; y < (basechan + s.totalchans); y++) { + memset(¶ms, 0, sizeof(params)); + params.channo = y; + if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { + fprintf(stdout, "port=%d,unknown\n", y); + continue; + }; + fprintf(stdout, "port=%d,", y); + switch (params.sigcap & (__DAHDI_SIG_FXO | __DAHDI_SIG_FXS)) { + case __DAHDI_SIG_FXO: + fprintf(stdout, "FXS"); + break; + case __DAHDI_SIG_FXS: + fprintf(stdout, "FXO"); + break; + default: + fprintf(stdout, "none"); + } + if (params.sigcap & DAHDI_SIG_BROKEN) + fprintf(stdout, " FAILED"); + fprintf(stdout, "\n"); + } + } + + basechan += s.totalchans; + } + + exit(0); +} diff --git a/dahdi_span_assignments b/dahdi_span_assignments new file mode 100755 index 0000000..bcafe89 --- /dev/null +++ b/dahdi_span_assignments @@ -0,0 +1,333 @@ +#! /bin/sh +# +# /usr/sbin/dahdi_span_assignments: +# +# this script can be used both from udev and +# from the command line to assign/unassign and list +# current span assignments. +# +# It uses a configuration file: $DAHDICONFDIR/assigned-spans.conf +# (default DAHDICONFDIR=/etc/dahdi) +# +# The first argument is an action: +# "auto" - trigger driver auto_assign attribute for given devices +# (no configuration file is used) +# "add" - assign (spans which are not already assigned), according +# to /etc/dahdi/assigned-spans.conf configuration file +# "remove" - unassign spans which are not already unassigned +# "list" - human-readable list of all spans (with/without assignments) +# "dumpconfig" - dump current assignments in a /etc/dahdi/assigned-spans.conf +# compatible format +# +# Without further arguments, it operates on all existing spans +# With one or more sysfs dahdi_devices it is limited to those. +# +# We may use alternative "keys" for device matching: +# * Available keys: +# - "hwid" - Hardware id attribute from sysfs +# - "@location" - Location attribute from sysfs (embeded inside '<>') +# - "/devpath" - The sysfs absolute devpath +# +# * During "dumpconfig", for each device we take the first available key: +# - The preference is: "hwid" or else "@location" or else "/devpath" +# - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable +# or the '{-k|--key} key' command line option. +# +# * During "add": +# - Any key match is valid (hwid/location/devpath) +# - Shell globs (wildcards: '*', '?', '[...]') may be optionally used. +# +# Command line options: +# - The '-h|--help' show a usage message. +# - The '-n|--dry-run' affects the "add" and "remove" operations. +# - The '-v|--verbose' currently shows device matches during "add" operation. +# - The '-k |--key ' overrides the SPAN_ASSIGNMENTS_KEY environment +# variable. +# +# Examples: +# dahdi_span_assignments list +# dahdi_span_assignments add # all unassigned devices +# dahdi_span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# dahdi_span_assignments remove # all assigned devices +# dahdi_span_assignments -k location dumpconfig +# + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +DAHDISASSIGNEDSPANSCONF="${DAHDIASSIGNEDSPANSCONF:-"${DAHDICONFDIR}/assigned-spans.conf"}" +SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid} +dry_run= +verbose= + +usage() { + echo >&2 "Usage: $0 [options] action [devpath ...]" + echo >&2 " action:" + echo >&2 " auto - trigger driver auto_assign attribute for given devices" + echo >&2 " add - assign spans, according to /etc/dahdi/assigned-spans.conf" + echo >&2 " remove - unassign spans" + echo >&2 " list - human-readable list of all spans" + echo >&2 " dumpconfig - dump current state as new configuration" + echo >&2 "" + echo >&2 " options:" + echo >&2 " -h|--help - Show this help" + echo >&2 " -n|--dry-run - For 'add/remove' actions" + echo >&2 " -v|--versbose - Show matches during 'add' action" + echo >&2 " -k|--key - Override prefered key during dumpconfig action" + exit 1 +} + +# Parse command line options +TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key: -n "$0" -- "$@"` +if [ $? != 0 ]; then + echo >&2 "Bad options" + usage +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + case "$1" in + -h|--help) + usage + ;; + -n|--dry-run) + dry_run='true' + shift + ;; + -v|--verbose) + verbose='true' + shift + ;; + -k|--key) + SPAN_ASSIGNMENTS_KEY="$2" + shift + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error!" + exit 1 + ;; + esac +done + +if [ "$#" -eq 0 ]; then + echo >&2 "Missing action argument" + usage +fi +action="$1" +shift + +# Validate SPAN_ASSIGNMENTS_KEY +case "$SPAN_ASSIGNMENTS_KEY" in +hwid|location|devpath) + ;; +*) + echo >&2 "Bad SPAN_ASSIGNMENTS_KEY='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)" + usage + ;; +esac + +if [ ! -d "$devbase" ]; then + echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" + exit 1 +fi + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`ls -d $devbase/* 2>/dev/null` +fi + +# Beware of special characters in attributes +attr_clean() { + cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +show_devices() { + + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + else + spanno='-' + basechan='-' + fi + printf "%-8s %-14s %s %s\n" "$local_spanno:$spanno:$basechan" "[$hardware_id]" "$location" "$devpath" + done | sort -n + done +} + +dump_config() { + echo '#' + echo "# Autogenerated by $0 on `date`" + echo "# Map devices + local spans to span + base channel number" + echo '' + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location=`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then + id="$hardware_id" + elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then + id="@$location" + else + id="$devpath" + fi + echo "# Device: [$hardware_id] @$location $devpath" + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + printf "%-30s %s\n" "$id" "$local_spanno:$spanno:$basechan" + else + echo "# Skipped unassigned local span $local_spanno" + fi + done | sort + echo '' + done +} + +unassign_all_spans() { + for device in $DEVICES + do + find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \ + sort | while read spandir; do + local_spanno=`cat "$spandir/local_spanno"` + if [ "$dry_run" = true ]; then + echo "(dry-run) unassign $device $local_spanno" + continue + fi + echo "unassign $device $local_spanno" + if ! echo "$local_spanno" > "$device/unassign_span"; then + echo >&2 "$0: failed unassigning '$local_spanno' in '$device'" + fi + done + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISASSIGNEDSPANSCONF" +} + +assign_device_spans() { + device="$1" + for s in $spanspecs + do + local_spanno=`echo "$s" | cut -d: -f1` + spanno=`echo "$s" | cut -d: -f2` + span="$device/span-$spanno" + if [ "$dry_run" = true ]; then + echo "(dry-run) assign $device: $s" + continue + fi + if [ -d "$span" ]; then + span_local_spanno=`cat "$span/local_spanno"` + if [ "$span_local_spanno" != "$local_spanno" ]; then + echo "WARNING: $span_local_spanno != $local_spanno" + fi + echo "$device [$local_spanno] already assigned to span $spanno. Skipping..." + continue + fi + echo "assign $device: $s" + if ! echo "$s" > "$device/assign_span"; then + echo >&2 "$0: failed assigning '$s' to '$device'" + fi + done +} + +match_device() { + device="$1" + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + filter_conf | while read id spanspecs + do + # We use case to enable shell-style globbing in configuration + case "$hardware_id" in + $id) + [ "$verbose" = true ] && echo "match by hwid ($id ~ $hardware_id): $spanspecs" + assign_device_spans "$device" + ;; + esac + # We use case to enable shell-style globbing in configuration + case "$location" in + $id) + [ "$verbose" = true ] && echo "match by location ($id ~ $location): $spanspecs" + assign_device_spans "$device" + ;; + esac + # We use case to enable shell-style globbing in configuration + case "$devpath" in + $id) + [ "$verbose" = true ] && echo "match by devpath ($id ~ $devpath): $spanspecs" + assign_device_spans "$device" + ;; + esac + done +} + +assign_devices() { + if [ ! -f "$DAHDISASSIGNEDSPANSCONF" ]; then + echo >&2 "$0: Missing '$DAHDISASSIGNEDSPANSCONF'" + exit 1 + fi + echo "using '$DAHDISASSIGNEDSPANSCONF'" + for device in $DEVICES + do + match_device "$device" + done +} + +auto_assign_devices() { + for device in $DEVICES + do + echo "auto-assign $device" + if [ "$dry_run" != true ]; then + echo 1 > "$device/auto_assign" + fi + done +} + +case "$action" in +auto) + auto_assign_devices + ;; +add) + assign_devices + ;; +remove) + unassign_all_spans + ;; +list) + show_devices + ;; +dumpconfig) + dump_config + ;; +*) + echo >&2 "Bad action='$action'" + usage + ;; +esac diff --git a/dahdi_span_types b/dahdi_span_types new file mode 100755 index 0000000..4154772 --- /dev/null +++ b/dahdi_span_types @@ -0,0 +1,366 @@ +#! /bin/sh +# +# /usr/sbin/dahdi_span_types +# +# This script can be used both from udev and +# from the command line to manage PRI spans +# type (E1/T1/J1). +# +# Span types can be set only *BEFORE* span are assigned. +# +# It uses a configuration file: $DAHDICONFDIR/span-types.conf +# (default DAHDICONFDIR=/etc/dahdi) +# (the format is documented inside that file) +# +# The first argument is an action: +# "set" - actually write the setting to the driver +# "list" - human-readable list of E1/T1/J1 types +# "dumpconfig" - dump current assignments in a /etc/dahdi/span-types.conf +# compatible format +# +# Without further arguments, it operates on all existing spans +# With one or more sysfs dahdi_devices it is limited to those. +# +# We may use alternative "keys" for device matching: +# * Available keys: +# - "hwid" - Hardware id attribute from sysfs +# - "@location" - Location attribute from sysfs (embeded inside '<>') +# - "/devpath" - The sysfs absolute devpath +# +# * Wildcard are allowed in the configuration file: +# - In the device specifiers (keys) +# - In the span numbers +# - Example for "match-all": * *:T1 +# +# * During "set": +# - If there are multiple matches, for a span, all are applied +# - They are always applied in their order in the configuration file +# - This means the last match wins +# - Example: +# * *:T1 # All span on all devices are T1 +# usb:X1234567 [34]:E1 # Except spans 3,4 on specific device +# +# * During "dumpconfig", for each device we take the first available key: +# - The preference is: "hwid" or else "@location" or else "/devpath" +# - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable +# or the '{-k|--key} key' command line option. +# +# Command line options: +# - The '-h|--help' show a usage message. +# - The '-v|--verbose' show debugging messages (on stderr) +# - The '-n|--dry-run' During "set", only show what would be done +# - The '-k |--key ' overrides the SPAN_ASSIGNMENTS_KEY environment +# variable. +# +# Examples: +# dahdi_span_types list +# dahdi_span_types set # all devices +# dahdi_span_types set /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# dahdi_span_types -k location dumpconfig +# + + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +DAHDISPANTYPESCONF="${DAHDISPANTYPESCONF:-"${DAHDICONFDIR}/span-types.conf"}" +SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid} + +usage() { + echo >&2 "Usage: $0 [options] action [devpath ...]" + echo >&2 " action:" + echo >&2 " set - set spans to E1/T1 according to /etc/dahdi/span-types.conf" + echo >&2 " list - human-readable list of all spans" + echo >&2 " dumpconfig - dump current state in /etc/dahdi/span-types.conf format" + echo >&2 "" + echo >&2 " options:" + echo >&2 " -h|--help - Show this help" + echo >&2 " -v|--verbose' - Show debugging messages (on stderr)" + echo >&2 " -n|--dry-run' - During 'set', only show what would be done" + echo >&2 " -k|--key - Override prefered key during dumpconfig action" + echo >&2 " --line-mode - Set default line mode to (E1/T1/J1)" + exit 1 +} + +# Parse command line options +TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key:,line-mode: -n "$0" -- "$@"` +if [ $? != 0 ]; then + echo >&2 "Bad options" + usage +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + case "$1" in + -h|--help) + usage + ;; + -n|--dry-run) + shift + dry_run=true + ;; + -v|--verbose) + shift + verbose=true + ;; + -k|--key) + SPAN_ASSIGNMENTS_KEY="$2" + shift + shift + ;; + --line-mode) + DEFAULT_LINE_MODE="$2" + shift + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error!" + exit 1 + ;; + esac +done + +if [ "$#" -eq 0 ]; then + echo >&2 "Missing action argument" + usage +fi +action="$1" +shift + +# Validate SPAN_ASSIGNMENTS_KEY +case "$SPAN_ASSIGNMENTS_KEY" in +hwid|location|devpath) + ;; +*) + echo >&2 "Bad --key='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)" + usage + ;; +esac + +# Validate DEFAULT_LINE_MODE +case "$DEFAULT_LINE_MODE" in +E1|T1|J1|'') + ;; +*) + echo >&2 "Bad --line-mode='$DEFAULT_LINE_MODE' (should be: E1|T1|J1)" + usage + ;; +esac + +if [ ! -d "$devbase" ]; then + echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" + exit 1 +fi + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`ls -d $devbase/* 2>/dev/null` +fi + +# Beware of special characters in attributes +attr_clean() { + cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +show_spantypes() { + echo "# PRI span types (E1/T1/J1)" + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + cat "$device/spantype" | while read st; do + case "$st" in + *:[ETJ]1) + printf "%-10s %-20s %-30s %s\n" \ + "$st" "[$hardware_id]" "$location" \ + "$devpath" + ;; + esac + done + done +} + +list_pri_spantypes() { + find $DEVICES -follow -maxdepth 1 -name spantype | \ + xargs cat | \ + sed -n '/:[ETJ]1$/s/^.*://p' | \ + sort -u | \ + tr '\n' ' ' | \ + sed -e 's/^ *//' -e 's/ *$//' +} + +dump_config() { + pri_spantypes=`list_pri_spantypes` + num_spantypes=`echo "$pri_spantypes" | wc -w` + gen_default='' + echo '#' + echo "# Autogenerated by $0 on `date`" + echo "# Map PRI DAHDI devices to span types for E1/T1/J1" + echo "#" + + echo "# Summary:" + if [ "$DEFAULT_LINE_MODE" != '' ]; then + gen_default="$DEFAULT_LINE_MODE" + echo "# * Generating wildcard match of $gen_default." + echo "# - Was run with '--line-mode=$DEFAULT_LINE_MODE'" + elif [ "$num_spantypes" -eq 1 ]; then + gen_default="$pri_spantypes" + echo "# * Generating wildcard match of $gen_default." + echo "# - Spans were $pri_spantypes" + else + echo "# * Not generating wildcard match." + echo "# - Was run without '--line-mode' option and span were of mixed types [$pri_spantypes]" + fi + echo "#" + if [ "$num_spantypes" -eq 1 ]; then + echo "# * Generating a list of commented out configurations for spans." + echo "# - Spans were $pri_spantypes" + echo "# - Uncomment for specific overrides" + else + echo "# * Generating a list of specific span configurations." + echo "# - Spans were of mixed types: $pri_spantypes" + fi + echo "#" + echo '' + + fmt="%-65s %s" + printf "$fmt\n" '# @location/hardware_id' 'span_type' + + if [ "$gen_default" != '' ]; then + printf "$fmt\t\t# Wildcard line-mode" "*" "*:$gen_default" + echo "" + fi + echo "" + for device in $DEVICES + do + devpath=`cd "$device" && pwd -P` + location=`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then + id="$hardware_id" + elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then + id="@$location" + else + id="$devpath" + fi + echo "# Device: [$hardware_id] @$location $devpath" + cat "$device/spantype" | while read st; do + case "$st" in + *:[ETJ]1) + if [ "$num_spantypes" -eq 1 ]; then + printf "#$fmt\n" "$id" "$st" + else + printf "$fmt\n" "$id" "$st" + fi + ;; + *) + #echo "# Skipped local span `echo $st | sed 's/:/ -- /'`" + ;; + esac + done | sort -n + echo '' + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISPANTYPESCONF" +} + +handle_span() { + device="$1" + spantype="$2" + attr_file="$device/spantype" + devpath=`cd "$device" && pwd -P` + devname=`echo "$device" | sed "s,$devbase/,,"` + location='@'`attr_clean "$device/location"` + hardware_id=`attr_clean "$device/hardware_id"` + spanno=`echo "$spantype" | cut -d: -f1` + #echo >&2 "DEBUG: $device $spanno ($spantype)" + filter_conf | while read id span_spec; do + sn=`echo "$span_spec" | cut -d: -f1` + val=`echo "$span_spec" | cut -d: -f2` + case "$spanno" in + $sn) + ;; + *) + #echo >&2 "no-match($device $spanno): $sn" + continue + ;; + esac + found=no + # GLOBBING + case "$location" in + $id) + #echo >&2 "match($id): $span_spec" + found=yes + ;; + esac + case "$hardware_id" in + $id) + #echo >&2 "match([$id]): $span_spec" + found=yes + ;; + esac + case "$devpath" in + $id) + #echo >&2 "match([$id]): $span_spec" + found=yes + ;; + esac + if [ "$found" = 'yes' ]; then + if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then + echo >&2 "Set $devname span $spanno = $val" + fi + if [ "$dry_run" != 'true' ]; then + echo "$spanno:$val" > "$attr_file" + fi + fi + done +} + +set_all_devices() { + if [ ! -f "$DAHDISPANTYPESCONF" ]; then + echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'" + exit 1 + fi + for device in $DEVICES + do + devname=`echo "$device" | sed "s,$devbase/,,"` + cat "$device/spantype" | while read spantype; do + case "$spantype" in + *:[ETJ]1) + handle_span "$device" "$spantype" + ;; + *) + if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then + echo >&2 "Skipping non-E1/T1/J1 span ($devname -- $spantype)" + fi + ;; + esac + done + done +} + +case "$action" in +list) + show_spantypes + ;; +dumpconfig) + dump_config + ;; +set) + set_all_devices + ;; +*) + usage + ;; +esac diff --git a/dahdi_speed.c b/dahdi_speed.c new file mode 100644 index 0000000..75bfa86 --- /dev/null +++ b/dahdi_speed.c @@ -0,0 +1,65 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * + * Generic speed test -- Run an infinite loop and + * see how high we can count (in 5 seconds). You + * can use this to measure how much CPU DAHDI REALLY + * is taking. + * + * MUST BE COMPILED WITHOUT OPTIMIZATION + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include + +#include "dahdi_tools_version.h" + +static long count=0; + +static void alm(int sig) +{ + printf("Count: %ld\n", count); + exit(0); +} + + +int main(int argc, char *argv[]) +{ + int a=0,b=0,c; + signal(SIGALRM, alm); + alarm(5); + for (;;) { + for (c=0;c<1000;c++) + a = a * b; + count++; + } +} diff --git a/dahdi_test.c b/dahdi_test.c new file mode 100644 index 0000000..d07a1f6 --- /dev/null +++ b/dahdi_test.c @@ -0,0 +1,177 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dahdi_tools_version.h" + +#define SIZE 8000 + +static int verbose; +static int pass = 0; +static float best = 0.0; +static float worst = 100.0; +static double total = 0.0; +static double total_time = 0.0; +static double total_count = 0.0; + +static inline float _fmin(float a, float b) +{ + return (a < b) ? a : b; +} + +static double calculate_accuracy(double count, double ms) +{ + return ((count - _fmin(count, fabs(count - ms))) / count) * 100.0; +} + +void hup_handler(int sig) +{ + double accuracy = calculate_accuracy(total_count, total_time); + printf("\n--- Results after %d passes ---\n", pass); + printf("Best: %.3f%% -- Worst: %.3f%% -- Average: %f%%\n", + best, worst, pass ? total/pass : 100.00); + printf("Cummulative Accuracy (not per pass): %0.3f\n", + pass ? accuracy : 0.0); + exit(0); +} + +static void usage(char *argv0) +{ + char *c; + c = strrchr(argv0, '/'); + if (!c) + c = argv0; + else + c++; + fprintf(stderr, + "Usage: %s [-c COUNT] [-v]\n" + " Valid options are:\n" + " -c COUNT Run just COUNT cycles (otherwise: forever).\n" + " -v More verbose output.\n" + " -h This help text.\n" + , c); +} + +int main(int argc, char *argv[]) +{ + int fd; + int res; + int c; + int count = 0; + int seconds = 0; + int curarg = 1; + char buf[8192]; + float ms; + struct timeval start, now; + fd = open("/dev/dahdi/pseudo", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open dahdi interface: %s\n", strerror(errno)); + exit(1); + } + + while ((c = getopt(argc, argv, "c:hv")) != -1) { + switch(c) { + case 'c': + seconds = atoi(optarg); + break; + case 'h': + usage(argv[0]); + exit(0); + break; + case '?': + usage(argv[0]); + exit(1); + break; + case 'v': + verbose++; + break; + } + } + while (curarg < argc) { + if (!strcasecmp(argv[curarg], "-v")) + verbose++; + if (!strcasecmp(argv[curarg], "-c") && argc > curarg) + seconds = atoi(argv[curarg + 1]); + curarg++; + } + printf("Opened pseudo dahdi interface, measuring accuracy...\n"); + signal(SIGHUP, hup_handler); + signal(SIGINT, hup_handler); + signal(SIGALRM, hup_handler); + /* Flush input buffer */ + for (count = 0; count < 4; count++) + res = read(fd, buf, sizeof(buf)); + count = 0; + ms = 0; /* Makes the compiler happy */ + if (seconds > 0) + alarm(seconds + 1); /* This will give 'seconds' cycles */ + for (;;) { + if (count == 0) + ms = 0; + gettimeofday(&start, NULL); + res = read(fd, buf, sizeof(buf)); + if (res < 0) { + fprintf(stderr, "Failed to read from pseudo interface: %s\n", strerror(errno)); + exit(1); + } + count += res; + gettimeofday(&now, NULL); + ms += (now.tv_sec - start.tv_sec) * 8000; + ms += (now.tv_usec - start.tv_usec) / 125.0; + if (count >= SIZE) { + const double percent = calculate_accuracy(count, ms); + if (verbose) { + printf("\n%d samples in %0.3f system clock sample intervals (%.3f%%)", + count, ms, percent); + } else if (pass > 0 && (pass % 8) == 0) { + printf("\n"); + } + if (percent > best) + best = percent; + if (percent < worst) + worst = percent; + if (!verbose) + printf("%.3f%% ", percent); + total += percent; + fflush(stdout); + total_count += count; + total_time += ms; + count = 0; + pass++; + } + } +} diff --git a/dahdi_tool.c b/dahdi_tool.c new file mode 100644 index 0000000..a814931 --- /dev/null +++ b/dahdi_tool.c @@ -0,0 +1,541 @@ +/* + * Configuration program for Zapata Telephony Interface + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2010 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/*** MODULEINFO + newt + ***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +static int ctl = -1; +static int span_max_chan_pos; + +static struct dahdi_spaninfo s[DAHDI_MAX_SPANS]; + +static char *dahdi_txlevelnames[] = { +"0 db (CSU)/0-133 feet (DSX-1)", +"133-266 feet (DSX-1)", +"266-399 feet (DSX-1)", +"399-533 feet (DSX-1)", +"533-655 feet (DSX-1)", +"-7.5db (CSU)", +"-15db (CSU)", +"-22.5db (CSU)" +} ; + +static char *alarmstr(int span) +{ + static char alarms[80]; + strcpy(alarms, ""); + if (s[span].alarms > 0) { + if (s[span].alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"Blue Alarm/"); + if (s[span].alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "Yellow Alarm/"); + if (s[span].alarms & DAHDI_ALARM_RED) + strcat(alarms, "Red Alarm/"); + if (s[span].alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"Loopback/"); + if (s[span].alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"Recovering/"); + if (s[span].alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "Not Open/"); + if (!strlen(alarms)) + strcat(alarms, "/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else + strcpy(alarms, "No alarms."); + return alarms; +} + +static char *getalarms(int span, int err) +{ + int res; + static char tmp[256]; + char alarms[50]; + s[span].spanno = span; + res = ioctl(ctl, DAHDI_SPANSTAT, &s[span]); + if (res) { + if (err) + fprintf(stderr, "Unable to get span info on span %d: %s\n", span, strerror(errno)); + return NULL; + } + strcpy(alarms, ""); + if (s[span].alarms > 0) { + if (s[span].alarms & DAHDI_ALARM_BLUE) + strcat(alarms,"BLU/"); + if (s[span].alarms & DAHDI_ALARM_YELLOW) + strcat(alarms, "YEL/"); + if (s[span].alarms & DAHDI_ALARM_RED) + strcat(alarms, "RED/"); + if (s[span].alarms & DAHDI_ALARM_LOOPBACK) + strcat(alarms,"LB/"); + if (s[span].alarms & DAHDI_ALARM_RECOVER) + strcat(alarms,"REC/"); + if (s[span].alarms & DAHDI_ALARM_NOTOPEN) + strcat(alarms, "NOP/"); + if (!strlen(alarms)) + strcat(alarms, "UUU/"); + if (strlen(alarms)) { + /* Strip trailing / */ + alarms[strlen(alarms)-1]='\0'; + } + } else { + if (s[span].numchans) + strcpy(alarms, "OK"); + else + strcpy(alarms, "UNCONFIGURED"); + } + + snprintf(tmp, sizeof(tmp), "%-15s %s", alarms, s[span].desc); + return tmp; +} + +static void add_cards(newtComponent spans) +{ + int x; + char *s; + void *prev=NULL; + + if (spans) + prev = newtListboxGetCurrent(spans); + newtListboxClear(spans); + for (x=0;x -1)) { + if (zp.rxbits & DAHDI_ABIT) + rabits[zp.chanpos - 1] = '1'; + else + rabits[zp.chanpos - 1] = '0'; + if (zp.rxbits & DAHDI_BBIT) + rbbits[zp.chanpos - 1] = '1'; + else + rbbits[zp.chanpos - 1] = '0'; + + if (zp.rxbits & DAHDI_CBIT) + rcbits[zp.chanpos - 1] = '1'; + else + rcbits[zp.chanpos - 1] = '0'; + if (zp.rxbits & DAHDI_DBIT) + rdbits[zp.chanpos - 1] = '1'; + else + rdbits[zp.chanpos - 1] = '0'; + + if (zp.txbits & DAHDI_ABIT) + tabits[zp.chanpos - 1] = '1'; + else + tabits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_BBIT) + tbbits[zp.chanpos - 1] = '1'; + else + tbbits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_CBIT) + tcbits[zp.chanpos - 1] = '1'; + else + tcbits[zp.chanpos - 1] = '0'; + if (zp.txbits & DAHDI_DBIT) + tdbits[zp.chanpos - 1] = '1'; + else + tdbits[zp.chanpos - 1] = '0'; + } else { + c = '-'; + if (!zp.sigtype) + c = ' '; + tabits[zp.chanpos - 1] = c; + tbbits[zp.chanpos - 1] = c; + tcbits[zp.chanpos - 1] = c; + tdbits[zp.chanpos - 1] = c; + rabits[zp.chanpos - 1] = c; + rbbits[zp.chanpos - 1] = c; + rcbits[zp.chanpos - 1] = c; + rdbits[zp.chanpos - 1] = c; + } + if (zp.rxisoffhook) + use++; + } + } + } + snprintf(tmp, sizeof(tmp), "%s\n%s\n%s\n%s\n\n%s\n%s\n%s\n%s", tabits, tbbits,tcbits,tdbits,rabits,rbbits,rcbits,rdbits); + newtTextboxSetText(bitbox, tmp); + sprintf(tmp, "%3d/%3d/%3d", s[span].totalchans, s[span].numchans, use); + newtTextboxSetText(inuse, tmp); + sprintf(tmp, "%s/", dahdi_txlevelnames[s[span].txlevel]); + strcat(tmp, dahdi_txlevelnames[s[span].rxlevel]); + sprintf(tmp, "%3d/%3d", s[span].txlevel, s[span].rxlevel); + newtTextboxSetText(levels, tmp); + sprintf(tmp, "%7d", s[span].bpvcount); + newtTextboxSetText(bpvcount, tmp); + sprintf(tmp, "%7d", s[span].irqmisses); + newtTextboxSetText(irqmisses, tmp); + newtTextboxSetText(alarms, alarmstr(span)); + if (s[span].syncsrc > 0) + strcpy(tmp, s[s[span].syncsrc].desc); + else + strcpy(tmp, "Internally clocked"); + newtTextboxSetText(syncsrc, tmp); + + +} + +static newtComponent spans; +static void show_span(int span) +{ + newtComponent form; + newtComponent back; + newtComponent label; + newtComponent bitbox; + newtComponent inuse; + newtComponent levels; + newtComponent bpvcount; + newtComponent alarms; + newtComponent syncsrc; + newtComponent irqmisses; + + char s1[] = " 1111111111222222222233"; + char s2[] = "1234567890123456789012345678901"; + int x; + struct newtExitStruct es; + + void *ss; + char info2[256]; + + if (span < 0) { + /* Display info on a span */ + ss = newtListboxGetCurrent(spans); + if (ss) { + span = (long)(ss); + } + } + + snprintf(info2, sizeof(info2), "%-59s F10=Back", s[span].desc); + newtCenteredWindow(60,20, s[span].desc); + newtPushHelpLine(info2); + + back = newtButton(48,8,"Back"); + form = newtForm(NULL, NULL, 0); + + newtFormAddComponents(form, back, NULL); + + span_max_chan_pos = s[span].totalchans; + for (x=0;x span_max_chan_pos ) + span_max_chan_pos = zp.chanpos; + } + + if (span_max_chan_pos > 32) + span_max_chan_pos = 32; + + s1[span_max_chan_pos] = '\0'; + s2[span_max_chan_pos] = '\0'; + + bitbox = newtTextbox(8,10,span_max_chan_pos,9,0); + newtFormAddComponent(form, bitbox); + + label = newtLabel(8,8,s1); + newtFormAddComponent(form, label); + + label = newtLabel(8,9,s2); + newtFormAddComponent(form, label); + + newtFormAddHotKey(form, NEWT_KEY_F10); + newtFormSetTimer(form, 200); + + label = newtLabel(4,10,"TxA"); + newtFormAddComponent(form, label); + + label = newtLabel(4,11,"TxB"); + newtFormAddComponent(form, label); + + label = newtLabel(4,12,"TxC"); + newtFormAddComponent(form, label); + + label = newtLabel(4,13,"TxD"); + newtFormAddComponent(form, label); + + label = newtLabel(4,15,"RxA"); + newtFormAddComponent(form, label); + + label = newtLabel(4,16,"RxB"); + newtFormAddComponent(form, label); + + label = newtLabel(4,17,"RxC"); + newtFormAddComponent(form, label); + + label = newtLabel(4,18,"RxD"); + newtFormAddComponent(form, label); + + + label = newtLabel(4,7,"Total/Conf/Act: "); + newtFormAddComponent(form, label); + + inuse = newtTextbox(24,7,12,1,0); + newtFormAddComponent(form, inuse); + + label = newtLabel(4,6,"Tx/Rx Levels: "); + newtFormAddComponent(form, label); + + levels = newtTextbox(24,6,30,1,0); + newtFormAddComponent(form, levels); + + label = newtLabel(4,5,"Bipolar Viol: "); + newtFormAddComponent(form, label); + + bpvcount = newtTextbox(24,5,30,1,0); + newtFormAddComponent(form, bpvcount); + + label = newtLabel(4,4,"IRQ Misses: "); + newtFormAddComponent(form, label); + + irqmisses = newtTextbox(24,4,30,1,0); + newtFormAddComponent(form, irqmisses); + + label = newtLabel(4,3,"Sync Source: "); + newtFormAddComponent(form, label); + + syncsrc = newtTextbox(24,3,30,1,0); + newtFormAddComponent(form, syncsrc); + + label = newtLabel(4,2,"Current Alarms: "); + newtFormAddComponent(form, label); + + alarms = newtTextbox(24,2,30,1,0); + newtFormAddComponent(form, alarms); + + for(;;) { + /* Wait for user to select something */ + do { + add_cards(NULL); + show_bits(span, bitbox, inuse, levels, bpvcount, alarms, syncsrc, irqmisses); + newtFormRun(form, &es); + } while(es.reason == NEWT_EXIT_TIMER); + switch(es.reason) { + case NEWT_EXIT_COMPONENT: + if (es.u.co == back) { + goto out; + } + break; + case NEWT_EXIT_HOTKEY: + switch(es.u.key) { +#if 0 + case NEWT_KEY_F1: + show_span(-1); + break; +#endif + case NEWT_KEY_F10: + goto out; + } + break; + default: + break; + } + } + +out: + newtFormDestroy(form); + newtPopWindow(); + newtPopHelpLine(); + span_max_chan_pos = 0; +} + +static void show_spans(void) +{ + newtComponent form; + newtComponent quit; + newtComponent label; + newtComponent sel; + + + struct newtExitStruct es; + + + quit = newtButton(50,14,"Quit"); + sel = newtButton(10,14,"Select"); + + spans = newtListbox(5, 2, 10, NEWT_FLAG_SCROLL); + newtListboxSetWidth(spans, 65); + + label = newtLabel(5,1,"Alarms Span"); + + newtCenteredWindow(72,18, "DAHDI Telephony Interfaces"); + form = newtForm(NULL, NULL, 0); + + newtFormSetTimer(form, 200); + + newtFormAddComponents(form, spans, sel, quit, label, NULL); + + newtComponentAddCallback(spans, sel_callback, NULL); + + newtFormAddHotKey(form, NEWT_KEY_F1); + newtFormAddHotKey(form, NEWT_KEY_F10); + + for(;;) { + /* Wait for user to select something */ + do { + add_cards(spans); + newtFormRun(form, &es); + } while(es.reason == NEWT_EXIT_TIMER); + + switch(es.reason) { + case NEWT_EXIT_COMPONENT: + if (es.u.co == quit) { + /* Quit if appropriate */ + newtFormDestroy(form); + return; + } else if (es.u.co == sel) { + show_span(-1); + } + break; + case NEWT_EXIT_HOTKEY: + switch(es.u.key) { + case NEWT_KEY_F1: + show_span(-1); + break; + case NEWT_KEY_F10: + newtFormDestroy(form); + return; + } + break; + default: + break; + } + } +} + +static void cleanup(void) +{ + newtPopWindow(); +} + +int main(int argc, char *argv[]) +{ + + ctl = open("/dev/dahdi/ctl", O_RDWR); + if (ctl < 0) { + fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); + exit(1); + } + newtInit(); + newtCls(); + + newtDrawRootText(0,0,"DAHDI Tool (C)2002-2008 Digium, Inc."); + newtPushHelpLine("Welcome to the DAHDI Tool!"); + show_spans(); + cleanup(); + newtFinished(); + return 0; +} diff --git a/dahdi_tools_version.h b/dahdi_tools_version.h new file mode 100644 index 0000000..b4ec5fb --- /dev/null +++ b/dahdi_tools_version.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +extern const char dahdi_tools_version[]; diff --git a/dahdi_waitfor_span_assignments b/dahdi_waitfor_span_assignments new file mode 100755 index 0000000..1080d84 --- /dev/null +++ b/dahdi_waitfor_span_assignments @@ -0,0 +1,73 @@ +#! /bin/sh + +usage() { + echo >&2 "Usage: $0 {assigned|unassigned}" + echo >&2 "# wait until all spans known are assigned/unassigned" + exit 1 +} + +TIMEOUT=5 # How much time to wait for spans + +if [ "$#" -lt 1 ]; then + usage +fi +wanted_event="$1" +shift + +case "$wanted_event" in +assigned) + ;; +unassigned) + ;; +*) + usage + ;; +esac + +devbase='/sys/bus/dahdi_devices/devices' + +spans_of() { + dev="$1" + wc -l < "$dev/spantype" +} + +assigned_spans_of() { + dev="$1" + ls -d "$dev/span-"* 2>/dev/null | wc -l +} + + +waitfor_span_assignments() { + wanted_state="$1" + device_list=`ls -d "$devbase/"* 2> /dev/null` + finished='' + count="$TIMEOUT" + echo -n "Waiting for spans to become $wanted_state: " + while [ "$count" -gt 0 ]; do + finished='yes' + for dev in $device_list + do + spans=`spans_of "$dev"` + assigned_spans=`assigned_spans_of "$dev"` + if [ "$wanted_state" = 'assigned' -a "$assigned_spans" -ne "$spans" ]; then + finished='no' + elif [ "$wanted_state" = 'unassigned' -a "$assigned_spans" -ne 0 ]; then + finished='no' + fi + done + if [ "$finished" = 'yes' ]; then + break + else + sleep 1 + echo -n "." + fi + count=`expr "$count" - 1` + done + if [ "$finished" = 'yes' ]; then + echo "done" + else + echo "timeout" + fi +} + +waitfor_span_assignments "$wanted_event" diff --git a/doc/dahdi_cfg.8 b/doc/dahdi_cfg.8 new file mode 100644 index 0000000..86d96d6 --- /dev/null +++ b/doc/dahdi_cfg.8 @@ -0,0 +1,86 @@ +.TH "DAHDI_CFG" "8" "16 Jun 2008" "" "" + +.SH NAME +dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf +.SH SYNOPSIS + +.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-S\fINUM\fB [\-S\fICHANS\fB]] [\-s] [\-f] [\-t] [\-v [\-v ... ] ] + +.B dahdi_cfg \-h + +.SH DESCRIPTION +.B dahdi_cfg +configures DAHDI interface cards from a config file. + +You generally need to run it with a valid configurations +in order for DAHDI modules to work properly. + +It must be run to configure every DAHDI span. Normally it is run from +the DAHDI init script. + +.SH OPTIONS + +.B \-c \fICFG_FILE +.RS +Use an alternative configuration file instead of +.I /etc/dahdi/system.conf + +If \fICFG_FILE\fR is '\fB\-\fR', it is read from stdin. +.RE + +.B \-C \fICHANNELS +.RS +Only apply changes to channels in the specified range. Only +applicable when \-S is in use. +.RE + +.B \-s +.RS +Only shutdown spans. +.RE + +.B \-S \fISPAN +.RS +Only apply changes to span no. \fISPAN\fR. For a digital span (with +a 'span=' line in the configuration file) this will do. For an analog +span you'll have to explicitly tell dahdi_cfg the range of channels, +using \-C . +.RE + +.B \-f +.RS +Always configure every channel, even if it appears not to have changed. +.RE + +.B \-t +.RS +Test mode. Don't do anything, just report what you wanted to do. +.RE + +.B \-v +.RS +Be more verbose. Add extra v-s for extra verbosity. +.RE + +.B \-h +.RS +Display a brief help message. +.RE + +.SH FILES + +.I /etc/dahdi/system.conf +.RS +The default location for the configuration file. +.RE + +.SH SEE ALSO +dahdi_tool(8), dahdi_monitor(8), asterisk(8). + +.SH AUTHOR +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_diag.8 b/doc/dahdi_diag.8 new file mode 100644 index 0000000..0f01a09 --- /dev/null +++ b/doc/dahdi_diag.8 @@ -0,0 +1,52 @@ +.TH dahdi_diag 8 "2008-01-07" +.SH NAME +dahdi_diag \(em Dump DAHDI channel parameters +.SH SYNOPSIS +.B dahdi_diag +.I channel + +.SH DESCRIPTION +.B dahdi_diag +asks the kernel to dump parameters for DAHDI channel no. +.I channel +to the kernel logs. You will be able to see them using, e.g. dmesg(1). + + +.SH OPTIONS +.I channel +.RS +The number of the DAHDI channel whose parammeters should be dumped. +May be any DAHDI channel (even if it is open). +.RE + +.SH EXAMPLE + + # /tmp/dahdi_diag 5 + # dmesg | tail \-n 15 + Dump of DAHDI Channel 5 (XPP_BRI_TE/00/01/1,5,2): + + flags: 501 hex, writechunk: c5190948, readchunk: c5190954 + rxgain: ccad2e80, txgain: ccad2e80, gainalloc: 0 + span: c48a900c, sig: 80 hex, sigcap: 80 hex + inreadbuf: \-1, outreadbuf: 0, inwritebuf: 0, outwritebuf: \-1 + blocksize: 160, numbufs: 4, txbufpolicy: 0, txbufpolicy: 0 + txdisable: 0, rxdisable: 0, iomask: 0 + curzone: c78e7000, tonezone: 0, curtone: 00000000, tonep: 0 + digitmode: 0, txdialbuf: , dialing: 0, aftdialtimer: 0, cadpos. 0 + confna: 0, confn: 0, confmode: 0, confmute: 0 + ec: 00000000, echocancel: 0, deflaw: 0, xlaw: ccab5e80 + echostate: 00, echotimer: 0, echolastupdate: 0 + itimer: 0, otimer: 0, ringdebtimer: 0 + +.SH SEE ALSO +dahdi_cfg(8), asterisk(8), dmesg(1). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/dahdi_maint.8 b/doc/dahdi_maint.8 new file mode 100644 index 0000000..98aad3d --- /dev/null +++ b/doc/dahdi_maint.8 @@ -0,0 +1,62 @@ +.TH "DAHDI_MAINT" "8" "9 Sep 2011" "" "" + +.SH NAME +dahdi_maint \- Sets Dahdi spans into maintenance mode, e.g.: loopback +.SH SYNOPSIS + +.B dahdi_maint \-s \fInum\fB [options] +.B dahdi_maint <\-h|\-\-help> + +.SH DESCRIPTION + +dahdi_maint uses the DAHDI_MAINT interface to set a Dahdi span (port +of a Dahdi adapter card) into loopback mode or similar maintenance mode. + +.SH OPTIONS +.B \-s \-\-span \fInum\fR +.RS +The span number. Required. +.RE + +.B \-l \-\-loopback +.RS +Loopback type. One of: +.IP localhost 4 +loop back towards host +.IP networkline 4 +network line loopback +.IP networkpayload 4 +network payload loopback +.IP loopup 4 +transmit loopup signal +.IP loopdown 4 +transmit loopdown signal +.IP off 4 +end loopback mode +.RE + +.B \-i \-\-insert +.RS +Insert an error of a specific type +.RE + +.SH EXAMPLES +Enable network line loopback on span 1: + + dahdi_maint \-s 1 \-\-loopback networkline + +Disable network line loopback on span 1: + + dahdi_maint \-s 1 \-\-loopback off + + +.SH SEE ALSO +.PP +dahdi_tool(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR +.PP +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 2 any later +version published by the Free Software Foundation. diff --git a/doc/dahdi_monitor.8 b/doc/dahdi_monitor.8 new file mode 100644 index 0000000..a0a2f42 --- /dev/null +++ b/doc/dahdi_monitor.8 @@ -0,0 +1,145 @@ +.TH "DAHDI_MONITOR" "8" "9 Sep 2011" "" "" + +.SH NAME +dahdi_monitor \- checks the Rx/Tx levels of a DAHDI channels +.SH SYNOPSIS + +.B dahdi_monitor \fInum\fB [\-v[v]] +.B dahdi_monitor \fInum\fB [\-o] [<\-f|\-F> \fIFILE\fB] +.B dahdi_monitor \fInum\fB [[<\-r|\-R> \fIFILE\fB]] [[<\-t|\-T> \fIFILE\fB]] + +.SH DESCRIPTION + +dahdi_monitor monitors a Dahdi channel. It can record the output to a +file, play it to the speaker, or visualize the audio levels on the +terminal. + +Recorded audio files are by default raw signed linear PCM. If the file +name ends with ".wav", the recorded file will be a WAV file. + +The visual display shows the current audio level at both the Rx +(audio Received by Asterisk) and +Tx (audio Transmitted by Asterisk) + +To exit the program, press Ctrl-C. + +.SH OPTIONS +The first (mandatory) parameter is the number of the channel +to monitor. + +.B \-m +.RS +Multiple channels. Don't multiplex both Rx and Tx in a single channel. +Normally there's a different option that you need that implies it. +.RE + +.B \-o +.RS +Plays the output to OSS (/dev/dsp). Requires \-m not to be used. +.RE + +.B \-v +.RS +Display Visual audio levels. With two v-s, Verbose mode is enabled, that +shows the actual levels as numbers. Note that this requires a terminal +wider than 80 columns to be properly displayed. + +Implies \-m. +.RE + +.B \-f \fIFILE +.RS +Record the content of the channel (Tx + Rx) to a file. +.RE + +.B \-F \fIFILE +.RS +Record the content of the channel (Tx + Rx) before the echo canceler +to a file. +.RE + +.B \-r \fIFILE +.RS +Record the content of the Rx channel to a file. + +Implies \-m. +.RE + +.B \-R \fIFILE +.RS +Record the content of the R channel before the echo canceler to a file. + +Implies \-m. +.RE + +.B \-s \fIFILE +.RS +Record the content of the Tx and Rx of the channel to a file. +.RE + +.B \-S \fIFILE +.RS +Records a stereo of both Tx and Rx of the channel before the echo +canceler to a file. +.RE + +.B \-t \fIFILE +.RS +Record the content of the Tx channel to a file. + +Implies \-m. +.RE + +.B \-T \fIFILE +.RS +Record the content of the Tx channel before the echo canceler to a file. + +Implies \-m. +.RE + +.SH EXAMPLES + +Visualize audio levels on DAHDI channel 2: + + dahdi_monitor 2 \-v + + +Record channel 3 to a file: + + dahdi_monitor 3 \-f output.raw + +This will create a raw PCM file (signed-linear, 8kHz, mono, 16 bits per +sample). Both the Tx and Rx will be multiplexed in a single channel. +It can be converted to a WAV file using e.g.: + + sox \-s \-c1 \-2 \-r8000 output.raw output.wav + + +Record Tx and Rx of channel 5 to separate files. This time directly to +WAV files: + + dahdi_monitor 5 \-r output_rx.wav \-t output_tx.wav + + +Record channel 8 to a stereo file (Tx and Rx on its two channels): + + dahdi_monitor 8 \-s output.raw + +Converting it to a WAV file: + + sox \-s \-c2 \-2 \-r8000 output.raw output.wav + + + +.SH SEE ALSO +.PP +dahdi_tool(8), dahdi_cfg(8). + +.SH AUTHOR +.PP +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_scan.8 b/doc/dahdi_scan.8 new file mode 100644 index 0000000..d7a9e16 --- /dev/null +++ b/doc/dahdi_scan.8 @@ -0,0 +1,101 @@ +.TH dahdi_scan 8 "2008-03-18" +.SH NAME +dahdi_scan \(em Print Configuration of DAHDI Spans +.SH SYNOPSIS +.B dahdi_scan +.I [spans] + +.SH DESCRIPTION +.B dahdi_scan +prints information about DAHDI spans in the system. For analog spans it +also provides a list of channels. + +By default it prints information about all the spans in the system. +However if parameters are provided, they will be considered to be a list +of span numbers and information will be printed for them. + +Output is printed to the standard output. The format is that of an +Asterisk configuration file (similar to a "ini" configuration file), +where the name of the section is the number of the span. Note that the +specifically for analog spans some keys may appear more than once, and +hence you can not use a parser for an "ini" format and assume you have a +dictionary. + +.SH EXAMPLES +Printing information for spans 1, 2 and 4: + + dahdi_scan 1 2 4 + +And to print all the spans: + + dahdi_scan + +Information about a certain analog span: + + [5] + active=yes + alarms=OK + description=Xorcom XPD #00/10: FXS + name=XBUS\-00/XPD\-10 + manufacturer=Xorcom Inc. + devicetype=Astribank: Unit 1 Subunit 0: FXS + location=usb\-0000:00:03.3\-4 + basechan=125 + totchans=8 + irq=0 + type=analog + port=125,FXS + port=126,FXS + port=127,FXS + port=128,FXS + port=129,FXS + port=130,FXS + port=131,FXS + port=132,FXS + +And an example of a digital span: + + [1] + active=yes + alarms=RED + description=T2XXP (PCI) Card 0 Span 1 + name=TE2/0/1 + manufacturer=Digium + devicetype=Wildcard TE205P (4th Gen) + location=Board ID Switch 0 + basechan=1 + totchans=24 + irq=193 + type=digital\-T1 + syncsrc=0 + lbo=0 db (CSU)/0\-133 feet (DSX\-1) + coding_opts=B8ZS,AMI + framing_opts=ESF,D4 + coding=B8ZS + framing=ESF + +The "type" field may contain: "analog", "digital\-T1", "digital\-E1", +"digital\-J1" or "digital\-BRI". + +.SH FILES +Requires read access to /dev/dahdi/ctl . + +.SH SEE ALSO +dahdi_cfg(8), asterisk(8). + +.SH BUGS +The program still does not do everything described in the man page. + +It also assumes that spans don't skip channel numbers, and that their +channel numbers are "running". This is anyway almost always the case. +And always the case in a normal boot process. + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/dahdi_span_assignments.8 b/doc/dahdi_span_assignments.8 new file mode 100644 index 0000000..52e0391 --- /dev/null +++ b/doc/dahdi_span_assignments.8 @@ -0,0 +1,251 @@ +.TH "DAHDI_SPAN_ASSIGNMENTS" "8" "23 Jan 2014" "" "" + +.SH NAME +dahdi_span_assignments \- handle DAHDI spans assignments +.SH SYNOPSIS + +.B dahdi_span_assignments [\-v|\-\-verbose] [\-n|\-\-dry\-run] \fB[\fIdevpath\fB...] + +.B dahdi_span_assignments [\-v|\-\-verbose] list \fB[\fIdevpath\fB...] + +.B dahdi_span_assignments [\-v|\-\-verbose] [\-k|\-\-key \fIkey\fB] dumpconfig + +.B dahdi_span_assignments \-h|\-\-help + +.SH DESCRIPTION +Channels in DAHDI devices (such as DAHDI PCI cards) are groups to logical +units called "spans" (for example: a port in a digital card is a span). +When the kernel module parameter \fBdahdi.auto_assign_span\fR is unset, +DAHDI devices that register with DAHDI don't cause their spans to be +automatically assigned. + +This allows user-space to order DAHDI to assign them to specific span +and channel numbers. That way, specific spans on specific DAHDI devices +may be assigned with specific span and channel numbers \fBregardless\fR +of the registration order of the hardware (or if all hardware is present +at all). + +.B dahdi_span_assignments +is used to assign those spans or to help creating the configuration +file used in their assignment: +.B /etc/dahdi/assigned\-spans.conf . + +.SH SUB-COMMANDS + +There are several sub-commands. + +All sub-commands take an optional list of paths to SysFS nodes of +devices. If given, the command will only operate on those DAHDI +devices. The default is to operate on all devices (which would normally +be the sane case when running from the command-line). + +.B add \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with unassigned +spans. + +The command will assign spans with DAHDI according to +configuration in \fBassigned\-spans.conf\fR. + +If no line matches the span, or if the assignment for it fails (it is +not available) it will remain unassigned. + +If any of the span settings fails (the span number or range of channels +is already in use), the program will print a message, but continue +applying the others. In such a case you should fix assigned\-spans.conf +and re-run \fBadd\fR (or run \fBauto\fR to give those channels the +first available range and regenerate the file with 'dahdi_genconf +assignedspans'). +.RE + +.B remove \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with assigned +spans. + +The command will un-assign them. +.RE + +.B auto \fB[\fIdevpath \fB...] +.RS +Applies to all devices or to those listed on the command line. +Parameters are paths (in SysFS) to DAHDI devices with unassigned +spans. + +Each span is assigned to first available span number and channel +numbers, as if \fBdahdi.auto_assign_span\fR was set. The configuration +file doesn't affect these assignments. +.RE + +.B list +.RS +List all spans in the system. +.RE + +.B dumpconfig +.RS +List all assigned spans in the system in a format fit to be used in +\fBassigned\-spans.conf\fR. Use this to generate a configuration file after +you have (automatically or manually) assigned all existing spans. + +.B dahdi_genconf assignedspans +uses this command internally. +.RE + +.SH OPTIONS + +.B \-v \-\-verbose +.RS +Verbose output. +.RE + +.B \-n \-\-dry\-run +.RS +Don't assign / un-assign spans. Only print commands used to do so. +.RE + +.B \-k \fIkey +.RS +For \fBdumpconfig\fR \- The key by which to identify the hardware in the +generated configuration. Legal values: + +.B hwid +.RS +Hardware identifier (e.g.: software-readable serial number). This is the +default. If the device has no hwid, devpath is used. +.RE + +.B location +.RS +The location field (file) in the SysFS device node (directory) for the +DAHDI device. If not available (typically: DAHDI version <= 2.7.x), +devpath is used. +.RE + +.B devpath +.RS +Path in SysFS to the device node. +.RE +.RE + +.SH CONFIGURATION +.B /etc/dahdi/assigned\-spans.conf +is a file with lines specifying assignment of spans. + +Empty lines or lines beginning with '#' are ignored. + +Each line is in the format of: + +.I ID spanspec ... + +The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR +define how to assign its spans. A line may have multiple +\fIspanspecs\fR in a single line (though dumpconfig generates a +configuration with one per line). + +.SS Span Identifier +A DAHDI device may be specified either by a hardware identifier (a +software readable serial number or whatever) or the location in which +it is installed on the system. The former makes it simpler to change +connector / slot whereas the latter makes it simpler to replace a unit. + +The value in this field is matched (when the commands \fBadd\fR and +\fBremove\fR) are used) to the following values: + + \fIhwid\fR + \fB@\fIlocation\fR + \fIdevpath\fR + +See above for their descriptions. The value may include shell wildcards: +*, ? and [], which are used in the match. The values to be matched are +first cleaned up: '!' is replaced with '/' and any character beyond +"a\-zA\-Z0\-9/:.\-" is removed. + +.SS Span Specification + +Each line should have one or more span specifications: this is the value +used to assign a span with DAHDI in the SysFS interface. A +specification has three colon-separated numbers: + +.I rel_span_no:span_no:first_chan + +for instance, the following are four span specifications for a quad-E1 +device: 1:6:53 2:7:84 3:8:115 4:9:146 occupying spans 6-9 and channels +53-176. + +.B rel_span_no +.RS +The relative number of the span in the device. E.g.: port number. +.RE + +.B span_no +.RS +The desired DAHDI span number. Must be available. +.RE + +.B first_chan +.RS +The desired DAHDI channel number for the first DAHDI channel in the span. +All channels of the span will be assigned following it and hence that +space must be available. +.RE + + +.SH ENVIRONMENT + +.B DAHDICONFDIR +.RS +The directory in which assigned\-spans.conf resides. /etc/dahdi if not +overridden from the environment. +.RE + +.B DAHDISASSIGNEDSPANSCONF +.RS +The path to assigned-spans.conf resides. /etc/dahdi/assigned\-spans.conf if +not overridden from the environment. +.RE + +.B SPAN_ASSIGNMENTS_KEY +.RS +The default value for \-k . Defaults to "hwid" if not overridden from the +environment. +.RE + + +.SH FILES + +.B /etc/dahdi/assigned\-spans.conf +.RS +The default location for the configuration file. +.RE + +.B /sys/bus/dahdi_devices/devices/\fIdevice\fR +.RS +SysFS node for the device. In this directory reside the following +files, among others: + +.B location +.RS +The value of the device's location field. +.RE + +.B assign_span, unassign_span, auto_assign +.RS +Write only files for the operations. Used by \fBadd\fR, \fBremove\fR and +\fBauto\fR, respectively. +.RE + +.RE + +.SH SEE ALSO +dahdi_span_types(8), dahdi_genconf(8), dahdi_cfg(8) + +.SH AUTHOR +dahdi_span_assignments was written by Oron Peled. This manual page was +written by Tzafrir Cohen. Permission is granted to copy, distribute +and/or modify this document under the terms of the GNU General Public +License, Version 2 any later version published by the Free Software +Foundation. + diff --git a/doc/dahdi_span_types.8 b/doc/dahdi_span_types.8 new file mode 100644 index 0000000..4aba1a9 --- /dev/null +++ b/doc/dahdi_span_types.8 @@ -0,0 +1,197 @@ +.TH "DAHDI_SPAN_TYPES" "8" "23 Jan 2014" "" "" + +.SH NAME +dahdi_span_types \- set line modes of DAHDI spans before assignment +.SH SYNOPSIS + +.B dahdi_span_types [\fIoptions\fB] \fB[\fIdevpath \fB...] + +.SH DESCRIPTION +The span type (the line mode: E1/T1/J1) must be set to a span before +DAHDI assigns it a span number, as E1 spans use more channels. +\fBdahdi_span_types\fR applies the span type configuration to an +un-assigned span. + +Using it only makes sense when the kernel module parameter +\fBdahdi.auto_assign_span\fR is unset, otherwise DAHDI automatically +assign span numbers during device registration. + +.B dahdi_span_types +takes a command and an optional list of devices. If no device is given, +the command is applied to all devices. + +The device is marked as a path in the SysFS tree. + +.SH OPTIONS + +.B \-h|\-\-help +.RS +Output usage message and exit +.RE + +.B \-n|\-\-dry\-run +.RS +During \fB"set"\fR operation, only show what would be done, without actually +changing anything. +.RE + +.B \-v|\-\-verbose +.RS +During \fB"set"\fR operation, show the actions that are being performed. +.RE + +.BI \-\-line\-mode= +.RS +During \fB"dumpconfig"\fR operation, force special generation mode: +.IP \(bu 3 +First, generates a "wildcard" entry with the fiven \fBline\-mode\fR. +.IP \(bu 3 +Comment out all span entries. Each of them may be manually un-commented +to override the "wildcard". +.RE + +.SH SUB-COMMANDS +.B set +.RS +Reads settings from \fBspan\-types.conf\fR and applies them to the +device(s) specified in the command line (or all devices, if none +specified). +.RE + +.B list +.RS +List line modes for all spans in the system which may be set with +dahdi_span_types (E1/T1/J1 spans). +.RE + +.B dumpconfig +.RS +List types for the spans in a format fit to be used in +\fBspan\-types.conf\fR. Use this to generate a configuration file after +you have (perhaps manually) set all existing spans. + +.B dahdi_genconf spantypes +uses this command internally. +.RE + +.SH CONFIGURATION +.SS General structure +.B span\-types.conf +is a file with lines specifying line modes of spans. + +Empty lines or lines beginning with '#' are ignored. + +Each line is in the format of: + +.I ID spanspec ... + +The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR +define the line modes of its spans. A line may have multiple +\fIspanspecs\fR in a single line (though dumpconfig generates a +configuration with one per line). + +.SS Span Identifier +A DAHDI device may be specified either by a hardware identifier (a +software readable serial number or whatever) or the location in which +it is installed on the system. The former makes it simpler to change +connector / slot whereas the latter makes it simpler to replace a unit. + +The value in this field is matched (when the command \fBset\fR is +used) to the following values: + + \fIhwid\fR + \fB@\fIlocation\fR + \fIdevpath\fR + +See above for their descriptions. The value may include shell wildcards: +*, ? and [], which are used in the match. The values to be matched are +first cleaned up: '!' is replaced with '/' and any character not in +"a\-zA\-Z0\-9/:.\-" is replaced by "_". + +Note that while span\-types.conf allows an arbitrarily-complex +combination of E1, J1 and T1 ports, it would normally have just a single +wildcard line setting the line mode (the first line in the example below). + +.SS Span Specification + +Each line should have one or more span specifications: this is the value +used to set span type with DAHDI in the SysFS interface. A +specification has two colon-separated fields: + +.I rel_span_no:span_type + +for instance, the following are four span specifications specify ports 1 +and 2 as E1 and ports 3 and 4 as T1: [12]:E1 [34]:T1 . + +.B rel_span_no +.RS +The relative number of the span in the device. E.g.: port number. +This field may contain shell wildcards (*, ? and []) +.RE + +.B span_type +.RS +E1/T1/J1 +.RE + +.SS Multiple matches +During \fBset\fR operation, the \fBdahdi_span_types\fR applies all +matching settings to a span. This is done in the order of lines in the +configuration files. + +Thus, if there are multiple matches to a span -- the last match +will \fIwin\fR (all will be applied to the kernel in order. The last +one in the file will be applied last). + +Example: +.EX +* *:T1 # All spans on all devices will be T1 +usb:X1234567 [34]:E1 # Except spans 3,4 on the device which will be E1 +.EE + + +.SH ENVIRONMENT + +.B DAHDICONFDIR +.RS +The directory in which span\-types.conf resides. /etc/dahdi if not +overridden from the environment. +.RE + +.B DAHDISPANTYPESCONF +.RS +The path to span\-types.conf resides. /etc/dahdi/span\-types.conf if +not overridden from the environment. +.RE + + +.SH FILES + +.B /etc/dahdi/span\-types.conf +.RS +The default location for the configuration file. +.RE + +.B /sys/bus/dahdi_devices/devices/\fIdevice\fR +.RS +SysFS node for the device. In this directory reside the following +files, among others: + +.B spantype +.RS +read/write file. Reading from it returns current configuration for spans +of the device. Span-specifications can be written to it to change line +modes (but only for a span that is not assigned yet). +.RE + + +.SH SEE ALSO +dahdi_span_assignments(8), dahdi_genconf(8), dahdi_cfg(8) + +.SH AUTHOR +dahdi_span_types was written by Oron Peled. This manual page was +written by Tzafrir Cohen. Permission is granted to copy, distribute +and/or modify this document under the terms of the GNU General Public +License, Version 2 any later version published by the Free Software +Foundation. + diff --git a/doc/dahdi_test.8 b/doc/dahdi_test.8 new file mode 100644 index 0000000..90b1e0b --- /dev/null +++ b/doc/dahdi_test.8 @@ -0,0 +1,49 @@ +.TH dahdi_test 8 "2005-06-25" +.SH "NAME" +dahdi_test \(em Test if the DAHDI timer provides timely response +.SH "SYNOPSIS" +.B dahdi_test +.I [ \-v ] + +.SH DESCRIPTION +.B dahdi_test +dahdi_test runs a timing test in a loop and prints the result of each loop. +The test is as follows: + +It reads 8192 bytes from the DAHDI timer device (\fI/dev/dahdi/pseudo\fR). +This should take exactly 8000 ms . It uses calls to +.I gettimeofday(2) +before and after that read to check that indeed exactly 8000ms have passed. + +Values of 100% and 99.99% Are normally considered a definite +.I pass. +Values of 99.98% and 99.97% are probably OK as well. + +.SH OPTIONS +.B \-v +.RS +Be more verbose: print one line per test. +.RE + +.B \-c +.I count +.RS +Run for +.I count +times instead of running forever. +.RE + +.SH FILES +.B /dev/dahdi/pseudo +.RS +.RE +The device file used to access the DAHDI timer. + +.SH SEE ALSO +dahdi_tool(8), dahdi_cfg(8), asterisk(8). gettimeofday(2) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_tool.8 b/doc/dahdi_tool.8 new file mode 100644 index 0000000..2777366 --- /dev/null +++ b/doc/dahdi_tool.8 @@ -0,0 +1,25 @@ +.TH "DAHDI_TOOL" "8" "16 June 2008" "" "" + +.SH NAME +dahdi_tool \- Shows status of DAHDI interfaces +.SH SYNOPSIS + +.B dahdi_tool + +.SH DESCRIPTION +dahdi_tool shows the current status the DAHDI inteface cards plugged +to the computer. + +It displays values like Current Alarms, SyncSource, Tx/Rx +Levels for each DAHDI interface. + +.SH SEE ALSO +dahdi_monitor(8), asterisk (8). + +.SH AUTHOR +This manual page was written by Santiago Ruano Rinc\['o]n + for +the Debian system (but may be used by others). Permission is +granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/doc/dahdi_waitfor_span_assignments.8 b/doc/dahdi_waitfor_span_assignments.8 new file mode 100644 index 0000000..6aaa0b9 --- /dev/null +++ b/doc/dahdi_waitfor_span_assignments.8 @@ -0,0 +1,49 @@ +.TH "DAHDI_WAITFOR_SPAN_ASSIGNMENTS" "8" "22 Jan 2014" "" "" + +.SH NAME +dahdi_waitfor_span_assignments \- wait for DAHDI spans to get (un)assigned +.SH SYNOPSIS + +.B dahdi_span_assignments assigned + +.B dahdi_span_assignments unassigned + +.SH DESCRIPTION +DAHDI spans get assigned / unassigned asynchronously. + +.B dahdi_span_assignments +is a helper script that allows running commands after all the spans have +been assigned or unassigned. + +It takes a single command: \fBassigned\fR or \fBunassigned\fR and waits +(up until a timeout of 5 seconds) for all the DAHDI spans in the system +to do so. + +Note that if the system has a span that will not get assigned +automatically (e.g.: it's not in assigned\-spans.conf), this program +does not know and will wait until a timeout. + +.SH EXAMPLES + + modprobe wctdm24xxp + dahdi_waitfor_span_assignments assigned + do_something + + dahdi_span_assignments add + dahdi_waitfor_span_assignments assigned + do_something_else + + dahdi_span_assignments remove + dahdi_span_assignments unassigned + do_something_completely_different + +.SH SEE ALSO +dahdi_span_assignments(8) + +.SH AUTHOR +dahdi_waitfor_span_assignments was written by Oron Peled. This manual +page was written by Tzafrir Cohen. Permission is granted to copy, +distribute and/or modify this document under the terms of the GNU +General Public License, Version 2 any later version published by the +Free Software Foundation. + diff --git a/doc/fxotune.8 b/doc/fxotune.8 new file mode 100644 index 0000000..d3257fc --- /dev/null +++ b/doc/fxotune.8 @@ -0,0 +1,208 @@ +.TH FXOTUNE "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" +.SH NAME +fxotune \- automatically tune DAHDI FXO channels +.SH SYNOPSIS +.B fxotune \-i +.I [options] +\- detect mode + +.B fxotune \-d +.I [ options ] +\- dump mode + +.B fxotune \-s +.I [ options ] +\- Startup mode +.SH +.SH DESCRIPTION +.B fxotune +is a script that fine-tune parameters of the FXO modules of the +card. It has three modes of operation: + +.I Detect mode (\-i): +it detects and tunes all the available FXO channels. +It writes settings to a configuration file (/etc/fxotune.conf) +from which it can be loaded (e.g: at startup) using \-s . + +.I Dump mode (\-d): +Runs detection on a single DAHDI channel, and just dumps waveforms to +.B fxotune_dump.vals +is generated in the current directory. + +.I Startup mode (\-s): +fxotune just reads the settings from fxotune.conf into the FXO modules. + +You are advised to run fxotune on all FXO ports you have that support +it and that are connected. Note that the tunning is affected by e.g. +the physical parameters of the connection, and thus if it has been +radically changed, you may need to re-run fxotune. + +This program only works for the Digium TDM400P/800P/2400P cards and +compatible and the Xorcom Astribank devices. Other cards (notably X100P +cards and clones) do not have the hardware to support such tuning. + +The tuning process needs a clear line to do the tuning. In order to do +that, it runs in cycles of the following: sets the line off-hook, dials +a dial string (which should set the PSTN provider waiting for the next +digit), and then starts tuning. It has a limited ammount of time for +tuning before the PSTN gives up and gives a busy tone. So after a while +it hangs up and starts a new cycle. + +.B fxotune +has two operation modes: tune (\-i) and set (\-s). In the tune mode it +generates /etc/fxotune.conf, and in the set mode it merely applies the +parameters from fxotune.conf to device's ports. + +.SH OPTIONS +The following options below except \-v (verbose) affect only the +detection process and hence apply only to the +.I detect +and +.I dump +modes. + +In addition, to maintain compatibility with older versions of fxotune, +if in detect or dump mode there is a parameter with option before it, it +is considered to be the +.I dialstring +parameter (\-n). + +.B \-b +.I startdev +.RS +Start tuning from dahdi channel num. \fI startdev\fR: skip all previous +channels. By default starting from channel 1. + +In dump mode (\-d) this is the single channel that will be tested. +.RE + +.B \-e +.I stopdev +.RS +Tune only up to dahdi channel num. \fI stopdev\fR: skip all previous +channels. By default stopping at channel 252. + +In dump mode (\-d) this parameter is ignored. +.RE + +.B \-l +.I delay-to-silence +.RS +Time in seconds to wait after dialing the dial-string to get a clear line. +The default is 0. +before +.RE + +.B \-m +.I silence-good-for +.RS +Time in seconds which states how long the PSTN will wait after we dialed +the dial-string until it starts giving a busy tone. You can test this by +connecting an analog phone to the line and dialing. + +The default is 18 (18 seconds). +.RE + +.B \-n +.I dial-string +.RS +Digits to dial to the PSTN in order to get it stop its dialtone and +waiting for the next digit. + +The default is "4" (sending just the digit 4). It should work in most +cases. Again, this can be tested by connecting a phone to the PSTN line +and dialing the dial-string. +.RE + +.B \-t +.I detect-type +.RS +This option allows using the older detection method used by fxotune of +Zaptel 1.2. use +.B \-t 1 +for that older method. whereas +.B \-t 2 +(the default) uses the current method. + +This option only applies to detect mode (\-i). +.RE + +.B \-v[vvvv] +.RS +Sets debugging on. The more v-s, the higher debug level. + +Note that: \-vv \-v will actually set debug level to 1 instead of 3. +.RE + +.B \-w +.I wave-form +.RS +The default: \-1, for multitone waveform. Alternatively: a frequency of a +single tone. + +This option only applies to dump mode (\-d). +.RE + + +.SH EXAMPLES +.RS +fxotune \-i 9 +.RE +if you need to dial 9 for an external line. If you always get a line, you +can simply use any digit. +.RE + +.B \-s +.RS +Load settings from the last test. Used at startup. +.RE + +.SH FILES +.I /etc/fxotune.conf +.RS +The configuration file generated by fxotune in detect mode and from which +configuration is loaded when +.B \-s +is used. + +.SH NOTES +Running fxotune takes approximately a minute per port. If you wish to only +run fxotune for several ports, you can use the options \-b and \-e to set a +specific range of ports. Another useful trick is to actually keep asterisk +running, and only "destroy" the dahdi channels you wish to tune (dahdi +destroy channel NNN): other channels will be used by Asterisk, and hence +skipped. This can be useful if you have many FXO ports that are not connected. + +.B fxotune +writes immediately to +.B /etc/fxotune.conf +so if you stop it half-way, you may get a half-configured system. If you +have already tuned your FXO channels and wish to test-run fxotune again, +you are advised to backup /etc/fxotune.conf . + +The default for \-m is 18 seconds. This asusmes that you get a clear line +for at least 18 seconds. It is advised that you test that timeout earlier +by connecting a phone to the FXO line, dialing 4 (or whatever dial string +you put with \-n) and see how much time of silence you have. + +If you connect your device to a PSTN provider that is not in the US, there +is a similar operation you should apply before even getting to fxotune: +setting the opermode. The opermode sets a number of country-specific +parameters. For the Digium analog cards this is set through the kernel module +parameter 'opermode' . For the Xorcom Astribank this is set through the +variable 'opermode' in /etc/dahdi/xpp.conf . +For valid values of this parameter, see +/usr/share/asterisk/init_fxo_modes (FIXME: this has changed and will +change. Tzafrir). + +.SH SEE ALSO +dahdi_cfg(8), dahdi_tool(8), dahdi_monitor(8), asterisk(8). + +.SH AUTHOR +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/fxstest.8 b/doc/fxstest.8 new file mode 100644 index 0000000..159480f --- /dev/null +++ b/doc/fxstest.8 @@ -0,0 +1,60 @@ +.TH "FXSTEST" "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" + +.SH NAME +fxstest \- Simple tests for DAHDI FXS adapters +.SH SYNOPSIS + +.B fxstest /dev/dahdi/\fIN comand\fR + +.SH DESCRIPTION +fxstest can be used to issue one of a number simple tests to FXS +adapters (analog adapters intended to connect phones). + +.SH OPTIONS +All of those tests operate on a single dahdi channel which has to be an +FXS port, and must not be in use by Asterisk or any other program. + +The command has two mandatory parameters. +The first parameter is the device file to operate on. It is typically +/dev/dahdi/NN , a device file under /dev/dahdi . + +The second parameter is the name of the command to run on that channel: + +.I stats +.RS +Reports voltages +.RE + +.I regdump +.RS +Dumps ProSLIC registers +.RE + +.I tones +.RS +Plays a series of tones +.RE + +.I polarity +.RS +Requests channel to reverse polarity. +.RE + +.I ring +.RS +Rings phone +.RE + +.SH "SEE ALSO" +.PP +dahdi_tool(8), dahdi_cfg(8), dahdi_monitor(8), asterisk(8). +.SH BUGS +Does not allow testing channels beyond 249. Should support opening +channels through /dev/dahdi/channel . +.SH AUTHOR +.PP +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. +.PP diff --git a/doc/patgen.8 b/doc/patgen.8 new file mode 100644 index 0000000..3585cff --- /dev/null +++ b/doc/patgen.8 @@ -0,0 +1,44 @@ +.TH patgen 8 "2 Dec 2009" +.SH NAME +patgen \(em Generates a Pattern for a DAHDI Clear Channel Test +.SH SYNOPSIS +.B patgen +.I dahdi-device + +.SH DESCRIPTION +.B patgen +Sends test data to a DAHDI channel. The channel should be of CLEAR +signalling (e.g: B channel of a PRI line). pattest(8) is used to test +the data at the other side. See its manual for more information. + +.B patgen +Must be able to write to the channel. Hence this cannot be used for a +channel used by Asterisk. + +.SH OPTIONS +.I dahdi-device +.RS +A DAHDI device. Can be either a device number or an explicit device file +name +.RE + +.SH EXAMPLE + patgen /dev/dahdi/5 + + patgen 305 + +.SH BUGS +Waiting for you to report them at . + +.SH SEE ALSO +pattest(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/doc/pattest.8 b/doc/pattest.8 new file mode 100644 index 0000000..bce3f1c --- /dev/null +++ b/doc/pattest.8 @@ -0,0 +1,49 @@ +.TH pattest 8 "2 Dec 2009" +.SH NAME +pattest \(em Tests a Pattern for a DAHDI Clear Channel Test +.SH SYNOPSIS +.B pattest +.I dahdi-device + +.SH DESCRIPTION +.B pattest +Receives test data from a DAHDI channel and checks if it matches the +test pattern. The channel should be of CLEAR signalling (e.g: B channel +of a PRI line). patgen(8) is used to generate the data at the other side. + +.B pattest +Must be able to read from the channel. Hence this cannot be used for a +channel used by Asterisk. + +The pattern is a simple series of values from 0 to 255. Hence it takes +at most one sample to get in sync with the other side. If there is no +output, all is well. Output is an error message. + +.SH OPTIONS +.I dahdi-device +.RS +A DAHDI device. Can be either a device number or an explicit device file +name +.RE + +.SH EXAMPLE + pattest /dev/dahdi/5 + + pattest 305 +.RE + +.SH BUGS +Gives way too many errors when does not get any input. + +.SH SEE ALSO +patgen(8), dahdi_cfg(8), asterisk(8). + +.SH AUTHOR + +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/fxotune.c b/fxotune.c new file mode 100644 index 0000000..865dc70 --- /dev/null +++ b/fxotune.c @@ -0,0 +1,1328 @@ +/* + * fxotune.c -- A utility for tuning the various settings on the fxo + * modules for the TDM400 cards. + * + * by Matthew Fredrickson + * + * (C) 2004-2008 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dahdi_tools_version.h" +#include "fxotune.h" + +#define TEST_DURATION 2000 +#define BUFFER_LENGTH (2 * TEST_DURATION) +#define SKIP_SAMPLES 800 +#define SINE_SAMPLES 8000 + +static float sintable[SINE_SAMPLES]; + +static const float amplitude = 16384.0; + +static char *configfile = "/etc/fxotune.conf"; + +static int audio_dump_fd = -1; + +static int printbest = 0; + +#define MAX_RESULTS (5) +struct result_catalog { + int idx; + float echo; + float freqres; + struct wctdm_echo_coefs settings; +}; + +struct { + struct result_catalog results[MAX_RESULTS]; + int numactive; +} topresults; + +static char *usage = +"Usage: fxotune [-v[vv] (-s | -i | -d )\n" +"\n" +" -s : set previously calibrated echo settings\n" +" -i : calibrate echo settings\n" +" options : [] [-t ]\n" +" [-b ][-e ]\n" +" [-n ][-l ][-m ]\n" +" -d : dump input and output waveforms to ./fxotune_dump.vals\n" +" options : [-b ][-w ]\n" +" [-n ][-l ][-m ]\n" +" -v : more output (-vv, -vvv also)\n" +" -p : print the 5 best candidates for acim and coefficients settings\n" +" -x : Perform sin/cos functions using table lookup\n" +" -o : Write the received raw 16-bit signed linear audio that is\n" +" used in processing to the file specified by \n" +" -c \n" +"\n" +" - type of calibration\n" +" (default 2, old method 1)\n" +" \n" +" - defines a range of devices to test\n" +" (default: 1-252)\n" +" - string to dial to clear the line\n" +" (default 5)\n" +" - seconds to wait for line to clear (default 0)\n" +" - seconds before line will no longer be clear\n" +" (default 18)\n" +" - the device to perform waveform dump on\n" +" (default 1)\n" +" - -1 for multitone waveform, or frequency of\n" +" single tone (default -1)\n" +" - Alternative file to set from / calibrate to.\n" +" (Default: /etc/fxotune.conf)\n" +; + + +#define OUT_OF_BOUNDS(x) ((x) < 0 || (x) > 255) + +struct silence_info{ + char *dialstr; + /** fd of device we are working with */ + int device; + /** seconds we should wait after dialing the dialstring before we know for sure we'll have silence */ + int initial_delay; + /** seconds after which a reset should occur */ + int reset_after; + /** time of last reset */ + struct timeval last_reset; +}; + +static short outbuf[TEST_DURATION]; +static int debug = 0; + +static FILE *debugoutfile = NULL; + +static int use_table = 0; + +static int fxotune_read(int fd, void *buffer, int len) +{ + int res; + + res = read(fd, buffer, len); + + if ((res > 0) && (audio_dump_fd != -1)) { + res = write(audio_dump_fd, buffer, len); + } + + return res; +} + +/** + * Makes sure that the line is clear. + * Right now, we do this by relying on the user to specify how long after dialing the + * dialstring we can rely on the line being silent (before the telco complains about + * the user not hitting the next digit). + * + * A more robust way to do this would be to actually measure the sound levels on the line, + * but that's a lot more complicated, and this should work. + * + * @return 0 if succesful (no errors), 1 if unsuccesful + */ +static int ensure_silence(struct silence_info *info) +{ + struct timeval tv; + long int elapsedms; + int x = DAHDI_ONHOOK; + struct dahdi_dialoperation dop; + + gettimeofday(&tv, NULL); + + if (info->last_reset.tv_sec == 0) { + /* this is the first request, we will force it to run */ + elapsedms = -1; + } else { + /* this is not the first request, we will compute elapsed time */ + elapsedms = ((tv.tv_sec - info->last_reset.tv_sec) * 1000L + (tv.tv_usec - info->last_reset.tv_usec) / 1000L); + } + if (debug > 4) { + fprintf(stdout, "Reset line request received - elapsed ms = %li / reset after = %ld\n", elapsedms, info->reset_after * 1000L); + } + + if (elapsedms > 0 && elapsedms < info->reset_after * 1000L) + return 0; + + if (debug > 1){ + fprintf(stdout, "Resetting line\n"); + } + + /* do a line reset */ + /* prepare line for silence */ + /* Do line hookstate reset */ + + if (ioctl(info->device, DAHDI_HOOK, &x)) { + fprintf(stderr, "Unable to hang up fd %d\n", info->device); + return -1; + } + + sleep(2); + x = DAHDI_OFFHOOK; + if (ioctl(info->device, DAHDI_HOOK, &x)) { + fprintf(stderr, "Cannot bring fd %d off hook\n", info->device); + return -1; + } + sleep(2); /* Added to ensure that dial can actually takes place */ + + memset(&dop, 0, sizeof(dop)); + dop.op = DAHDI_DIAL_OP_REPLACE; + dop.dialstr[0] = 'T'; + dahdi_copy_string(dop.dialstr + 1, info->dialstr, sizeof(dop.dialstr)); + + + if (ioctl(info->device, DAHDI_DIAL, &dop)) { + fprintf(stderr, "Unable to dial!\n"); + return -1; + } + sleep(1); + sleep(info->initial_delay); + + + gettimeofday(&info->last_reset, NULL); + + + return 0; +} + +/** + * Generates a tone of specified frequency. + * + * @param hz the frequency of the tone to be generated + * @param idx the current sample + * to begenerated. For a normal waveform you need to increment + * this every time you execute the function. + * + * @return 16bit slinear sample for the specified index + */ +static short inline gentone(int hz, int idx) +{ + return amplitude * sin((idx * 2.0 * M_PI * hz)/8000); +} + +/* Using DTMF tones for now since they provide good mid band testing + * while not being harmonics of each other */ +static int freqs[] = {697, 770, 941, 1209, 1336, 1633}; +static int freqcount = 6; + +/** + * Generates a waveform of several frequencies. + * + * @param idx the current sample + * to begenerated. For a normal waveform you need to increment + * this every time you execute the function. + * + * @return 16bit slinear sample for the specified index + */ +static short inline genwaveform(int idx) +{ + int i = 0; + float response = (float)0; + for (i = 0; i < freqcount; i++){ + response += sin((idx * 2.0 * M_PI * freqs[i])/8000); + } + + + return amplitude * response / freqcount; +} + + +/** + * Calculates the RMS of the waveform buffer of samples in 16bit slinear format. + * prebuf the buffer of either shorts or floats + * bufsize the number of elements in the prebuf buffer (not the number of bytes!) + * short_format 1 if prebuf points to an array of shorts, 0 if it points to an array of floats + * + * Formula for RMS (http://en.wikipedia.org/wiki/Root_mean_square): + * + * Xrms = sqrt(1/N Sum(x1^2, x2^2, ..., xn^2)) + * + * Note: this isn't really a power calculation - but it gives a good measure of the level of the response + * + * @param prebuf the buffer containing the values to compute + * @param bufsize the size of the buffer + * @param short_format 1 if prebuf contains short values, 0 if it contains float values + */ +static float power_of(void *prebuf, int bufsize, int short_format) +{ + float sum_of_squares = 0; + int numsamples = 0; + float finalanswer = 0; + short *sbuf = (short*)prebuf; + float *fbuf = (float*)prebuf; + int i = 0; + + if (short_format) { + /* idiot proof checks */ + if (bufsize <= 0) + return -1; + + numsamples = bufsize; /* Got rid of divide by 2 - the bufsize parameter should give the number of samples (that's what it does for the float computation, and it should do it here as well) */ + + for (i = 0; i < numsamples; i++) { + sum_of_squares += ((float)sbuf[i] * (float)sbuf[i]); + } + } else { + /* Version for float inputs */ + for (i = 0; i < bufsize; i++) { + sum_of_squares += (fbuf[i] * fbuf[i]); + } + } + + finalanswer = sum_of_squares/(float)bufsize; /* need to divide by the number of elements in the sample for RMS calc */ + + if (finalanswer < 0) { + fprintf(stderr, "Error: Final answer negative number %f\n", finalanswer); + return -3; + } + + return sqrtf(finalanswer); +} + +/* + * In an effort to eliminate as much as possible the effect of outside noise, we use principles + * from the Fourier Transform to attempt to calculate the return loss of our signal for each setting. + * + * To begin, we send our output signal out on the line. We then receive back the reflected + * response. In the Fourier Transform, each evenly distributed frequency within the window + * is correlated (multiplied against, then the resulting samples are added together) with + * the real (cos) and imaginary (sin) portions of that frequency base to detect that frequency. + * + * Instead of doing a complete Fourier Transform, we solve the transform for only our signal + * by multiplying the received signal by the real and imaginary portions of our reference + * signal. This then gives us the real and imaginary values that we can use to calculate + * the return loss of the sinusoids that we sent out on the line. This is done by finding + * the magnitude (think polar form) of the vector resulting from the real and imaginary + * portions calculated above. + * + * This essentially filters out any other noise which maybe present on the line which is outside + * the frequencies used in our test multi-tone. + */ + +void init_sinetable(void) +{ + int i; + if (debug) { + fprintf(stdout, "Using sine tables with %d samples\n", SINE_SAMPLES); + } + for (i = 0; i < SINE_SAMPLES; i++) { + sintable[i] = sin(((float)i * 2.0 * M_PI )/(float)(SINE_SAMPLES)); + } +} + +/* Sine and cosine table lookup to use periodicity of the calculations being done */ +float sin_tbl(int arg, int num_per_period) +{ + arg = arg % num_per_period; + + arg = (arg * SINE_SAMPLES)/num_per_period; + + return sintable[arg]; +} + +float cos_tbl(int arg, int num_per_period) +{ + arg = arg % num_per_period; + + arg = (arg * SINE_SAMPLES)/num_per_period; + + arg = (arg + SINE_SAMPLES/4) % SINE_SAMPLES; /* Pi/2 adjustment */ + + return sintable[arg]; +} + + +static float db_loss(float measured, float reference) +{ + return 20 * (logf(measured/reference)/logf(10)); +} + +static void one_point_dft(const short *inbuf, int len, int frequency, float *real, float *imaginary) +{ + float myreal = 0, myimag = 0; + int i; + + for (i = 0; i < len; i++) { + if (use_table) { + myreal += (float) inbuf[i] * cos_tbl(i*frequency, 8000); + myimag += (float) inbuf[i] * sin_tbl(i*frequency, 8000); + } else { + myreal += (float) inbuf[i] * cos((i * 2.0 * M_PI * frequency)/8000); + myimag += (float) inbuf[i] * sin((i * 2.0 * M_PI * frequency)/8000); + } + } + + myimag *= -1; + + *real = myreal / (float) len; + *imaginary = myimag / (float) len; +} + + +static float calc_magnitude(short *inbuf, int insamps) +{ + float real, imaginary, magnitude; + float totalmagnitude = 0; + int i; + + for (i = 0; i < freqcount; i++) { + one_point_dft(inbuf, insamps, freqs[i], &real, &imaginary); + magnitude = sqrtf((real * real) + (imaginary * imaginary)); + totalmagnitude += magnitude; + } + + return totalmagnitude; +} + + +/** + * dumps input and output buffer contents for the echo test - used to see exactly what's going on + */ +static int maptone(int whichdahdi, int freq, char *dialstr, int delayuntilsilence) +{ + int i = 0; + int res = 0, x = 0; + struct dahdi_bufferinfo bi; + short inbuf[TEST_DURATION]; /* changed from BUFFER_LENGTH - this buffer is for short values, so it should be allocated using the length of the test */ + FILE *outfile = NULL; + int leadin = 50; + int trailout = 100; + struct silence_info sinfo; + float power_result; + float power_waveform; + float echo; + + outfile = fopen("fxotune_dump.vals", "w"); + if (!outfile) { + fprintf(stdout, "Cannot create fxotune_dump.vals\n"); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = TEST_DURATION; /* KD - changed from BUFFER_LENGTH; */ + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + + /* Fill the output buffers */ + for (i = 0; i < leadin; i++) + outbuf[i] = 0; + for (; i < TEST_DURATION - trailout; i++){ + outbuf[i] = freq > 0 ? gentone(freq, i) : genwaveform(i); /* if frequency is negative, use a multi-part waveform instead of a single frequency */ + } + for (; i < TEST_DURATION; i++) + outbuf[i] = 0; + + /* Make sure the line is clear */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = 4; /* doesn't matter - we are only running one test */ + + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear outside line\n"); + return -1; + } + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); /* we are sending a TEST_DURATION length array of shorts (which are 2 bytes each) */ + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + /* write content of output buffer to debug file */ + power_result = power_of(inbuf, TEST_DURATION, 1); + power_waveform = power_of(outbuf, TEST_DURATION, 1); + echo = power_result/power_waveform; + + fprintf(outfile, "Buffers, freq=%d, outpower=%0.0f, echo=%0.4f\n", freq, power_result, echo); + fprintf(outfile, "Sample, Input (received from the line), Output (sent to the line)\n"); + for (i = 0; i < TEST_DURATION; i++){ + fprintf(outfile, "%d, %d, %d\n", + i, + inbuf[i], + outbuf[i] + ); + } + + fclose(outfile); + + fprintf(stdout, "echo ratio = %0.4f (%0.1f / %0.1f)\n", echo, power_result, power_waveform); + + return 0; +} + + +/** + * Initialize the data store for storing off best calculated results + */ +static void init_topresults(void) +{ + topresults.numactive = 0; +} + + +/** + * If this is a best result candidate, store in the top results data store + * This is dependent on being the lowest echo value + * + * @param tbleoffset - The offset into the echo_trys table used + * @param setting - Pointer to the settings used to achieve the fgiven value + * @param echo - The calculated echo return value (in dB) + * @param echo - The calculated magnitude of the response + */ +static void set_topresults(int tbloffset, struct wctdm_echo_coefs *setting, float echo, float freqres) +{ + int place; + int idx; + + for ( place = 0; place < MAX_RESULTS && place < topresults.numactive; place++) { + if (echo < topresults.results[place].echo) { + break; + } + } + + if (place < MAX_RESULTS) { + /* move results to the bottom */ + for (idx = topresults.numactive-2; idx >= place; idx--) { + topresults.results[idx+1] = topresults.results[idx]; + } + topresults.results[place].idx = tbloffset; + topresults.results[place].settings = *setting; + topresults.results[place].echo = echo; + topresults.results[place].freqres = freqres; + if (MAX_RESULTS > topresults.numactive) { + topresults.numactive++; + } + } +} + + +/** + * Prints the top results stored to stdout + * + * @param header - Text that goes in the header of the response + */ +static void print_topresults(char * header) +{ + int item; + + fprintf(stdout, "Top %d results for %s\n", topresults.numactive, header); + for (item = 0; item < topresults.numactive; item++) { + fprintf(stdout, "Res #%d: index=%d, %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d: magnitude = %0.0f, echo = %0.4f dB\n", + item+1, topresults.results[item].idx, topresults.results[item].settings.acim, + topresults.results[item].settings.coef1, topresults.results[item].settings.coef2, + topresults.results[item].settings.coef3, topresults.results[item].settings.coef4, + topresults.results[item].settings.coef5, topresults.results[item].settings.coef6, + topresults.results[item].settings.coef7, topresults.results[item].settings.coef8, + topresults.results[item].freqres, topresults.results[item].echo); + + } +} + + +/** + * Perform calibration type 2 on the specified device + * + * Determine optimum echo coefficients for the specified device + * + * New tuning strategy. If we have a number that we can dial that will result in silence from the + * switch, the tune will be *much* faster (we don't have to keep hanging up and dialing a digit, etc...) + * The downside is that the user needs to actually find a 'no tone' phone number at their CO's switch - but for + * really fixing echo problems, this is what it takes. + * + * Also, for the purposes of optimizing settings, if we pick a single frequency and test with that, + * we can try a whole bunch of impedence/echo coefficients. This should give better results than trying + * a bunch of frequencies, and we can always do a a frequency sweep to pick between the best 3 or 4 + * impedence/coefficients configurations. + * + * Note: It may be possible to take this even further and do some pertubation analysis on the echo coefficients + * themselves (maybe use the 72 entry sweep to find some settings that are close to working well, then + * deviate the coefficients a bit to see if we can improve things). A better way to do this would be to + * use the optimization strategy from silabs. For reference, here is an application note that describes + * the echo coefficients (and acim values): + * + * http://www.silabs.com/Support%20Documents/TechnicalDocs/an84.pdf + * + * See Table 13 in this document for a breakdown of acim values by region. + * + * http://www.silabs.com/Support%20Documents/TechnicalDocs/si3050-18-19.pdf + * + */ +static int acim_tune2(int whichdahdi, int freq, char *dialstr, int delayuntilsilence, int silencegoodfor, struct wctdm_echo_coefs *coefs_out) +{ + int i = 0; + int res = 0, x = 0; + int lowesttry = -1; + float lowesttryresult = 999999999999.0; + float lowestecho = 999999999999.0; + struct dahdi_bufferinfo bi; + short inbuf[TEST_DURATION * 2]; + struct silence_info sinfo; + int echo_trys_size = 72; + int trys = 0; + float waveform_power; + float freq_result; + float echo; + + init_topresults(); + + if (debug && !debugoutfile) { + if (!(debugoutfile = fopen("fxotune.vals", "w"))) { + fprintf(stdout, "Cannot create fxotune.vals\n"); + return -1; + } + } + + /* Set echo settings */ + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &echo_trys[0])) { + fprintf(stderr, "Unable to set impedance on fd %d\n", whichdahdi); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = BUFFER_LENGTH; + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + x = DAHDI_OFFHOOK; + if (ioctl(whichdahdi, DAHDI_HOOK, &x)) { + fprintf(stderr, "Cannot bring fd %d off hook", whichdahdi); + return -1; + } + + + /* Set up silence settings */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = silencegoodfor; + + /* Fill the output buffers */ + for (i = 0; i < TEST_DURATION; i++) + outbuf[i] = freq > 0 ? gentone(freq, i) : genwaveform(i); /* if freq is negative, use a multi-frequency waveform */ + + /* compute power of input (so we can later compute echo levels relative to input) */ + waveform_power = calc_magnitude(outbuf, TEST_DURATION); + + /* sweep through the various coefficient settings and see how our responses look */ + + for (trys = 0; trys < echo_trys_size; trys++){ + + /* ensure silence on the line */ + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear outside line\n"); + return -1; + } + + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &echo_trys[trys])) { + fprintf(stderr, "Unable to set echo coefficients on fd %d\n", whichdahdi); + return -1; + } + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH * 2); + if (res != BUFFER_LENGTH * 2) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + freq_result = calc_magnitude(inbuf, TEST_DURATION * 2); + echo = db_loss(freq_result, waveform_power); + +#if 0 + if (debug > 0) + fprintf(stdout, "%3d,%d,%d,%d,%d,%d,%d,%d,%d: magnitude = %0.0f, echo = %0.4f dB\n", + echo_trys[trys].acim, echo_trys[trys].coef1, echo_trys[trys].coef2, + echo_trys[trys].coef3, echo_trys[trys].coef4, echo_trys[trys].coef5, + echo_trys[trys].coef6, echo_trys[trys].coef7, echo_trys[trys].coef8, + freq_result, echo); +#endif + + if (freq_result < lowesttryresult){ + lowesttry = trys; + lowesttryresult = freq_result; + lowestecho = echo; + } + if (debug) { + char result[256]; + snprintf(result, sizeof(result), "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%f,%f", + echo_trys[trys].acim, + echo_trys[trys].coef1, + echo_trys[trys].coef2, + echo_trys[trys].coef3, + echo_trys[trys].coef4, + echo_trys[trys].coef5, + echo_trys[trys].coef6, + echo_trys[trys].coef7, + echo_trys[trys].coef8, + freq_result, + echo + ); + + fprintf(debugoutfile, "%s\n", result); + fprintf(stdout, "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d: magnitude = %0.0f, echo = %0.4f dB\n", + echo_trys[trys].acim, echo_trys[trys].coef1, echo_trys[trys].coef2, + echo_trys[trys].coef3, echo_trys[trys].coef4, echo_trys[trys].coef5, + echo_trys[trys].coef6, echo_trys[trys].coef7, echo_trys[trys].coef8, + freq_result, echo); + } + + if (printbest) { + set_topresults(trys, &echo_trys[trys], echo, freq_result); + } + } + + if (debug > 0) + fprintf(stdout, "Config with lowest response = %d, magnitude = %0.0f, echo = %0.4f dB\n", lowesttry, lowesttryresult, lowestecho); + + memcpy(coefs_out, &echo_trys[lowesttry], sizeof(struct wctdm_echo_coefs)); + if (printbest) { + print_topresults("Acim2_tune Test"); + } + + return 0; +} + +/** + * Perform calibration type 1 on the specified device. Only tunes the line impedance. Look for best response range + */ +static int acim_tune(int whichdahdi, char *dialstr, int delayuntilsilence, int silencegoodfor, struct wctdm_echo_coefs *coefs_out) +{ + int i = 0, freq = 0, acim = 0; + int res = 0, x = 0; + struct dahdi_bufferinfo bi; + struct wctdm_echo_coefs coefs; + short inbuf[TEST_DURATION]; /* changed from BUFFER_LENGTH - this buffer is for short values, so it should be allocated using the length of the test */ + int lowest = 0; + FILE *outfile = NULL; + float acim_results[16]; + struct silence_info sinfo; + + if (debug) { + outfile = fopen("fxotune.vals", "w"); + if (!outfile) { + fprintf(stdout, "Cannot create fxotune.vals\n"); + return -1; + } + } + + /* Set up silence settings */ + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.device = whichdahdi; + sinfo.dialstr = dialstr; + sinfo.initial_delay = delayuntilsilence; + sinfo.reset_after = silencegoodfor; + + /* Set echo settings */ + memset(&coefs, 0, sizeof(coefs)); + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &coefs)) { + fprintf(stdout, "Skipping non-TDM / non-FXO\n"); + return -1; + } + + x = 1; + if (ioctl(whichdahdi, DAHDI_SETLINEAR, &x)) { + fprintf(stderr, "Unable to set channel to signed linear mode.\n"); + return -1; + } + + memset(&bi, 0, sizeof(bi)); + if (ioctl(whichdahdi, DAHDI_GET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to get buffer information!\n"); + return -1; + } + bi.numbufs = 2; + bi.bufsize = BUFFER_LENGTH; + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + if (ioctl(whichdahdi, DAHDI_SET_BUFINFO, &bi)) { + fprintf(stderr, "Unable to set buffer information!\n"); + return -1; + } + + for (acim = 0; acim < 16; acim++) { + float freq_results[15]; + + coefs.acim = acim; + if (ioctl(whichdahdi, WCTDM_SET_ECHOTUNE, &coefs)) { + fprintf(stderr, "Unable to set impedance on fd %d\n", whichdahdi); + return -1; + } + + for (freq = 200; freq <=3000; freq+=200) { + /* Fill the output buffers */ + for (i = 0; i < TEST_DURATION; i++) + outbuf[i] = gentone(freq, i); + + /* Make sure line is ready for next test iteration */ + if (ensure_silence(&sinfo)){ + fprintf(stderr, "Unable to get a clear line\n"); + return -1; + } + + + /* Flush buffers */ + x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE | DAHDI_FLUSH_EVENT; + if (ioctl(whichdahdi, DAHDI_FLUSH, &x)) { + fprintf(stderr, "Unable to flush I/O: %s\n", strerror(errno)); + return -1; + } + + /* send data out on line */ + res = write(whichdahdi, outbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + fprintf(stderr, "Could not write all data to line\n"); + return -1; + } + + /* read return response */ +retry: + /* read return response */ + res = fxotune_read(whichdahdi, inbuf, BUFFER_LENGTH); + if (res != BUFFER_LENGTH) { + int dummy; + + ioctl(whichdahdi, DAHDI_GETEVENT, &dummy); + goto retry; + } + + /* calculate power of response */ + + freq_results[(freq/200)-1] = power_of(inbuf+SKIP_SAMPLES, TEST_DURATION-SKIP_SAMPLES, 1); /* changed from inbuf+SKIP_BYTES, BUFFER_LENGTH-SKIP_BYTES, 1 */ + if (debug) fprintf(outfile, "%d,%d,%f\n", acim, freq, freq_results[(freq/200)-1]); + } + acim_results[acim] = power_of(freq_results, 15, 0); + } + + if (debug) { + for (i = 0; i < 16; i++) + fprintf(outfile, "acim_results[%d] = %f\n", i, acim_results[i]); + } + /* Find out what the "best" impedance is for the line */ + lowest = 0; + for (i = 0; i < 16; i++) { + if (acim_results[i] < acim_results[lowest]) { + lowest = i; + } + } + + coefs_out->acim = lowest; + coefs_out->coef1 = 0; + coefs_out->coef2 = 0; + coefs_out->coef3 = 0; + coefs_out->coef4 = 0; + coefs_out->coef5 = 0; + coefs_out->coef6 = 0; + coefs_out->coef7 = 0; + coefs_out->coef8 = 0; + + return 0; +} + +static int channel_is_fxo(int channo) +{ + int res = 0; + int fd; + const char *CTL_DEV = "/dev/dahdi/ctl"; + struct dahdi_params params; + + fd = open(CTL_DEV, O_RDWR, 0600); + if (-1 == fd) { + fprintf(stderr, "Failed to open %s: %s\n", + CTL_DEV, strerror(errno)); + return -1; + } + params.channo = channo; + if (ioctl(fd, DAHDI_GET_PARAMS, ¶ms)) { + fprintf(stderr, + "%d is not a valid channel number.\n", channo); + res = -1; + } else if (0 == (__DAHDI_SIG_FXS & params.sigcap)) { + fprintf(stderr, + "Channel %d is not an FXO port.\n", channo); + res = -1; + } else if (0 == params.sigtype) { + fprintf(stderr, + "Cannot run on unconfigured channel %d. Please run dahdi_cfg to configure channels before running fxotune.\n", + channo); + res = -1; + } + close(fd); + return res; +} + +static int channel_open(int channo) +{ + int fd; + const char *DEVICE = "/dev/dahdi/channel"; + + if (channo > 0) { + if (channel_is_fxo(channo)) + return -1; + + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DADHI_SPECIFY ioctl failed"); + close(fd); + fd = -1; + } + } else { + fprintf(stderr, + "Specified channel is not a valid channel number"); + fd = -1; + } + return fd; +} + +/** + * Reads echo register settings from the configuration file and pushes them into + * the appropriate devices + * + * @param configfilename the path of the file that the calibration results should be written to + * + * @return 0 if successful, !0 otherwise + */ +static int do_set(char *configfilename, int dev_range, int startdev, int stopdev) +{ + FILE *fp = NULL; + int res = 0; + int fd = 0; + + fp = fopen(configfile, "r"); + + if (!fp) { + fprintf(stdout, "Cannot open %s!\n",configfile); + return -1; + } + + + while (res != EOF) { + struct wctdm_echo_coefs mycoefs; + char completedahdipath[56] = ""; + int mydahdi,myacim,mycoef1,mycoef2,mycoef3,mycoef4,mycoef5,mycoef6,mycoef7,mycoef8; + + + res = fscanf(fp, "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d",&mydahdi,&myacim,&mycoef1, + &mycoef2,&mycoef3,&mycoef4,&mycoef5,&mycoef6,&mycoef7, + &mycoef8); + + if (res == EOF) { + break; + } + if (dev_range && (mydahdi < startdev || mydahdi > stopdev)) + continue; + + /* Check to be sure conversion is done correctly */ + if (OUT_OF_BOUNDS(myacim) || OUT_OF_BOUNDS(mycoef1)|| + OUT_OF_BOUNDS(mycoef2)|| OUT_OF_BOUNDS(mycoef3)|| + OUT_OF_BOUNDS(mycoef4)|| OUT_OF_BOUNDS(mycoef5)|| + OUT_OF_BOUNDS(mycoef6)|| OUT_OF_BOUNDS(mycoef7)|| OUT_OF_BOUNDS(mycoef8)) { + + fprintf(stdout, "Bounds check error on inputs from %s:%d\n", configfile, mydahdi); + return -1; + } + + mycoefs.acim = myacim; + mycoefs.coef1 = mycoef1; + mycoefs.coef2 = mycoef2; + mycoefs.coef3 = mycoef3; + mycoefs.coef4 = mycoef4; + mycoefs.coef5 = mycoef5; + mycoefs.coef6 = mycoef6; + mycoefs.coef7 = mycoef7; + mycoefs.coef8 = mycoef8; + + if (debug >= 2) + printf("fxotune: set channel %d\n", mydahdi); + fd = channel_open(mydahdi); + if (fd < 0) { + return -1; + } + + if (ioctl(fd, WCTDM_SET_ECHOTUNE, &mycoefs)) { + fprintf(stdout, "%s: %s\n", completedahdipath, strerror(errno)); + return -1; + } + + close(fd); + } + + fclose(fp); + + if (debug) + fprintf(stdout, "fxotune: successfully set echo coeffecients on FXO modules\n"); + return 0; +} + +/** + * Output waveform information from a single test + * + * Clears the line, then sends a single waveform (multi-tone, or single tone), and listens + * for the response on the line. Output is written to fxotune_dump.vals + * + * @param startdev the device to test + * @param dialstr the string that should be dialed to clear the dialtone from the line + * @param delayuntilsilence the number of seconds to wait after dialing dialstr before starting the test + * @param silencegoodfor the number of seconds that the test can run before having to reset the line again + * (this is basically the amount of time it takes before the 'if you'd like to make a call...' message + * kicks in after you dial dialstr. This test is so short that the value is pretty much ignored. + * @param waveformtype the type of waveform to use - -1 = multi-tone waveform, otherwise the specified value + * is used as the frequency of a single tone. A value of 0 will output silence. + */ +static int do_dump(int startdev, char* dialstr, int delayuntilsilence, int silencegoodfor, int waveformtype) +{ + int res = 0; + int fd; + char dahdidev[80] = ""; + + int dahdimodule = startdev; + fd = channel_open(dahdimodule); + if (fd < 0) { + return -1; + } + + fprintf(stdout, "Dumping module %s\n", dahdidev); + res = maptone(fd, waveformtype, dialstr, delayuntilsilence); + + close(fd); + + if (res) { + fprintf(stdout, "Failure!\n"); + return res; + } else { + fprintf(stdout, "Done!\n"); + return 0; + } + +} + +/** + * Performs calibration on all specified devices + * + * @param startdev the first device to check + * @param enddev the last device to check + * @param calibtype the type of calibration to perform. 1=old style (loops through individual frequencies + * doesn't optimize echo coefficients. 2=new style (uses multi-tone and optimizes echo coefficients + * and acim setting) + * @param configfilename the path of the file that the calibration results should be written to + * @param dialstr the string that should be dialed to clear the dialtone from the line + * @param delayuntilsilence the number of seconds to wait after dialing dialstr before starting the test + * @param silencegoodfor the number of seconds that the test can run before having to reset the line again + * (this is basically the amount of time it takes before the 'if you'd like to make a call...' message + * kicks in after you dial dialstr + * + * @return 0 if successful, -1 for serious error such as device not available , > 0 indicates the number of channels + */ +static int do_calibrate(int startdev, int enddev, int calibtype, char* configfilename, char* dialstr, int delayuntilsilence, int silencegoodfor) +{ + int problems = 0; + int res = 0; + int configfd, fd; + int devno = 0; + struct wctdm_echo_coefs coefs; + + configfd = open(configfile, O_CREAT|O_TRUNC|O_WRONLY, 0666); + + if (configfd < 0) { + fprintf(stderr, "Cannot generate config file %s: open: %s\n", configfile, strerror(errno)); + return -1; + } + + for (devno = startdev; devno <= enddev; devno++) { + fd = channel_open(devno); + if (fd < 0) { + continue; + } + + fprintf(stdout, "Tuning module %d\n", devno); + + if (1 == calibtype) + res = acim_tune(fd, dialstr, delayuntilsilence, silencegoodfor, &coefs); + else + res = acim_tune2(fd, -1, dialstr, delayuntilsilence, silencegoodfor, &coefs); + + close(fd); + + if (res) { + fprintf(stdout, "Failure!\n"); + problems++; + } else { + fprintf(stdout, "Done!\n"); + } + + if (res == 0) { + + /* Do output to file */ + int len = 0; + static char output[255] = ""; + + snprintf(output, sizeof(output), "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + devno, + coefs.acim, + coefs.coef1, + coefs.coef2, + coefs.coef3, + coefs.coef4, + coefs.coef5, + coefs.coef6, + coefs.coef7, + coefs.coef8 + ); + + if (debug) + fprintf(stdout, "Found best echo coefficients: %s\n", output); + + len = strlen(output); + res = write(configfd, output, strlen(output)); + if (res != len) { + fprintf(stdout, "Unable to write line \"%s\" to file.\n", output); + return -1; + } + } + } + + close(configfd); + + if (problems) + fprintf(stdout, "Unable to tune %d devices, even though those devices are present\n", problems); + + return problems; +} + +int main(int argc , char **argv) +{ + int startdev = 1; /* -b */ + int stopdev = 252; /* -e */ + int dev_range = 0; /* false */ + int calibtype = 2; /* -t */ + int waveformtype = -1; /* -w multi-tone by default. If > 0, single tone of specified frequency */ + int delaytosilence = 0; /* -l */ + int silencegoodfor = 18; /* -m */ + char* dialstr = "5"; /* -n */ + int res = 0; + int doset = 0; /* -s */ + int docalibrate = 0; /* -i */ + int dodump = 0; /* -d */ + int i = 0; + int moreargs; + + for (i = 1; i < argc; i++){ + if (!(argv[i][0] == '-' || argv[i][0] == '/') || (strlen(argv[i]) <= 1)){ + fprintf(stdout, "Unknown option : %s\n", argv[i]); + /* Show usage */ + fputs(usage, stdout); + return -1; + } + + moreargs = (i < argc - 1); + + switch(argv[i][1]){ + case 's': + doset=1; + continue; + case 'i': + docalibrate = 1; + if (moreargs){ /* we need to check for a value after 'i' for backwards compatability with command line options of old fxotune */ + if (argv[i+1][0] != '-' && argv[i+1][0] != '/') + dialstr = argv[++i]; + } + continue; + case 'c': + configfile = moreargs ? argv[++i] : configfile; + continue; + case 'd': + dodump = 1; + continue; + case 'b': + startdev = moreargs ? atoi(argv[++i]) : startdev; + dev_range = 1; + break; + case 'e': + stopdev = moreargs ? atoi(argv[++i]) : stopdev; + dev_range = 1; + break; + case 't': + calibtype = moreargs ? atoi(argv[++i]) : calibtype; + break; + case 'w': + waveformtype = moreargs ? atoi(argv[++i]) : waveformtype; + break; + case 'l': + delaytosilence = moreargs ? atoi(argv[++i]) : delaytosilence; + break; + case 'm': + silencegoodfor = moreargs ? atoi(argv[++i]) : silencegoodfor; + break; + case 'n': + dialstr = moreargs ? argv[++i] : dialstr; + break; + case 'p': + printbest++; + break; + case 'x': + use_table = 1; + break; + case 'v': + debug = strlen(argv[i])-1; + break; + case 'o': + if (moreargs) { + audio_dump_fd = open(argv[++i], O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (audio_dump_fd == -1) { + fprintf(stdout, "Unable to open file %s: %s\n", argv[i], strerror(errno)); + return -1; + } + break; + } else { + fprintf(stdout, "No path supplied to -o option!\n"); + return -1; + } + default: + fprintf(stdout, "Unknown option : %s\n", argv[i]); + /* Show usage */ + fputs(usage, stdout); + return -1; + + } + } + + if (debug > 3){ + fprintf(stdout, "Running with parameters:\n"); + fprintf(stdout, "\tdoset=%d\n", doset); + fprintf(stdout, "\tdocalibrate=%d\n", docalibrate); + fprintf(stdout, "\tdodump=%d\n", dodump); + fprintf(stdout, "\tprint best settings=%d\n", printbest); + fprintf(stdout, "\tstartdev=%d\n", startdev); + fprintf(stdout, "\tstopdev=%d\n", stopdev); + fprintf(stdout, "\tcalibtype=%d\n", calibtype); + fprintf(stdout, "\twaveformtype=%d\n", waveformtype); + fprintf(stdout, "\tdelaytosilence=%d\n", delaytosilence); + fprintf(stdout, "\tsilencegoodfor=%d\n", silencegoodfor); + fprintf(stdout, "\tdialstr=%s\n", dialstr); + fprintf(stdout, "\tdebug=%d\n", debug); + } + + if(use_table) { + init_sinetable(); + } + + if (docalibrate){ + res = do_calibrate(startdev, stopdev, calibtype, configfile, dialstr, delaytosilence, silencegoodfor); + if (!res) + return do_set(configfile, dev_range, startdev, stopdev); + else + return -1; + } + + if (doset) + return do_set(configfile, dev_range, startdev, stopdev); + + if (dodump){ + res = do_dump(startdev, dialstr, delaytosilence, silencegoodfor, waveformtype); + if (!res) + return 0; + else + return -1; + } + + fputs(usage, stdout); + return -1; +} diff --git a/fxotune.h b/fxotune.h new file mode 100644 index 0000000..97b02e6 --- /dev/null +++ b/fxotune.h @@ -0,0 +1,119 @@ +/* + * fxotune.h -- data structures and associated definitions for fxotune.c + * + * By Matthew Fredrickson + * + * Echo coefficients and acim register values taken from AN84 from Silicon + * Laboratories app note AN84 for setting echo cancellation coefficients + * + * (C) 2005 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +struct wctdm_echo_coefs echo_trys [] = +{ + /* 600 ohm echo settings */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 0, 6, 1, 254, 2, 255, 0, 0}, + { 3, 255, 255, 0, 1, 0, 0, 0, 0}, + { 3, 1, 253, 253, 2, 255, 0, 0, 0}, + { 9, 254, 251, 255, 2, 0, 1, 0, 0}, + { 5, 3, 251, 250, 2, 254, 0, 0, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 900 ohm echo settings */ + { 1, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 252, 255, 1, 255, 0, 0, 0, 0}, + { 7, 255, 251, 251, 2, 255, 255, 1, 255}, + { 3, 1, 251, 250, 1, 254, 255, 0, 255}, + { 5, 252, 250, 0, 0, 255, 1, 0, 0}, + { 5, 3, 251, 250, 1, 253, 0, 0, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 270 ohm + (750 ohm || 150 nF) (CTR21) */ + { 2, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 0, 0, 255, 254, 0, 0, 0, 0}, + { 9, 0, 253, 254, 2, 255, 0, 0, 0}, + { 5, 1, 249, 254, 4, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 220 ohm + (820 ohm || 120 nF) (Australia/NewZealand) and 220 ohm + (820 ohm + * || 115nF) (Slovakia/SAfrica/Germany/Austria/Bulgaria) + */ + { 3, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 0, 255, 254, 255, 0, 255, 0, 0}, + { 9, 0, 253, 253, 1, 255, 0, 0, 0}, + { 5, 1, 249, 254, 3, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 251, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 370 ohm + (620ohm || 310nF) (New Zealand #2/India) CO Termination */ + { 4, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 255, 1, 4, 0, 0, 1, 255, 0}, + { 9, 0, 253, 0, 3, 254, 0, 0, 255}, + { 9, 2, 250, 253, 5, 253, 1, 0 ,255}, + { 5, 252, 250, 1, 2, 255, 0 ,255, 0}, + { 5, 3, 251, 250, 3, 254, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 320 ohm + (1050ohm || 230 nF) (England) CO Termination */ + { 5, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 0 ,255, 1, 255, 255, 0, 255, 0}, + { 5, 255, 252, 0, 2, 254, 0, 255, 255}, + { 9, 2, 250, 253, 4, 252, 0, 255, 255}, + { 5, 252, 250, 1, 1, 254, 0 ,255, 255}, + { 5, 3, 251, 250, 2, 253, 255, 255, 254}, + { 3, 1, 1, 242, 2, 9, 245, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 370 ohm + (820 ohm || 110 nF) CO Termination */ + { 6, 0, 0, 0, 0, 0, 0, 0, 0}, + { 6, 1, 254, 253, 0, 255, 0, 0, 0}, + { 9, 0, 251, 252, 2, 255, 0, 0, 0}, + { 5, 1, 248, 252, 4, 253, 1, 0, 0}, + { 5, 252, 250, 0, 0, 254, 0 , 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 254}, + { 3, 1, 1, 242, 2, 9, 245, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* 275 ohm + (780 ohm || 115 nF) CO Termination */ + { 7, 0, 0, 0, 0, 0, 0, 0, 0}, + { 7, 255, 255, 255, 255, 0, 0, 0, 0}, + { 9, 0, 253, 254, 2, 255, 0, 0, 0}, + { 5, 1, 249, 254, 4, 253, 1, 0, 0}, + { 5, 252, 250, 1, 1, 254, 0, 255, 0}, + { 5, 3, 251, 250, 2, 253, 255, 255, 255}, + { 8, 253, 2, 244, 255, 10, 244, 3, 253}, + { 10, 249, 244, 8, 12, 245, 252, 0, 1}, + + /* Make sure we include the rest of the impedances */ + { 8, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9, 0, 0, 0, 0, 0, 0, 0, 0}, + { 10, 0, 0, 0, 0, 0, 0, 0, 0}, + { 11, 0, 0, 0, 0, 0, 0, 0, 0}, + { 12, 0, 0, 0, 0, 0, 0, 0, 0}, + { 13, 0, 0, 0, 0, 0, 0, 0, 0}, + { 14, 0, 0, 0, 0, 0, 0, 0, 0}, + { 15, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + diff --git a/fxstest.c b/fxstest.c new file mode 100644 index 0000000..94709c6 --- /dev/null +++ b/fxstest.c @@ -0,0 +1,373 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tonezone.h" +#include "dahdi_tools_version.h" + +static int tones[] = { + DAHDI_TONE_DIALTONE, + DAHDI_TONE_BUSY, + DAHDI_TONE_RINGTONE, + DAHDI_TONE_CONGESTION, + DAHDI_TONE_DIALRECALL, +}; + +struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */ + +/* Use to translate a DTMF character to the value required by the dahdi call */ +static int digit_to_dtmfindex(char digit) +{ + if (isdigit(digit)) + return DAHDI_TONE_DTMF_BASE + (digit - '0'); + else if (digit >= 'A' && digit <= 'D') + return DAHDI_TONE_DTMF_A + (digit - 'A'); + else if (digit >= 'a' && digit <= 'd') + return DAHDI_TONE_DTMF_A + (digit - 'a'); + else if (digit == '*') + return DAHDI_TONE_DTMF_s; + else if (digit == '#') + return DAHDI_TONE_DTMF_p; + else + return -1; +} + +/* Place a channel into ringing mode */ +static int dahdi_ring_phone(int fd) +{ + int x; + int res; + /* Make sure our transmit state is on hook */ + x = 0; + x = DAHDI_ONHOOK; + res = ioctl(fd, DAHDI_HOOK, &x); + do { + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + if (res) { + switch (errno) { + case EBUSY: + case EINTR: + /* Wait just in case */ + fprintf(stderr, "Ring phone is busy:%s\n", strerror(errno)); + usleep(10000); + continue; + case EINPROGRESS: + fprintf(stderr, "Ring In Progress:%s\n", strerror(errno)); + res = 0; + break; + default: + fprintf(stderr, "Couldn't ring the phone: %s\n", strerror(errno)); + res = 0; + } + } else { + fprintf(stderr, "Phone is ringing\n"); + } + } while (res); + return res; +} + +int channel_open(const char *name) +{ + int channo, fd; + struct stat filestat; + const char *DEVICE = "/dev/dahdi/channel"; + + /* stat file, if character device, open it */ + channo = strtoul(name, NULL, 10); + fd = stat(name, &filestat); + if (!fd && S_ISCHR(filestat.st_mode)) { + fd = open(name, O_RDWR, 0600); + if (fd < 0) { + perror(name); + return -1; + } + /* try out the dahdi_specify interface */ + } else if (channo > 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res; + int x; + if (argc < 3) { + fprintf(stderr, "Usage: fxstest \n" + " where cmd is one of:\n" + " stats - reports voltages\n" + " regdump - dumps ProSLIC registers\n" + " tones - plays a series of tones\n" + " polarity - tests polarity reversal\n" + " ring - rings phone\n" + " vmwi - toggles VMWI LED lamp\n" + " hvdc - toggles VMWI HV lamp\n" + " neon - toggles VMWI NEON lamp\n" + " dtmf []- Send a sequence of dtmf tones (\"-\" denotes no tone)\n" + " dtmfcid - create a dtmf cid spill without polarity reversal\n"); + exit(1); + } + fd = channel_open(argv[1]); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); + exit(1); + } + + if ( !strcasecmp(argv[2], "neon") || !strcasecmp(argv[2], "vmwi") || !strcasecmp(argv[2], "hvdc")) { + fprintf(stderr, "Twiddling %s ...\n", argv[2]); + + if ( !strcasecmp(argv[2], "vmwi") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_LREV; + } else if ( !strcasecmp(argv[2], "neon") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_HVAC; + } else if ( !strcasecmp(argv[2], "hvdc") ) { + mwisend_setting.vmwi_type = DAHDI_VMWI_HVDC; + } + res = ioctl(fd, DAHDI_VMWI_CONFIG, &mwisend_setting); + + x = 1; + res = ioctl(fd, DAHDI_VMWI, &x); + if (res) { + fprintf(stderr, "Unable to set %s ...\n", argv[2]); + } else { + fprintf(stderr, "Set 1 Voice Message...\n"); + + sleep(5); + x = 2; + ioctl(fd, DAHDI_VMWI, &x); + fprintf(stderr, "Set 2 Voice Messages...\n"); + + sleep(5); + x = 0; + ioctl(fd, DAHDI_VMWI, &x); + fprintf(stderr, "Set No Voice messages...\n"); + sleep(2); + mwisend_setting.vmwi_type = 0; + } + } else if (!strcasecmp(argv[2], "ring")) { + fprintf(stderr, "Ringing phone...\n"); + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + if (res) { + fprintf(stderr, "Unable to ring phone...\n"); + } else { + fprintf(stderr, "Phone is ringing...\n"); + sleep(2); + } + } else if (!strcasecmp(argv[2], "polarity")) { + fprintf(stderr, "Twiddling polarity...\n"); + /* Insure that the channel is in active mode */ + x = DAHDI_RING; + res = ioctl(fd, DAHDI_HOOK, &x); + usleep(100000); + x = 0; + res = ioctl(fd, DAHDI_HOOK, &x); + + x = 0; + res = ioctl(fd, DAHDI_SETPOLARITY, &x); + if (res) { + fprintf(stderr, "Unable to polarity...\n"); + } else { + fprintf(stderr, "Polarity is forward...\n"); + sleep(2); + x = 1; + ioctl(fd, DAHDI_SETPOLARITY, &x); + fprintf(stderr, "Polarity is reversed...\n"); + sleep(5); + x = 0; + ioctl(fd, DAHDI_SETPOLARITY, &x); + fprintf(stderr, "Polarity is forward...\n"); + sleep(2); + } + } else if (!strcasecmp(argv[2], "tones")) { + int x = 0; + for (;;) { + res = tone_zone_play_tone(fd, tones[x]); + if (res) + fprintf(stderr, "Unable to play tone %d\n", tones[x]); + sleep(3); + x=(x+1) % (sizeof(tones) / sizeof(tones[0])); + } + } else if (!strcasecmp(argv[2], "stats")) { + struct wctdm_stats stats; + res = ioctl(fd, WCTDM_GET_STATS, &stats); + if (res) { + fprintf(stderr, "Unable to get stats on channel %s\n", argv[1]); + } else { + printf("TIP: %7.4f Volts\n", (float)stats.tipvolt / 1000.0); + printf("RING: %7.4f Volts\n", (float)stats.ringvolt / 1000.0); + printf("VBAT: %7.4f Volts\n", (float)stats.batvolt / 1000.0); + } + } else if (!strcasecmp(argv[2], "regdump")) { + struct wctdm_regs regs; + int numregs = NUM_REGS; + memset(®s, 0, sizeof(regs)); + res = ioctl(fd, WCTDM_GET_REGS, ®s); + if (res) { + fprintf(stderr, "Unable to get registers on channel %s\n", argv[1]); + } else { + for (x=60;x= 5) { + sscanf(argv[4], "%30i", &duration); + } + printf("Going to send a set of DTMF tones >%s<\n", outstring); + printf("Using a duration of %d mS per tone\n", duration); + /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ + x = DAHDI_FLUSH_BOTH; + res = ioctl(fd, DAHDI_FLUSH, &x); + x = 500 + strlen(outstring) * duration; + ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); + + for (x = 0; '\0' != outstring[x]; x++) { + dtmftone = digit_to_dtmfindex(outstring[x]); + if (0 > dtmftone) { + dtmftone = -1; + } + res = tone_zone_play_tone(fd, dtmftone); + if (res) { + fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); + } + usleep(duration * 1000); + } + } + } else if (!strcasecmp(argv[2], "dtmfcid")) { + char * outstring = "A5551212C"; /* Default string using A and C tones to bracket the number */ + int dtmftone; + + if(argc >= 4) { /* Use user supplied string */ + outstring = argv[3]; + } + printf("Going to send a set of DTMF tones >%s<\n", outstring); + /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ + x = DAHDI_FLUSH_BOTH; + res = ioctl(fd, DAHDI_FLUSH, &x); + x = 500 + strlen(outstring) * 100; + ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); + + /* Play the DTMF tones at a 50 mS on and 50 mS off rate which is standard for DTMF CID spills */ + for (x = 0; '\0' != outstring[x]; x++) { + + dtmftone = digit_to_dtmfindex(outstring[x]); + if (0 > dtmftone) { + dtmftone = -1; + } + res = tone_zone_play_tone(fd, dtmftone); + if (res) { + fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); + } + usleep(50000); + tone_zone_play_tone(fd, -1); + usleep(50000); + } + /* Wait for 150 mS from end of last tone to initiating the ring */ + usleep(100000); + dahdi_ring_phone(fd); + sleep(10); + printf("Ringing Done\n"); + } else + fprintf(stderr, "Invalid command\n"); + close(fd); + return 0; +} diff --git a/hdlcgen.c b/hdlcgen.c new file mode 100644 index 0000000..29811bb --- /dev/null +++ b/hdlcgen.c @@ -0,0 +1,135 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "dahdi_tools_version.h" + +#define RANDOM "/dev/urandom" /* Not genuinely random */ +/* #define RANDOM "/dev/random" */ /* Quite genuinely random */ + +int myread(int fd, char *buf, int len) +{ + int sofar; + int res; + sofar = 0; + while(sofar < len) { + res = read(fd, buf + sofar, len - sofar); + if (res < 0) + return res; + sofar += res; + } + return sofar; +} + +int main(int argc, char *argv[]) +{ + unsigned char buf[1024]; + unsigned char outbuf[2048]; + int res; + int randin; + int randout; + int hdlcout; + int cnt; + int hdlccnt; + int x; + int flags; + struct fasthdlc_state transmitter; + + fasthdlc_precalc(); + + fasthdlc_init(&transmitter, FASTHDLC_MODE_64); + + randin = open(RANDOM, O_RDONLY); + if (randin < 0) { + fprintf(stderr, "Unable to open %s: %s\n", RANDOM, strerror(errno)); + exit(1); + } + randout = open("random.raw", O_WRONLY|O_TRUNC|O_CREAT, 0666); + if (randout < 0) { + fprintf(stderr, "Unable to open random.raw: %s\n", strerror(errno)); + exit(1); + } + hdlcout = open("random.hdlc", O_WRONLY|O_TRUNC|O_CREAT, 0666); + if (hdlcout < 0) { + fprintf(stderr, "Unable to open random.hdlc: %s\n", strerror(errno)); + exit(1); + } + for (;;) { + cnt = (rand() % 256) + 4; /* Read a pseudo-random amount of stuff */ + res = myread(randin, buf, cnt); + if (res != cnt) { + fprintf(stderr, "Tried to read %d bytes, but read %d instead\n", cnt, res); + exit(1); + } + res = write(randout, buf, cnt); + if (res != cnt) { + fprintf(stderr, "Tried to write %d bytes, but wrote %d instead\n", cnt, res); + exit(1); + } + /* HDLC encode */ + hdlccnt = 0; + /* Start with a flag */ + fasthdlc_tx_frame(&transmitter); + if (transmitter.bits >= 8) + outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); + for (x=0;x= 8) { + outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); + } + } + flags = (rand() % 4); + for (x=0;x 1) + printf("Encoded %d byte message with %d bytes of HDLC and %d extra flags\n", cnt, hdlccnt, flags); + res = write(hdlcout, outbuf, hdlccnt); + if (res != hdlccnt) { + fprintf(stderr, "Tried to write %d HDLC bytes, but wrote %d instead\n", cnt, res); + exit(1); + } + + } +} diff --git a/hdlcstress.c b/hdlcstress.c new file mode 100644 index 0000000..6704f1f --- /dev/null +++ b/hdlcstress.c @@ -0,0 +1,233 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "bittest.h" + + +#include "dahdi_tools_version.h" + +/* #define BLOCK_SIZE 2048 */ +#define BLOCK_SIZE 2041 + +static int hdlcmode = 0; +static int bri_delay = 0; + + +static unsigned short fcstab[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + } + fcs ^= 0xffff; + if (fasthdlc_tx_load(&fs, (fcs & 0xff))) + fprintf(stderr, "Load error (fcs1)\n"); + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fasthdlc_tx_load(&fs, ((fcs >> 8) & 0xff))) + fprintf(stderr, "Load error (fcs2)\n"); + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fasthdlc_tx_frame(&fs)) + fprintf(stderr, "Frame error\n"); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + if (fs.bits > 7) + outbuf[pos++] = fasthdlc_tx_run(&fs); + write(fd, outbuf, pos); + } +} + +int main(int argc, char *argv[]) +{ + int res, ch, x; + struct dahdi_params tp; + struct dahdi_bufferinfo bi; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + + while((ch = getopt(argc, argv, "b")) != -1) { + switch(ch) { + case 'b': bri_delay = 300000; break; + case '?': exit(1); + } + } + + if (argc - optind != 1) { + fprintf(stderr, "Usage: %s [-b] \n", argv[0]); + exit(1); + } + fd = open(argv[optind], O_RDWR, 0600); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[optind], strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { + fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + exit(1); + } + if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { + printf("In HDLC mode\n"); + hdlcmode = 1; + } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { + printf("In CLEAR mode\n"); + hdlcmode = 0; + } else { + fprintf(stderr, "Not in a reasonable mode\n"); + exit(1); + } + res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); + if (!res) { + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 4; + res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); + if (res < 0) { + fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); + exit(1); + } + } else { + fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); + exit(1); + } + ioctl(fd, DAHDI_GETEVENT); + fasthdlc_precalc(); + fasthdlc_init(&fs, FASTHDLC_MODE_64); +#if 0 + print_packet(outbuf, res); + printf("FCS is %x, PPP_GOODFCS is %x\n", + fcs,PPP_GOODFCS); +#endif + for(;;) { + if (c < 1) + c = 1; + for (x=0;x<50;x++) { + outbuf[x] = c; + } + send_packet(outbuf, 50); +#if 0 + printf("Wrote %d of %d bytes\n", res, c); +#endif + /* The HFC chip can't be bombarded too much. If a write has + failed, let it recover */ + if (bri_delay) + usleep(bri_delay); + + c = bit_next(c); +#if 0 + printf("(%d) Wrote %d bytes\n", packets++, res); +#endif + } + +} diff --git a/hdlctest.c b/hdlctest.c new file mode 100644 index 0000000..7358fc1 --- /dev/null +++ b/hdlctest.c @@ -0,0 +1,302 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "bittest.h" + +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 + +static unsigned short fcstab[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x = 0; x < len; x++) { + printf("%02x ", buf[x]); + } + printf("}\n"); +} + +static int bytes; +static int errors; +static int c; + +void dump_bits(unsigned char *outbuf, int len) +{ + int x, i; + for (x = 0; x < len; x++) { + for (i = 0; i < 8; i++) { + if (outbuf[x] & (1 << (7 - i))) { + printf("1"); + } else { + printf("0"); + } + } + } + printf("\n"); +} + +void dump_bitslong(unsigned int outbuf, int bits) +{ + int i; + printf("Dumping %d bits from %04x\n", bits, outbuf); + for (i = 0; i < bits; i++) { + if (outbuf & (1 << (31 - i))) { + printf("1"); + } else { + printf("0"); + } + } + printf("\n"); +} + +int check_frame(unsigned char *outbuf, int res) +{ + static int setup = 0; + int x; + unsigned short fcs = PPP_INITFCS; + if (c < 1) { + c = 1; + } + if (!setup) { + c = outbuf[0]; + setup++; + } + for (x = 0; x < res; x++) { + if (outbuf[x] != c && (x < res - 2)) { + printf("(Error %d): Unexpected result, %d != %d, position %d %d bytes since last error.\n", + ++errors, outbuf[x], c, x, bytes); + if (!x) { + c = outbuf[0]; + } + bytes = 0; + } else { + bytes++; + } + fcs = PPP_FCS(fcs, outbuf[x]); + } + if (fcs != PPP_GOODFCS) { + printf("FCS Check failed :( (%04x != %04x)\n", fcs, PPP_GOODFCS); + } +#if 0 + if (res != c) { + printf("Res is %d, expected %d\n", res, c+2); + } +#endif + c = bit_next(c); + return 0; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + struct dahdi_params tp; + struct dahdi_bufferinfo bi; + int bs = BLOCK_SIZE; + int pos = 0; + unsigned char inbuf[BLOCK_SIZE]; + unsigned char outbuf[BLOCK_SIZE]; + int bytes = 0; + int out; + unsigned int olddata1; + int oldones1; + int oldbits1; + unsigned int olddata = 0; + int oldones = 0; + int oldbits = 0; + int hdlcmode = 0; + struct fasthdlc_state fs; + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + fd = open(argv[1], O_RDWR, 0600); + if (fd < 0) { + fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { + fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); + exit(1); + } + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + exit(1); + } + if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { + printf("In HDLC mode\n"); + hdlcmode = 1; + } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { + printf("In CLEAR mode\n"); + hdlcmode = 0; + } else { + fprintf(stderr, "Not in a reasonable mode\n"); + exit(1); + } + res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); + if (!res) { + bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + bi.numbufs = 4; + res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); + if (res < 0) { + fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); + exit(1); + } + } else { + fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); + exit(1); + } + ioctl(fd, DAHDI_GETEVENT); + fasthdlc_precalc(); + fasthdlc_init(&fs, FASTHDLC_MODE_64); + for (;;) { + res = read(fd, outbuf, sizeof(outbuf)); + if (hdlcmode) { + if (res < 0) { + if (errno == ELAST) { + if (ioctl(fd, DAHDI_GETEVENT, &x) < 0) { + fprintf(stderr, "Unaable to get event: %s\n", strerror(errno)); + exit(1); + } + fprintf(stderr, "Event: %d (%d bytes since last error)\n", x, bytes); + bytes = 0; + continue; + } else { + fprintf(stderr, "Error: %s\n", strerror(errno)); + exit(1); + } + } +#if 0 + printf("Res is %d, buf0 is %d, buf1 is %d\n", res, outbuf[0], outbuf[1]); +#endif + if (res < 2) { + fprintf(stderr, "Too small? Only got %d bytes\n", res); + } + check_frame(outbuf, res); + } else { + for (x = 0; x < res; x++) { + oldones1 = oldones; + oldbits1 = oldbits; + olddata1 = olddata; + oldones = fs.ones; + oldbits = fs.bits; + olddata = fs.data; + fasthdlc_rx_load(&fs, outbuf[x]); + out = fasthdlc_rx_run(&fs); + if (out & RETURN_EMPTY_FLAG) { + /* Empty */ + } else if (out & RETURN_COMPLETE_FLAG) { + if (pos && (pos < 2)) { + printf("Too short? (%d)\n", pos); + } else if (pos) { + check_frame(inbuf, pos); + } + pos = 0; + } else if (out & RETURN_DISCARD_FLAG) { + printf("Discard (search = %d, len = %d, buf = %d, x=%d, res=%d, oldones: %d, oldbits: %d)\n", + c, pos, inbuf[0], x, res, oldones, oldbits); + dump_bitslong(olddata, oldbits); + printf("Discard oldones: %d, oldbits: %d)\n", + oldones1, oldbits1); + dump_bitslong(olddata1, oldbits1); + if (x > 64) { + dump_bits(outbuf + x - 64, 64); + dump_bits(outbuf + x, 64); + } + pos = 0; + } else { + if ((out != c) && (pos < c) && !pos) { + printf("Warning: Expecting %d at pos %d, got %d (x =%d)\n", c, pos, out, x); + if (x > 64) { + dump_bits(outbuf + x - 64, 64); + dump_bits(outbuf + x, 64); + } + } + inbuf[pos++] = out; + } + } + } + } + +} diff --git a/hdlcverify.c b/hdlcverify.c new file mode 100644 index 0000000..a7401fe --- /dev/null +++ b/hdlcverify.c @@ -0,0 +1,136 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define FAST_HDLC_NEED_TABLES +#include + +#include "dahdi_tools_version.h" + +int myread(int fd, unsigned char *buf, int len) +{ + int sofar; + int res; + sofar = 0; + while(sofar < len) { + res = read(fd, buf + sofar, len - sofar); + if (res < 0) + return res; + sofar += res; + } + return sofar; +} + +static inline unsigned char nextchar(int fd) +{ + static unsigned char inbuf[2048]; + static int bytes = 0; + static int pos = 0; + if (pos >= bytes) { + pos = 0; + bytes = read(fd, inbuf, sizeof(inbuf)); + if (bytes < 0) { + fprintf(stderr, "Unable to read more data: %s\n", strerror(errno)); + exit(1); + } + if (bytes == 0) { + fprintf(stderr, "-- END OF DATA --\n"); + exit(0); + } + } + return inbuf[pos++]; +} + +int main(int argc, char *argv[]) +{ + unsigned char decbuf[1024]; + unsigned char actual[1024]; + int res; + int datain; + int hdlcin; + int hdlccnt; + int x; + struct fasthdlc_state receiver; + + fasthdlc_precalc(); + + fasthdlc_init(&receiver, FASTHDLC_MODE_64); + + hdlcin = open("random.hdlc", O_RDONLY); + if (hdlcin < 0) { + fprintf(stderr, "Unable to open %s: %s\n", "random.hdlc", strerror(errno)); + exit(1); + } + datain = open("random.raw", O_RDONLY); + if (datain < 0) { + fprintf(stderr, "Unable to open random.raw: %s\n", strerror(errno)); + exit(1); + } + hdlccnt = 0; + for (;;) { + /* Feed in some input */ + if (fasthdlc_rx_load(&receiver, nextchar(hdlcin))) { + fprintf(stderr, "Unable to feed receiver :(\n"); + exit(1); + } + res = fasthdlc_rx_run(&receiver); + if (res & RETURN_EMPTY_FLAG) + continue; + if (res & RETURN_COMPLETE_FLAG) { + if (hdlccnt) { + if (argc > 1) + printf("Got message of length %d\n", hdlccnt); + res = myread(datain, actual, hdlccnt); + if (res != hdlccnt) { + fprintf(stderr, "Tried to read %d bytes, but read %d instead\n", hdlccnt, res); + exit(1); + } + for (x=0;x/dev/null | \ + sed 's,/registration_time:,\t,' | \ + sort -k 2,2 +} + +# First assign non-Astribank devices +devices_by_registration_time | \ + grep -v '/astribanks:' | \ + while read devpath time; do + echo >&2 "D: auto '$devpath'" + dahdi_span_assignments auto "$devpath" + done + +# Now handle Astribanks +LC_ALL=C dahdi_registration -Rv on diff --git a/hotplug/dahdi_handle_device b/hotplug/dahdi_handle_device new file mode 100755 index 0000000..30329bd --- /dev/null +++ b/hotplug/dahdi_handle_device @@ -0,0 +1,87 @@ +#! /bin/sh +# +# /usr/share/dahdi/dahdi_handle_device +# +# Called by UDEV when a dahdi device is added/removed +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" +NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +exec 2> /dev/null +# If you wish to trace this script: +#exec 2> "/tmp/${me}.$NAME" 1>&2 +#exec 2> /dev/console + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" +export PATH + +set -e + +#echo >&2 "$0($ACTION): DEBUG($# args): '$*'" + +# Do we have a configuration? +if [ -f /etc/dahdi/init.conf ]; then + . /etc/dahdi/init.conf +fi + +if [ "$DAHDI_UDEV_DISABLE_DEVICES" = 'yes' ]; then + echo "DAHDI_UDEV_DISABLE_DEVICES=yes. Skip $DEVPATH" | $LOGGER + exit 0 +fi + +# Can we pass a different value so we can use +# alternate (testing) configuration? +# Meanwhile, make it hard-coded. +DAHDICONFDIR='/etc/dahdi' +export DAHDICONFDIR + +run_parts() { + # Have our internal "run-parts" (adapted from Fedora), + # as implementations differ + for i in `LC_ALL=C; ls -d $dir/handle_device.d/*[!~,] 2>/dev/null` ; do + [ -d "$i" ] && continue + [ ! -x "$i" ] && continue + # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files + case "$i" in + *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) + continue + ;; + esac + echo "D: Running '$i'" + "$i" + done +} + +case "$ACTION" in +add) + echo "$ACTION: $DEVPATH" | $LOGGER + + # Check if we can safely do our job + if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then + echo "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" | $LOGGER + exit 0 + fi + if [ `cat /sys/module/dahdi/parameters/auto_assign_spans` -ne 0 ]; then + echo "auto_assign_spans=1. Skip $DEVPATH" | $LOGGER + exit 0 + fi + + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +remove) + echo "$ACTION: $DEVPATH" | $LOGGER + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +*) + echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER + ;; +esac diff --git a/hotplug/dahdi_span_config b/hotplug/dahdi_span_config new file mode 100755 index 0000000..25a10e2 --- /dev/null +++ b/hotplug/dahdi_span_config @@ -0,0 +1,97 @@ +#! /bin/sh +# +# /usr/share/dahdi/dahdi_span_config +# +# Called by UDEV when a dahdi span is added/removed +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" +NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` + +exec 2> /dev/null +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}.$NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" +export PATH + +set -e + +#echo >&2 "$0($ACTION): DEBUG($# args): '$*'" + +# Do we have a configuration? +if [ -f /etc/dahdi/init.conf ]; then + . /etc/dahdi/init.conf +fi + +if [ "$DAHDI_UDEV_DISABLE_SPANS" = 'yes' ]; then + echo "DAHDI_UDEV_DISABLE_SPANS=yes. Skip $DEVPATH" | $LOGGER + exit 0 +fi + +# Can we pass a different value so we can use +# alternate (testing) configuration? +# Meanwhile, make it hard-coded. +DAHDICONFDIR='/etc/dahdi' +export DAHDICONFDIR + +run_parts() { + # Have our internal "run-parts" (adapted from Fedora), + # as implementations differ + for i in `LC_ALL=C; ls -d $dir/span_config.d/*[!~,] 2>/dev/null` ; do + [ -d "$i" ] && continue + [ ! -x "$i" ] && continue + # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files + case "$i" in + *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) + continue + ;; + esac + #echo "D: Running '$i'" + "$i" + done +} + +case "$ACTION" in +add) + echo "$ACTION: $DEVPATH" | $LOGGER + + # Old driver. These scripts probably won't work anyway. + if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then + if [ -f /sys/module/dahdi ]; then + $LOGGER "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" + exit 0 + fi + fi + + if [ $(cat /sys/module/dahdi/parameters/auto_assign_spans) -ne 0 ]; then + $LOGGER "auto_assign_spans=1. Skip $DEVPATH" + exit 0 + fi + + # Set variables + span_devpath="/sys$DEVPATH" + SPANNO=`echo "$span_devpath" | sed 's,.*/span-,,'` + BASECHAN=`cat "$span_devpath/basechan"` + CHANNELS=`cat "$span_devpath/channels"` + ENDCHAN=`expr "$BASECHAN" + "$CHANNELS" - 1` + export SPANNO BASECHAN CHANNELS ENDCHAN + # Background run -- don't block udev + run_parts 2>&1 < /dev/null | $LOGGER & + ;; +remove|online|offline) + # Nothing to do yet... + echo "$ACTION: $DEVPATH" | $LOGGER + ;; +*) + echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER + ;; +esac + diff --git a/hotplug/handle_device.d/10-span-types b/hotplug/handle_device.d/10-span-types new file mode 100755 index 0000000..6b78021 --- /dev/null +++ b/hotplug/handle_device.d/10-span-types @@ -0,0 +1,12 @@ +#! /bin/sh + +case "$ACTION" in +add) + ;; +*) + exit 0 +esac + +if [ -r "$DAHDICONFDIR/span-types.conf" ]; then + dahdi_span_types set "/sys$DEVPATH" +fi diff --git a/hotplug/handle_device.d/20-span-assignments b/hotplug/handle_device.d/20-span-assignments new file mode 100755 index 0000000..5493232 --- /dev/null +++ b/hotplug/handle_device.d/20-span-assignments @@ -0,0 +1,15 @@ +#! /bin/sh + +case "$ACTION" in +add) + ;; +*) + exit 0 +esac + +# For now, handle only spans in assigned-spans.conf +# We leave other cases to /etc/init.d/dahdi, so +# legacy ordering can be preserved. +if [ -r "$DAHDICONFDIR/assigned-spans.conf" ]; then + dahdi_span_assignments add "/sys$DEVPATH" +fi diff --git a/hotplug/span_config.d/10-dahdi-cfg b/hotplug/span_config.d/10-dahdi-cfg new file mode 100755 index 0000000..9ca2efe --- /dev/null +++ b/hotplug/span_config.d/10-dahdi-cfg @@ -0,0 +1,28 @@ +#! /bin/sh + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +# Sanity check +checkit=`"dahdi_cfg" --help 2>&1 | grep -- '-S' | wc -l` +if [ "$checkit" != 1 ]; then + echo "Bad dahdi_cfg (no -S support). Skipping" + exit 0 +fi + +run_dahdi_cfg() { + echo "dahdi_cfg: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" + dahdi_cfg -c "$cfg_file" -S "$SPANNO" -C "$BASECHAN-$ENDCHAN" +} + +# Configure DAHDI +cfg_file="$DAHDICONFDIR/system.conf" +if [ -r "$cfg_file" ]; then + run_dahdi_cfg +else + echo "Using auto-generated config for dahdi_cfg" + cfg_file='-' + DAHDI_CONF_FILE="$cfg_file" dahdi_genconf system | run_dahdi_cfg +fi diff --git a/hotplug/span_config.d/20-fxotune b/hotplug/span_config.d/20-fxotune new file mode 100755 index 0000000..199c82c --- /dev/null +++ b/hotplug/span_config.d/20-fxotune @@ -0,0 +1,12 @@ +#! /bin/sh + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +fxotune_cfg='/etc/fxotune.conf' +if [ -r "$fxotune_cfg" ]; then + echo "fxotune: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" + fxotune -s -b "$BASECHAN" -e "$ENDCHAN" +fi diff --git a/hotplug/span_config.d/50-asterisk b/hotplug/span_config.d/50-asterisk new file mode 100755 index 0000000..3b75899 --- /dev/null +++ b/hotplug/span_config.d/50-asterisk @@ -0,0 +1,14 @@ +#! /bin/sh + +# This file, if installed under /usr/share/dahdi/span_config.d/ , will +# attempt to add a newly-generated span to a running copy of Asterisk. +# Asterisk has to be running (if not: it will pick the span on its +# startup), and has to have the channels already configured. + +if [ "$ACTION" != 'add' ]; then + # Nothing to do here + exit 0 +fi + +# Add to asterisk +asterisk -rx "dahdi create channels $BASECHAN $ENDCHAN" diff --git a/ifup-hdlc b/ifup-hdlc new file mode 100644 index 0000000..6602c46 --- /dev/null +++ b/ifup-hdlc @@ -0,0 +1,39 @@ +#!/bin/sh +PATH=/sbin:/usr/sbin:/bin:/usr/bin + +cd /etc/sysconfig/network-scripts +. network-functions + +CONFIG=$1 +source_config + +if [ "foo$2" = "fooboot" -a "${ONBOOT}" = "no" ] +then + exit +fi + +if [ -z "${MODE}" ]; then + echo "No mode specified!" + exit +fi + +sethdlc ${DEVICE} mode ${MODE} +ifconfig ${DEVICE} ${IPADDR} pointopoint ${REMIP} +route add -net ${NETWORK} netmask ${NETMASK} ${DEVICE} + +# this is broken! it's only here to keep compatibility with old RH sytstems +if [ "${GATEWAY}" != "" -a "${GATEWAY}" != "none" ] +then + route add default gw ${GATEWAY} metric 1 ${DEVICE} +fi + +. /etc/sysconfig/network + +if [ "${GATEWAY}" != "" ]; then + if [ "${GATEWAYDEV}" = "" -o "${GATEWAYDEV}" = "${DEVICE}" ]; then + # set up default gateway + route add default gw ${GATEWAY} + fi +fi + +/etc/sysconfig/network-scripts/ifup-post $1 diff --git a/init.conf.sample b/init.conf.sample new file mode 100644 index 0000000..6bbb199 --- /dev/null +++ b/init.conf.sample @@ -0,0 +1,24 @@ +# +# Shell settings for Dahdi initialization scripts. +# This replaces the old/per-platform files (/etc/sysconfig/zaptel, +# /etc/defaults/zaptel) +# + +# The maximal timeout (seconds) to wait for udevd to finish generating +# device nodes after the modules have loaded and before running dahdi_cfg. +#DAHDI_DEV_TIMEOUT=40 + +# A list of modules to unload when stopping. +# All of their dependencies will be unloaded as well. +#DAHDI_UNLOAD_MODULES="" # Disable module unloading +#DAHDI_UNLOAD_MODULES="dahdi echo" # If you use OSLEC + +# Override settings for xpp_fxloader +#XPP_FIRMWARE_DIR=/usr/share/dahdi +#XPP_HOTPLUG_DISABLED=yes +#XPP_HOTPLUG_DAHDI=yes +#ASTERISK_SUPPORTS_DAHDI_HOTPLUG=yes + +# Disable udev handling: +#DAHDI_UDEV_DISABLE_DEVICES=yes +#DAHDI_UDEV_DISABLE_SPANS=yes diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/makeopts.in b/makeopts.in new file mode 100644 index 0000000..a892a76 --- /dev/null +++ b/makeopts.in @@ -0,0 +1,49 @@ +CC=@CC@ +LD=@LD@ +HOSTCC=@HOSTCC@ +CFLAGS=@CFLAGS@ +LDFLAGS=@LDFLAGS@ + +INSTALL=@INSTALL@ +GREP=@GREP@ +SHELL=@SHELL@ +LN=@LN@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +includedir = @includedir@ +infodir = @infodir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ + +DOWNLOAD=@DOWNLOAD@ + +DAHDI_DEVMODE=@DAHDI_DEVMODE@ +DAHDI_DECLARATION_AFTER_STATEMENT=@DAHDI_DECLARATION_AFTER_STATEMENT@ + +PBX_NEWT=@PBX_NEWT@ +NEWT_LIB=@NEWT_LIB@ +NEWT_INCLUDE=@NEWT_INCLUDE@ + +PBX_USB=@PBX_USB@ +USB_LIB=@USB_LIB@ +USB_INCLUDE=@USB_INCLUDE@ + +PBX_HDLC=@PBX_HDLC@ + +DAHDI_INCLUDE=@DAHDI_INCLUDE@ + +USE_SELINUX=@USE_SELINUX@ + +PPPD_VERSION=@PPPD_VERSION@ + +ASCIIDOC=@ASCIIDOC@ diff --git a/modprobe.conf.sample b/modprobe.conf.sample new file mode 100644 index 0000000..1570d00 --- /dev/null +++ b/modprobe.conf.sample @@ -0,0 +1,4 @@ +# You should place any module parameters for your DAHDI modules here +# Example: +# +# options wctdm24xxp latency=6 diff --git a/modules.sample b/modules.sample new file mode 100644 index 0000000..08692af --- /dev/null +++ b/modules.sample @@ -0,0 +1,63 @@ +# Contains the list of modules to be loaded / unloaded by /etc/init.d/dahdi. +# +# NOTE: Please add/edit /etc/modprobe.d/dahdi or /etc/modprobe.conf if you +# would like to add any module parameters. +# +# Format of this file: list of modules, each in its own line. +# Anything after a '#' is ignore, likewise trailing and leading +# whitespaces and empty lines. + +# Digium TE205P/TE207P/TE210P/TE212P: PCI dual-port T1/E1/J1 +# Digium TE405P/TE407P/TE410P/TE412P: PCI quad-port T1/E1/J1 +# Digium TE220: PCI-Express dual-port T1/E1/J1 +# Digium TE420: PCI-Express quad-port T1/E1/J1 +wct4xxp + +# Digium TE435 +# Digium TE235 +# Digium TE436 +# Digium TE236 +wcte43x + +# Digium TE120P: PCI single-port T1/E1/J1 +# Digium TE121: PCI-Express single-port T1/E1/J1 +# Digium TE122: PCI single-port T1/E1/J1 +wcte12xp + +# Digium TE131: PCI-Express single-port T1/E1/J1 +# Digium TE132: PCI single-port T1/E1/J1 +# Digium TE133: PCI-Express single-port T1/E1/J1 with hardware echocan +# Digium TE134: PCI single-port T1/E1/J1 with hardware echocan +wcte13xp + +# Digium T100P: PCI single-port T1 +# Digium E100P: PCI single-port E1 +wct1xxp + +# Digium TE110P: PCI single-port T1/E1/J1 +wcte11xp + +# Digium TDM2400P/AEX2400: up to 24 analog ports +# Digium TDM800P/AEX800: up to 8 analog ports +# Digium TDM410P/AEX410: up to 4 analog ports +wctdm24xxp + +# Digium A4A/A4B/A8A/A8B +wcaxx + +# X100P - Single port FXO interface +# X101P - Single port FXO interface +wcfxo + +# Digium TDM400P: up to 4 analog ports +wctdm + +# Digium B410P: 4 NT/TE BRI ports +wcb4xxp + +# Digium TC400B: G729 / G723 Transcoding Engine +wctc4xxp + +# Xorcom Astribank Devices +xpp_usb + diff --git a/patgen.c b/patgen.c new file mode 100644 index 0000000..2b619d3 --- /dev/null +++ b/patgen.c @@ -0,0 +1,175 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bittest.h" + +#include +#include "dahdi_tools_version.h" + +/* #define BLOCK_SIZE 2048 */ +#define BLOCK_SIZE 2041 +#define DEVICE "/dev/dahdi/channel" + +static const char rcsid[] = "$Id$"; +char *prog_name; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s \n", prog_name); + fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); + fprintf(stderr, " %s 455\n", prog_name); + fprintf(stderr, "%s version %s\n", prog_name, rcsid); + exit(1); +} + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, res1, x; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + + prog_name = argv[0]; + + if (argc < 2) { + usage(); + } + + fd = channel_open(argv[1], &bs); + if (fd < 0) + exit(1); + + ioctl(fd, DAHDI_GETEVENT); +#if 0 + print_packet(outbuf, res); + printf("FCS is %x, PPP_GOODFCS is %x\n", + fcs,PPP_GOODFCS); +#endif + for(;;) { + res = bs; + for (x=0;x + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/* + * This test sends a set of incrementing byte values out the specified + * dadhi device. The device is then read back and the read back characters + * are verified that they increment as well. + * If there is a break in the incrementing pattern, an error is flagged + * and the comparison starts at the last value read. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 +#define DEVICE "/dev/dahdi/channel" + +#define CONTEXT_SIZE 7 +/* Prints a set of bytes in hex format */ +static void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x= bufsize || 0 >= bufsize || 0 > offset ) { + return; + } + + low = offset - (CONTEXT_SIZE-1)/2; + if (0 > low) { + total += low; + low = 0; + } + if (low + total > bufsize) { + total = bufsize - low; + } + buf += low; + printf("Offset %d ", low); + print_packet(buf, total); + return; +} + +/* Shows how the program can be invoked */ +static void usage(const char * progname) +{ + printf("%s: Pattern loop test\n", progname); + printf("Usage: %s [-t ] [-r ] [-b ] [-vh?] \n", progname); + printf("\t-? - Print this usage summary\n"); + printf("\t-t - # of seconds for the test to run\n"); + printf("\t-r - # of test loops to run before a summary is printed\n"); + printf("\t-s - # of writes to skip before testing for results\n"); + printf("\t-v - Verbosity (repetitive v's add to the verbosity level e.g. -vvvv)\n"); + printf("\t-b <# buffer bytes> - # of bytes to display from buffers on each pass\n"); + printf("\n\t Also accepts old style usage:\n\t %s []\n", progname); +} + +int channel_open(const char *name, int *bs) +{ + int channo, fd; + struct dahdi_params tp; + struct stat filestat; + + /* stat file, if character device, open it */ + channo = strtoul(name, NULL, 10); + fd = stat(name, &filestat); + if (!fd && S_ISCHR(filestat.st_mode)) { + fd = open(name, O_RDWR, 0600); + if (fd < 0) { + perror(name); + return -1; + } + /* try out the dahdi_specify interface */ + } else if (channo > 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + int i; + int bs = BLOCK_SIZE; + int skipcount = 10; + unsigned char c=0,c1=0; + unsigned char inbuf[BLOCK_SIZE]; + unsigned char outbuf[BLOCK_SIZE]; + int setup=0; + unsigned long bytes=0; + int timeout=0; + int loop_errorcount; + int reportloops = 0; + int buff_disp = 0; + unsigned long currentloop = 0; + unsigned long total_errorcount = 0; + int verbose = 0; + char * device; + int opt; + int oldstyle_cmdline = 1; + unsigned int event_count = 0; + + /* Parse the command line arguments */ + while((opt = getopt(argc, argv, "b:s:t:r:v?h")) != -1) { + switch(opt) { + case 'h': + case '?': + usage(argv[0]); + exit(1); + break; + case 'b': + buff_disp = strtoul(optarg, NULL, 10); + if (BLOCK_SIZE < buff_disp) { + buff_disp = BLOCK_SIZE; + } + oldstyle_cmdline = 0; + break; + case 'r': + reportloops = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 's': + skipcount = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 't': + timeout = strtoul(optarg, NULL, 10); + oldstyle_cmdline = 0; + break; + case 'v': + verbose++; + oldstyle_cmdline = 0; + break; + } + } + + /* If no device was specified */ + if(NULL == argv[optind]) { + printf("You need to supply a dahdi device to test\n"); + usage(argv[0]); + exit (1); + } + + /* Get the dahdi device name */ + if (argv[optind]) + device = argv[optind]; + + /* To maintain backward compatibility with previous versions process old style command line */ + if (oldstyle_cmdline && argc > optind +1) { + timeout = strtoul(argv[optind+1], NULL, 10); + } + + time_t start_time = 0; + + fd = channel_open(device, &bs); + if (fd < 0) + exit(1); + ioctl(fd, DAHDI_GETEVENT); + + i = DAHDI_FLUSH_ALL; + if (ioctl(fd,DAHDI_FLUSH,&i) == -1) { + perror("DAHDI_FLUSH"); + exit(255); + } + + /* Mark time if program has a specified timeout */ + if(0 < timeout){ + start_time = time(NULL); + printf("Using Timeout of %d Seconds\n",timeout); + } + + /* ********* MAIN TESTING LOOP ************ */ + for(;;) { + /* Prep the data and write it out to dahdi device */ + res = bs; + for (x = 0; x < bs; x++) { + outbuf[x] = c1++; + } + +write_again: + res = write(fd,outbuf,bs); + if (res != bs) { + if (ELAST == errno) { + ioctl(fd, DAHDI_GETEVENT, &x); + if (event_count > 0) + printf("Event: %d\n", x); + ++event_count; + } else { + printf("W: Res is %d: %s\n", res, strerror(errno)); + } + goto write_again; + } + + /* If this is the start of the test then skip a number of packets before test results */ + if (skipcount) { + if (skipcount > 1) { + res = read(fd,inbuf,bs); + } + skipcount--; + if (!skipcount) { + printf("Going for it...\n"); + } + i = 1; + ioctl(fd,DAHDI_BUFFER_EVENTS, &i); + continue; + } + +read_again: + res = read(fd, inbuf, bs); + if (res < bs) { + printf("R: Res is %d\n", res); + ioctl(fd, DAHDI_GETEVENT, &x); + printf("Event: %d\n", x); + goto read_again; + } + /* If first time through, set byte that is used to test further bytes */ + if (!setup) { + c = inbuf[0]; + setup++; + } + /* Test the packet read back for data pattern */ + loop_errorcount = 0; + for (x = 0; x < bs; x++) { + /* if error */ + if (inbuf[x] != c) { + total_errorcount++; + loop_errorcount++; + if (oldstyle_cmdline) { + printf("(Error %ld): Unexpected result, %d != %d, %ld bytes since last error.\n", total_errorcount, inbuf[x],c, bytes); + } else { + if (1 <= verbose) { + printf("Error %ld (loop %ld, offset %d, error %d): Unexpected result, Read: 0x%02x, Expected 0x%02x.\n", + total_errorcount, + currentloop, + x, + loop_errorcount, + inbuf[x], + c); + } + if (2 <= verbose) { + show_error_context(inbuf, x, bs); + } + } + /* Reset the expected data to what was just read. so test can resynch on skipped data */ + c = inbuf[x]; + bytes=0; /* Reset the count from the last encountered error */ + } + c++; + bytes++; + } + /* If the user wants to see some of each buffer transaction */ + if (0 < buff_disp) { + printf("Buffer Display %d (errors =%d)\nIN: ", buff_disp, loop_errorcount); + print_packet(inbuf, 64); + printf("OUT:"); + print_packet(outbuf, 64); + } + + currentloop++; + /* Update stats if the user has specified it */ + if (0 < reportloops && 0 == (currentloop % reportloops)) { + printf("Status on loop %lu: Total errors = %lu\n", currentloop, total_errorcount); + + } +#if 0 + printf("(%d) Wrote %d bytes\n", packets++, res); +#endif + if(timeout && (time(NULL)-start_time) > timeout){ + printf("Timeout achieved Ending Program\n"); + printf("Test ran %ld loops of %d bytes/loop with %ld errors\n", currentloop, bs, total_errorcount); + return total_errorcount; + } + } + +} + diff --git a/pattest.c b/pattest.c new file mode 100644 index 0000000..09b0c8e --- /dev/null +++ b/pattest.c @@ -0,0 +1,181 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bittest.h" + +#include +#include "dahdi_tools_version.h" + +#define BLOCK_SIZE 2039 +#define DEVICE "/dev/dahdi/channel" + +static const char rcsid[] = "$Id$"; +char *prog_name; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s \n", prog_name); + fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); + fprintf(stderr, " %s 455\n", prog_name); + fprintf(stderr, "%s version %s\n", prog_name, rcsid); + exit(1); +} + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ "); + for (x=0;x 0) { + fd = open(DEVICE, O_RDWR, 0600); + if (fd < 0) { + perror(DEVICE); + return -1; + } + if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { + perror("DAHDI_SPECIFY ioctl failed"); + return -1; + } + /* die */ + } else { + fprintf(stderr, "Specified channel is not a valid character " + "device or channel number"); + return -1; + } + + if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { + perror("SET_BLOCKSIZE"); + return -1; + } + + if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { + fprintf(stderr, "Unable to get channel parameters\n"); + return -1; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + int fd; + int res, x; + int bs = BLOCK_SIZE; + unsigned char c=0; + unsigned char outbuf[BLOCK_SIZE]; + int setup=0; + int errors=0; + int bytes=0; + + prog_name = argv[0]; + + if (argc < 2) { + usage(); + } + + fd = channel_open(argv[1], &bs); + if (fd < 0) + exit(1); + + ioctl(fd, DAHDI_GETEVENT); + for(;;) { + res = bs; + res = read(fd, outbuf, res); + if (res < bs) { + int e; + struct dahdi_spaninfo zi; + res = ioctl(fd,DAHDI_GETEVENT,&e); + if (res == -1) + { + perror("DAHDI_GETEVENT"); + exit(1); + } + if (e == DAHDI_EVENT_NOALARM) + printf("ALARMS CLEARED\n"); + if (e == DAHDI_EVENT_ALARM) + { + zi.spanno = 0; + res = ioctl(fd,DAHDI_SPANSTAT,&zi); + if (res == -1) + { + perror("DAHDI_SPANSTAT"); + exit(1); + } + printf("Alarm mask %x hex\n",zi.alarms); + } + continue; + } + if (!setup) { + c = outbuf[0]; + setup++; + } + for (x=0;x + * + * Borrows from PPPoE by Michal Ostrowski , + * Jamal Hadi Salim + * + * which in turn... + * + * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., + * which is based in part on work from Jens Axboe and Paul Mackerras. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern int new_style_driver; + +const char pppd_version[] = VERSION; + +#define _PATH_DAHDI_OPT _ROOT_PATH "/etc/ppp/options." + +#define DAHDI_MTU (DAHDI_DEFAULT_MTU_MRU - 16) +extern int kill_link; +int retries = 0; + +int setdevname_dahdi(const char *cp); + +static option_t dahdi_options[] = { + { "device name", o_wild, (void *) &setdevname_dahdi, + "Serial port device name", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, + { NULL } +}; + +static int dahdi_fd = -1; +static int dahdi_chan = 0; + +static int connect_dahdi(void) +{ + + struct dahdi_params dahdi_params; + int res; + int x; + + info("DAHDI device is '%s'\n", devnam); + + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + + if (strlen(devnam) && strcmp(devnam, "stdin")) { + /* Get the channel number */ + dahdi_chan = atoi(devnam); + if (dahdi_chan < 1) { + fatal("'%s' is not a valid device name\n", devnam); + return -1; + } + + /* Open /dev/dahdi/channel interface */ + dahdi_fd = open("/dev/dahdi/channel", O_RDWR); + if (dahdi_fd < 0) { + fatal("Unable to open DAHDI channel interface: '%s'\n", strerror(errno)); + return dahdi_fd; + } + + /* Specify which channel we really want */ + x = dahdi_chan; + res = ioctl(dahdi_fd, DAHDI_SPECIFY, &x); + if (res) { + fatal("Unable to specify channel %d: %s\n", dahdi_chan, strerror(errno)); + close(dahdi_fd); + dahdi_fd = -1; + return -1; + } + } else + dahdi_fd = STDIN_FILENO; + + + /* Get channel parameters */ + memset(&dahdi_params, 0, sizeof(dahdi_params)); + dahdi_params.channo = -1; + + res = ioctl(dahdi_fd, DAHDI_GET_PARAMS, &dahdi_params); + + if (res) { + fatal("Device '%s' does not appear to be a DAHDI device\n", devnam ? devnam : ""); + } + + x = 1; + + /* Throw into HDLC/PPP mode */ + res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x); + + if (res) { + fatal("Unable to put device '%s' into HDLC mode\n", devnam); + close(dahdi_fd); + dahdi_fd = -1; + return -1; + } + + /* Once the logging is fixed, print a message here indicating + connection parameters */ + dahdi_chan = dahdi_params.channo; + info("Connected to DAHDI device '%s' (%d)\n", dahdi_params.name, dahdi_params.channo); + + return dahdi_fd; +} + +static void disconnect_dahdi(void) +{ + int res; + int x = 0; + /* Throw out of HDLC mode */ + res = ioctl(dahdi_fd, DAHDI_HDLCPPP, &x); + + if (res) { + warn("Unable to take device '%s' out of HDLC mode\n", devnam); + } + + /* Close if it's not stdin */ + if (strlen(devnam)) + close(dahdi_fd); + warn("Disconnect from DAHDI"); + +} + + +static int setspeed_dahdi(const char *cp) +{ + return 0; +} + +static void dahdi_extra_options() +{ + int ret; + char buf[256]; + snprintf(buf, 256, _PATH_DAHDI_OPT "%s",devnam); + if(!options_from_file(buf, 0, 0, 1)) + exit(EXIT_OPTION_ERROR); + +} + + + +static void send_config_dahdi(int mtu, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + int sock; + + if (mtu > DAHDI_MTU) { + warn("Couldn't increase MTU to %d.", mtu); + mtu = DAHDI_MTU; + } +} + + +static void recv_config_dahdi(int mru, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ + if (mru > DAHDI_MTU) + error("Couldn't increase MRU to %d", mru); +} + +static void set_xaccm_pppoe(int unit, ext_accm accm) +{ + /* NOTHING */ +} + + + +struct channel dahdi_channel; + +/* Check is cp is a valid DAHDI device + * return either 1 if "cp" is a reasonable thing to name a device + * or die. + * Note that we don't actually open the device at this point + * We do need to fill in: + * devnam: a string representation of the device + */ + +int (*old_setdevname_hook)(const char* cp) = NULL; +int setdevname_dahdi(const char *cp) +{ + int ret; + int chan; + + /* If already set, forgoe */ + if (strlen(devnam)) + return 1; + + + if (strcmp(cp, "stdin")) { + ret = sscanf(cp, "%d", &chan); + if (ret != 1) { + fatal("DAHDI: Invalid channel: '%s'\n", cp); + return -1; + } + } + + dahdi_copy_string(devnam, cp, sizeof(devnam)); + + info("Using DAHDI device '%s'\n", devnam); + + ret = 1; + + if( ret == 1 && the_channel != &dahdi_channel ){ + + the_channel = &dahdi_channel; + + modem = 0; + + lcp_allowoptions[0].neg_accompression = 0; + lcp_wantoptions[0].neg_accompression = 0; + + lcp_allowoptions[0].neg_pcompression = 0; + lcp_wantoptions[0].neg_pcompression = 0; + + ccp_allowoptions[0].deflate = 0 ; + ccp_wantoptions[0].deflate = 0 ; + + ipcp_allowoptions[0].neg_vj=0; + ipcp_wantoptions[0].neg_vj=0; + + ccp_allowoptions[0].bsd_compress = 0; + ccp_wantoptions[0].bsd_compress = 0; + + lcp_allowoptions[0].neg_asyncmap = 0; + lcp_wantoptions[0].neg_asyncmap = 0; + + } + return ret; +} + + + +void plugin_init(void) +{ + if (!ppp_available() && !new_style_driver) + fatal("Kernel doesn't support ppp_generic needed for DAHDI PPP"); + add_options(dahdi_options); + + info("DAHDI Plugin Initialized"); +} + +struct channel dahdi_channel = { + options: dahdi_options, + process_extra_options: &dahdi_extra_options, + check_options: NULL, + connect: &connect_dahdi, + disconnect: &disconnect_dahdi, + establish_ppp: &generic_establish_ppp, + disestablish_ppp: &generic_disestablish_ppp, + send_config: &send_config_dahdi, + recv_config: &recv_config_dahdi, + close: NULL, + cleanup: NULL +}; + diff --git a/sethdlc.c b/sethdlc.c new file mode 100644 index 0000000..cc0517c --- /dev/null +++ b/sethdlc.c @@ -0,0 +1,704 @@ +/* + * sethdlc.c + * + * Copyright (C) 1999 - 2002 Krzysztof Halasa + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +#if GENERIC_HDLC_VERSION != 4 +#error Generic HDLC layer version mismatch, please get correct sethdlc.c +#endif + +#if !defined(IF_PROTO_HDLC_ETH) || !defined(IF_PROTO_FR_ETH_PVC) +#warning "No kernel support for Ethernet over Frame Relay / HDLC, skipping it" +#endif + + +static struct ifreq req; /* for ioctl */ +static int argc; +static char **argv; +int sock; + + +static void error(const char *format, ...) __attribute__ ((noreturn, format(printf, 1, 2))); + +static void error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "%s: ", req.ifr_name); + vfprintf(stderr, format, args); + va_end(args); + exit(1); +} + + + +typedef struct { + const char *name; + const unsigned int value; +} parsertab; + + + +static int checkkey(const char* name) +{ + if (argc < 1) + return -1; /* no enough parameters */ + + if (strcmp(name, argv[0])) + return -1; + argc--; + argv++; + return 0; +} + + + +static int checktab(parsertab *tab, unsigned int *value) +{ + int i; + + if (argc < 1) + return -1; /* no enough parameters */ + + for (i = 0; tab[i].name; i++) + if (!strcmp(tab[i].name, argv[0])) { + argc--; + argv++; + *value = tab[i].value; + return 0; + } + + return -1; /* Not found */ +} + + + +static const char* tabstr(unsigned int value, parsertab *tab, + const char* unknown) +{ + int i; + for (i = 0; tab[i].name; i++) + if (tab[i].value == value) + return tab[i].name; + + return unknown; /* Not found */ +} + + + +static unsigned int match(const char* name, unsigned int *value, + unsigned int minimum, unsigned int maximum) +{ + char test; + + if (argc < 1) + return -1; /* no enough parameters */ + + if (name) { + if (strcmp(name, argv[0])) + return -1; + argc--; + argv++; + } + + if (argc < 1) + error("Missing parameter\n"); + + if (sscanf(argv[0], "%u%c", value, &test) != 1) + error("Invalid parameter: %s\n", argv[0]); + + if ((*value > maximum) || (*value < minimum)) + error("Parameter out of range [%u - %u]: %u\n", + minimum, maximum, *value); + + argc--; + argv++; + return 0; +} + + +static parsertab ifaces[] = {{ "v35", IF_IFACE_V35 }, + { "v24", IF_IFACE_V24 }, + { "x21", IF_IFACE_X21 }, + { "e1", IF_IFACE_E1 }, + { "t1", IF_IFACE_T1 }, + { NULL, 0 }}; + +static parsertab clocks[] = {{ "int", CLOCK_INT }, + { "ext", CLOCK_EXT }, + { "txint", CLOCK_TXINT }, + { "txfromrx", CLOCK_TXFROMRX }, + { NULL, 0 }}; + + +static parsertab protos[] = {{ "hdlc", IF_PROTO_HDLC}, + { "cisco", IF_PROTO_CISCO}, + { "fr", IF_PROTO_FR}, + { "ppp", IF_PROTO_PPP}, + { "x25", IF_PROTO_X25}, +#ifdef IF_PROTO_HDLC_ETH + { "hdlc-eth", IF_PROTO_HDLC_ETH}, +#endif + { NULL, 0 }}; + + +static parsertab hdlc_enc[] = {{ "nrz", ENCODING_NRZ }, + { "nrzi", ENCODING_NRZI }, + { "fm-mark", ENCODING_FM_MARK }, + { "fm-space", ENCODING_FM_SPACE }, + { "manchester", ENCODING_MANCHESTER }, + { NULL, 0 }}; + +static parsertab hdlc_par[] = {{ "no-parity", PARITY_NONE }, + { "crc16", PARITY_CRC16_PR1 }, + { "crc16-pr0", PARITY_CRC16_PR0 }, + { "crc16-itu", PARITY_CRC16_PR1_CCITT }, + { "crc16-itu-pr0", PARITY_CRC16_PR0_CCITT }, + { "crc32-itu", PARITY_CRC32_PR1_CCITT }, + { NULL, 0 }}; + +static parsertab lmi[] = {{ "none", LMI_NONE }, + { "ansi", LMI_ANSI }, + { "ccitt", LMI_CCITT }, + { NULL, 0 }}; + + +static void set_iface(void) +{ + int orig_argc = argc; + te1_settings te1; + + memset(&te1, 0, sizeof(te1)); + req.ifr_settings.type = IF_IFACE_SYNC_SERIAL; + + while (argc > 0) { + if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) + if (!checktab(ifaces, &req.ifr_settings.type)) + continue; + + if (!te1.clock_type) + if (!checkkey("clock")) { + if (!checktab(clocks, &te1.clock_type)) + continue; + error("Invalid clock type\n"); + } + + if (!te1.clock_rate && + (te1.clock_type == CLOCK_INT || + te1.clock_type == CLOCK_TXINT)) + if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF)) + continue; + if (!te1.loopback) { + if (!checkkey("loopback") || + !checkkey("lb")) { + te1.loopback = 1; + continue; + } + } + /* slotmap goes here */ + + if (orig_argc == argc) + return; /* not an iface definition */ + error("Invalid parameter: %s\n", argv[0]); + } + + if (!te1.clock_rate && + (te1.clock_type == CLOCK_INT || + te1.clock_type == CLOCK_TXINT)) + te1.clock_rate = 64000; + + /* FIXME stupid hack, will remove it later */ + req.ifr_settings.ifs_ifsu.te1 = &te1; + if (req.ifr_settings.type == IF_IFACE_E1 || + req.ifr_settings.type == IF_IFACE_T1) + req.ifr_settings.size = sizeof(te1_settings); + else + req.ifr_settings.size = sizeof(sync_serial_settings); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set interface information: %s\n", + strerror(errno)); + + exit(0); +} + + + +static void set_proto_fr(void) +{ + unsigned int lmi_type = 0; + fr_proto fr; + + memset(&fr, 0, sizeof(fr)); + + while (argc > 0) { + if (!lmi_type) + if (!checkkey("lmi")) { + if (!checktab(lmi, &lmi_type)) + continue; + error("Invalid LMI type: %s\n", + argv[0]); + } + + if (lmi_type && lmi_type != LMI_NONE) { + if (!fr.dce) + if (!checkkey("dce")) { + fr.dce = 1; + continue; + } + + if (!fr.t391) + if (!match("t391", &fr.t391, + 1, 1000)) + continue; + if (!fr.t392) + if (!match("t392", &fr.t392, + 1, 1000)) + continue; + if (!fr.n391) + if (!match("n391", &fr.n391, + 1, 1000)) + continue; + if (!fr.n392) + if (!match("n392", &fr.n392, + 1, 1000)) + continue; + if (!fr.n393) + if (!match("n393", &fr.n393, + 1, 1000)) + continue; + } + error("Invalid parameter: %s\n", argv[0]); + } + + /* polling verification timer*/ + if (!fr.t391) fr.t391 = 10; + /* link integrity verification polling timer */ + if (!fr.t392) fr.t392 = 15; + /* full status polling counter*/ + if (!fr.n391) fr.n391 = 6; + /* error threshold */ + if (!fr.n392) fr.n392 = 3; + /* monitored events count */ + if (!fr.n393) fr.n393 = 4; + + if (!lmi_type) + fr.lmi = LMI_DEFAULT; + else + fr.lmi = lmi_type; + + req.ifr_settings.ifs_ifsu.fr = &fr; + req.ifr_settings.size = sizeof(fr); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set FR protocol information: %s\n", + strerror(errno)); +} + + + +static void set_proto_hdlc(int eth) +{ + unsigned int enc = 0, par = 0; + raw_hdlc_proto raw; + + memset(&raw, 0, sizeof(raw)); + + while (argc > 0) { + if (!enc) + if (!checktab(hdlc_enc, &enc)) + continue; + if (!par) + if (!checktab(hdlc_par, &par)) + continue; + + error("Invalid parameter: %s\n", argv[0]); + } + + if (!enc) + raw.encoding = ENCODING_DEFAULT; + else + raw.encoding = enc; + + if (!par) + raw.parity = ENCODING_DEFAULT; + else + raw.parity = par; + + req.ifr_settings.ifs_ifsu.raw_hdlc = &raw; + req.ifr_settings.size = sizeof(raw); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set HDLC%s protocol information: %s\n", + eth ? "-ETH" : "", strerror(errno)); +} + + + +static void set_proto_cisco(void) +{ + cisco_proto cisco; + memset(&cisco, 0, sizeof(cisco)); + + while (argc > 0) { + if (!cisco.interval) + if (!match("interval", &cisco.interval, + 1, 100)) + continue; + if (!cisco.timeout) + if (!match("timeout", &cisco.timeout, + 1, 100)) + continue; + + error("Invalid parameter: %s\n", + argv[0]); + } + + if (!cisco.interval) + cisco.interval = 10; + if (!cisco.timeout) + cisco.timeout = 25; + + req.ifr_settings.ifs_ifsu.cisco = &cisco; + req.ifr_settings.size = sizeof(cisco); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to set Cisco HDLC protocol information: %s\n", + strerror(errno)); +} + + + +static void set_proto(void) +{ + if (checktab(protos, &req.ifr_settings.type)) + return; + + switch(req.ifr_settings.type) { + case IF_PROTO_HDLC: set_proto_hdlc(0); break; +#ifdef IF_PROTO_HDLC_ETH + case IF_PROTO_HDLC_ETH: set_proto_hdlc(1); break; +#endif + case IF_PROTO_CISCO: set_proto_cisco(); break; + case IF_PROTO_FR: set_proto_fr(); break; + + case IF_PROTO_PPP: + case IF_PROTO_X25: + req.ifr_settings.ifs_ifsu.sync = NULL; /* FIXME */ + req.ifr_settings.size = 0; + + if (!ioctl(sock, SIOCWANDEV, &req)) + break; + + error("Unable to set %s protocol information: %s\n", + req.ifr_settings.type == IF_PROTO_PPP + ? "PPP" : "X.25", strerror(errno)); + + default: error("Unknown protocol %u\n", req.ifr_settings.type); + } + + if (argc > 0) + error("Unexpected parameter: %s\n", argv[0]); + + close(sock); + exit(0); +} + + + +static void set_pvc(void) +{ + char *op = argv[0]; + parsertab ops[] = {{ "create", IF_PROTO_FR_ADD_PVC }, + { "delete", IF_PROTO_FR_DEL_PVC }, + { NULL, 0 }}; + fr_proto_pvc pvc; + + memset(&pvc, 0, sizeof(pvc)); + + if (checktab(ops, &req.ifr_settings.type)) + return; + +#ifdef IF_PROTO_FR_ETH_PVC + if (!match("ether", &pvc.dlci, 0, 1023)) { + if (req.ifr_settings.type == IF_PROTO_FR_ADD_PVC) + req.ifr_settings.type = IF_PROTO_FR_ADD_ETH_PVC; + else + req.ifr_settings.type = IF_PROTO_FR_DEL_ETH_PVC; + + } else +#endif + if (match(NULL, &pvc.dlci, 0, 1023)) + return; + + if (argc != 0) + return; + + req.ifr_settings.ifs_ifsu.fr_pvc = &pvc; + req.ifr_settings.size = sizeof(pvc); + + if (ioctl(sock, SIOCWANDEV, &req)) + error("Unable to %s PVC: %s\n", op, strerror(errno)); + exit(0); +} + + + +static void private(void) +{ + if (argc < 1) + return; + + if (!strcmp(argv[0], "private")) { + if (argc != 1) + return; + if (ioctl(sock, SIOCDEVPRIVATE, &req)) + error("SIOCDEVPRIVATE: %s\n", strerror(errno)); + exit(0); + } +} + + + +static void show_port(void) +{ + const char *s; + char buffer[128]; + const te1_settings *te1 = (void*)buffer; + const raw_hdlc_proto *raw = (void*)buffer; + const cisco_proto *cisco = (void*)buffer; + const fr_proto *fr = (void*)buffer; +#ifdef IF_PROTO_FR_PVC + const fr_proto_pvc_info *pvc = (void*)buffer; +#endif + req.ifr_settings.ifs_ifsu.sync = (void*)buffer; /* FIXME */ + + printf("%s: ", req.ifr_name); + + req.ifr_settings.size = sizeof(buffer); + req.ifr_settings.type = IF_GET_IFACE; + + if (ioctl(sock, SIOCWANDEV, &req)) + if (errno != EINVAL) { + printf("unable to get interface information: %s\n", + strerror(errno)); + close(sock); + exit(1); + } + + /* Get and print physical interface settings */ + if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) + s = ""; /* Unspecified serial interface */ + else + s = tabstr(req.ifr_settings.type, ifaces, NULL); + + if (!s) + printf("unknown interface 0x%x\n", req.ifr_settings.type); + else { + if (*s) + printf("interface %s ", s); + + printf("clock %s", tabstr(te1->clock_type, clocks, + "type unknown")); + if (te1->clock_type == CLOCK_INT || + te1->clock_type == CLOCK_TXINT) + printf(" rate %u", te1->clock_rate); + + if (te1->loopback) + printf(" loopback"); + + if (req.ifr_settings.type == IF_IFACE_E1 || + req.ifr_settings.type == IF_IFACE_T1) { + unsigned int u; + printf(" slotmap "); + for (u = te1->slot_map; u != 0; u /= 2) + printf("%u", u % 2); + } + printf("\n"); + } + + /* Get and print protocol settings */ + do { + printf("\t"); + req.ifr_settings.size = sizeof(buffer); + req.ifr_settings.type = IF_GET_PROTO; + + if (ioctl(sock, SIOCWANDEV, &req)) { + if (errno == EINVAL) + printf("no protocol set\n"); + else + printf("unable to get protocol information: " + "%s\n", strerror(errno)); + break; + } + + switch(req.ifr_settings.type) { + case IF_PROTO_FR: + printf("protocol fr lmi %s", + tabstr(fr->lmi, lmi, "unknown")); + if (fr->lmi == LMI_ANSI || + fr->lmi == LMI_CCITT) + printf("%s t391 %u t392 %u n391 %u n392 %u " + "n393 %u\n", + fr->dce ? " dce" : "", + fr->t391, + fr->t392, + fr->n391, + fr->n392, + fr->n393); + else + putchar('\n'); + break; + +#ifdef IF_PROTO_FR_PVC + case IF_PROTO_FR_PVC: + printf("Frame-Relay PVC: DLCI %u, master device %s\n", + pvc->dlci, pvc->master); + break; +#endif + +#ifdef IF_PROTO_FR_ETH_PVC + case IF_PROTO_FR_ETH_PVC: + printf("Frame-Relay PVC (Ethernet emulation): DLCI %u," + " master device %s\n", pvc->dlci, pvc->master); + break; +#endif + + case IF_PROTO_HDLC: + printf("protocol hdlc %s %s\n", + tabstr(raw->encoding, hdlc_enc, "unknown"), + tabstr(raw->parity, hdlc_par, "unknown")); + break; + +#ifdef IF_PROTO_HDLC_ETH + case IF_PROTO_HDLC_ETH: + printf("protocol hdlc-eth %s %s\n", + tabstr(raw->encoding, hdlc_enc, "unknown"), + tabstr(raw->parity, hdlc_par, "unknown")); + break; +#endif + + case IF_PROTO_CISCO: + printf("protocol cisco interval %u timeout %u\n", + cisco->interval, + cisco->timeout); + break; + + case IF_PROTO_PPP: + printf("protocol ppp\n"); + break; + + case IF_PROTO_X25: + printf("protocol x25\n"); + break; + + default: + printf("unknown protocol %u\n", req.ifr_settings.type); + } + }while(0); + + close(sock); + exit(0); +} + + + +static void usage(void) +{ + fprintf(stderr, "sethdlc version 1.15\n" + "Copyright (C) 2000 - 2003 Krzysztof Halasa \n" + "\n" + "Usage: sethdlc INTERFACE [PHYSICAL] [clock CLOCK] [LOOPBACK] " + "[slotmap SLOTMAP]\n" + " sethdlc INTERFACE [PROTOCOL]\n" + " sethdlc INTERFACE create | delete" +#ifdef IF_PROTO_FR_ETH_PVC + " [ether]" +#endif + " DLCI\n" + " sethdlc INTERFACE private...\n" + "\n" + "PHYSICAL := v24 | v35 | x21 | e1 | t1\n" + "CLOCK := int [rate RATE] | ext | txint [rate RATE] | txfromrx\n" + "LOOPBACK := loopback | lb\n" + "\n" + "PROTOCOL := hdlc [ENCODING] [PARITY] |\n" +#ifdef IF_PROTO_HDLC_ETH + " hdlc-eth [ENCODING] [PARITY] |\n" +#endif + " cisco [interval val] [timeout val] |\n" + " fr [lmi LMI] |\n" + " ppp |\n" + " x25\n" + "\n" + "ENCODING := nrz | nrzi | fm-mark | fm-space | manchester\n" + "PARITY := no-parity | crc16 | crc16-pr0 | crc16-itu | crc16-itu-pr0 | crc32-itu\n" + "LMI := none | ansi [LMI_SPEC] | ccitt [LMI_SPEC]\n" + "LMI_SPEC := [dce] [t391 val] [t392 val] [n391 val] [n392 val] [n393 val]\n"); + exit(0); +} + + + +int main(int arg_c, char *arg_v[]) +{ + argc = arg_c; + argv = arg_v; + + if (argc <= 1) + usage(); + + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sock < 0) + error("Unable to create socket: %s\n", strerror(errno)); + + dahdi_copy_string(req.ifr_name, argv[1], sizeof(req.ifr_name)); /* Device name */ + + if (argc == 2) + show_port(); + + argc -= 2; + argv += 2; + + set_iface(); + set_proto(); + set_pvc(); + private(); + + close(sock); + usage(); + exit(0); +} diff --git a/span-types.conf.sample b/span-types.conf.sample new file mode 100644 index 0000000..71c391e --- /dev/null +++ b/span-types.conf.sample @@ -0,0 +1,28 @@ +# +# /etc/dahdi/spantype.conf: Set E1/T1/J1 per-device +# +# Built as a table of two columns: +# : +# +# Where: +# * The field may be either: +# hardware_id +# @location +# devpath (in sysfs) +# * The is the relative span number +# in the device (starting from 1) +# In this filed globbing rules apply. E.g: +# - * are all the spans in this device +# - [12] are the first two spans in this device +# * The may be E1, T1 or J1 +# +# Examples: +# Set the first two spans of a specific Astribank to T1 +#usb:000156 [12]:T1 + +# Set all spans of another Astribank to T1 +#usb:INT03165 *:E1 + +# Set the first two spans of an Astribank to T1. The +# Astribanks is specified by its location instead of hardware_id +#@usb-0000:00:1d.7-3 [12]:T1 diff --git a/system.conf.sample b/system.conf.sample new file mode 100644 index 0000000..f05ecb8 --- /dev/null +++ b/system.conf.sample @@ -0,0 +1,326 @@ +# +# DAHDI Configuration File +# +# This file is parsed by the DAHDI Configurator, dahdi_cfg +# +# Span Configuration +# ++++++++++++++++++ +# First come the span definitions, in the format +# +# span=,,,,[,yellow] +# +# All T1/E1/BRI spans generate a clock signal on their transmit side. The +# parameter determines whether the clock signal from the far +# end of the T1/E1/BRI is used as the master source of clock timing. If it is, our +# own clock will synchronise to it. T1/E1/BRI connected directly or indirectly to +# a PSTN provider (telco) should generally be the first choice to sync to. The +# PSTN will never be a slave to you. You must be a slave to it. +# +# Choose 1 to make the equipment at the far end of the E1/T1/BRI link the preferred +# source of the master clock. Choose 2 to make it the second choice for the master +# clock, if the first choice port fails (the far end dies, a cable breaks, or +# whatever). Choose 3 to make a port the third choice, and so on. If you have, say, +# 2 ports connected to the PSTN, mark those as 1 and 2. The number used for each +# port should be different. +# +# If you choose 0, the port will never be used as a source of timing. This is +# appropriate when you know the far end should always be a slave to you. If +# the port is connected to a channel bank, for example, you should always be +# its master. Likewise, BRI TE ports should always be configured as a slave. +# Any number of ports can be marked as 0. +# +# Incorrect timing sync may cause clicks/noise in the audio, poor quality or failed +# faxes, unreliable modem operation, and is a general all round bad thing. +# +# NOTE: The B410P card cannot reliably connect one of its four ports +# configured in TE mode to another one configured in NT mode. It will not +# reliably sync clock from itself. Please use another physical card and +# configure one to provide clock and one to recover clock in any B410P test +# environments. +# +# The line build-out (or LBO) is an integer, from the following table: +# +# 0: 0 db (CSU) / 0-133 feet (DSX-1) +# 1: 133-266 feet (DSX-1) +# 2: 266-399 feet (DSX-1) +# 3: 399-533 feet (DSX-1) +# 4: 533-655 feet (DSX-1) +# 5: -7.5db (CSU) +# 6: -15db (CSU) +# 7: -22.5db (CSU) +# +# If the span is a BRI port the line build-out is not used and should be set +# to 0. +# +# framing:: +# one of 'd4' or 'esf' for T1 or 'cas' or 'ccs' for E1. Use 'ccs' for BRI. +# 'd4' could be referred to as 'sf' or 'superframe' +# +# coding:: +# one of 'ami' or 'b8zs' for T1 or 'ami' or 'hdb3' for E1. Use 'ami' for +# BRI. +# +# * For E1 there is the optional keyword 'crc4' to enable CRC4 checking. +# * If the keyword 'yellow' follows, yellow alarm is transmitted when no +# channels are open. +# +#span=1,0,0,esf,b8zs +#span=2,1,0,esf,b8zs +#span=3,0,0,ccs,hdb3,crc4 +# +# Dynamic Spans +# +++++++++++++ +# Next come the dynamic span definitions, in the form: +# +# dynamic=,
,, +# +# Where is the name of the driver (e.g. eth),
is the +# driver specific address (like a MAC for eth), is the number +# of channels, and is a timing priority, like for a normal span. +# use "0" to not use this as a timing source, or prioritize them as +# primary, secondard, etc. Note that you MUST have a REAL DAHDI device +# if you are not using external timing. +# +# dynamic=eth,eth0/00:02:b3:35:43:9c,24,0 +# +# If a non-zero timing value is used, as above, only the last span should +# have the non-zero value. +# +# Channel Configuration +# +++++++++++++++++++++ +# Next come the definitions for using the channels. The format is: +# = +# +# Valid devices are: +# +# e&m:: +# Channel(s) are signalled using E&M signalling on a T1 line. +# Specific implementation, such as Immediate, Wink, or Feature +# Group D are handled by the userspace library. +# e&me1:: +# Channel(s) are signalled using E&M signalling on an E1 line. +# fxsls:: +# Channel(s) are signalled using FXS Loopstart protocol. +# fxsgs:: +# Channel(s) are signalled using FXS Groundstart protocol. +# fxsks:: +# Channel(s) are signalled using FXS Koolstart protocol. +# fxols:: +# Channel(s) are signalled using FXO Loopstart protocol. +# fxogs:: +# Channel(s) are signalled using FXO Groundstart protocol. +# fxoks:: +# Channel(s) are signalled using FXO Koolstart protocol. +# +# unused:: +# No signalling is performed, each channel in the list remains idle +# clear:: +# Channel(s) are bundled into a single span. No conversion or +# signalling is performed, and raw data is available on the master. +# bchan:: +# Like 'clear' except all channels are treated individually and +# are not bundled. 'inclear' is an alias for this. +# rawhdlc:: +# The DAHDI driver performs HDLC encoding and decoding on the +# bundle, and the resulting data is communicated via the master +# device. +# dchan:: +# The DAHDI driver performs HDLC encoding and decoding on the +# bundle and also performs incoming and outgoing FCS insertion +# and verification. 'fcshdlc' is an alias for this. +# hardhdlc:: +# The hardware driver performs HDLC encoding and decoding on the +# bundle and also performs incoming and outgoing FCS insertion +# and verification. Is subject to limitations and support of underlying +# hardware. BRI spans serviced by the wcb4xxp driver must use hardhdlc +# channels for the signalling channels. +# nethdlc:: +# The DAHDI driver bundles the channels together into an +# hdlc network device, which in turn can be configured with +# sethdlc (available separately). In 2.6.x kernels you can also optionally +# pass the name for the network interface after the channel list. +# Syntax: +# +# nethdlc=[:interface name] +# Use original names, don't use the names which have been already registered +# in system e.g eth. +# +# dacs:: +# The DAHDI driver cross connects the channels starting at +# the channel number listed at the end, after a colon +# dacsrbs:: +# The DAHDI driver cross connects the channels starting at +# the channel number listed at the end, after a colon and +# also performs the DACSing of RBS bits +# +# The channel list is a comma-separated list of channels or ranges, for +# example: +# +# 1,3,5 (channels one, three, and five) +# 16-23, 29 (channels 16 through 23, as well as channel 29) +# +# So, some complete examples are: +# +# e&m=1-12 +# nethdlc=13-24 +# fxsls=25,26,27,28 +# fxols=29-32 +# +# An example of BRI port: +# +# span=1,1,0,ccs,ami +# bchan=1,2 +# hardhdlc=3 +# +# NOTE: When using BRI channels in asterisk, use the bri_cpe, bri_net, or +# bri_cpe_ptmp (for point to multipoint mode). libpri does not currently +# support point to multipoint when in NT mode. Otherwise, the bearer channel +# are configured identically to other DAHDI channels. +# +#fxoks=1-24 +#bchan=25-47 +#dchan=48 +#fxols=1-12 +#fxols=13-24 +#e&m=25-29 +#nethdlc=30-33 +#clear=44 +#clear=45 +#clear=46 +#clear=47 +#fcshdlc=48 +#dacs=1-24:48 +#dacsrbs=1-24:48 +# +# Tone Zone Data +# ++++++++++++++ +# Finally, you can preload some tone zones, to prevent them from getting +# overwritten by other users (if you allow non-root users to open /dev/dahdi/* +# interfaces anyway. Also this means they won't have to be loaded at runtime. +# The format is "loadzone=" where the zone is a two letter country code. +# +# You may also specify a default zone with "defaultzone=" where zone +# is a two letter country code. +# +# An up-to-date list of the zones can be found in the file zonedata.c +# +loadzone = us +#loadzone = us-old +#loadzone=gr +#loadzone=it +#loadzone=fr +#loadzone=de +#loadzone=uk +#loadzone=fi +#loadzone=jp +#loadzone=sp +#loadzone=no +#loadzone=hu +#loadzone=lt +#loadzone=pl +defaultzone=us +# +# PCI Radio Interface +# +++++++++++++++++++ +# (see http://www.zapatatelephony.org/app_rpt.html) +# +# The PCI Radio Interface card interfaces up to 4 two-way radios (either +# a base/mobile radio or repeater system) to DAHDI channels. The driver +# may work either independent of an application, or with it, through +# the driver;s ioctl() interface. This file gives you access to specify +# load-time parameters for Radio channels, so that the driver may run +# by itself, and just act like a generic DAHDI radio interface. +# +# Unlike the rest of this file, you specify a block of parameters, and +# then the channel(s) to which they apply. CTCSS is specified as a frequency +# in tenths of hertz, for example 131.8 HZ is specified as 1318. DCS +# for receive is specified as the code directly, for example 223. DCS for +# transmit is specified as D and then the code, for example D223. +# +# The hardware supports a "community" CTCSS decoder system that has +# arbitrary transmit CTCSS or DCS codes associated with them, unlike +# traditional "community" systems that encode the same tone they decode. +# +# this example is a single tone DCS transmit and receive +# +# specify the transmit tone (in DCS mode this stays constant): +#tx=D371 +# +# specify the receive DCS code: +#dcsrx=223 +# +# this example is a "community" CTCSS (if you only want a single tone, then +# only specify 1 in the ctcss list) +# +# specify the default transmit tone (when not receiving): +#tx=1000 +# +# Specify the receive freq, the tag (use 0 if none), and the transmit code. +# The tag may be used by applications to determine classification of tones. +# The tones are to be specified in order of presedence, most important first. +# Currently, 15 tones may be specified.. +# +#ctcss=1318,1,1318 +#ctcss=1862,1,1862 +# +# The following parameters may be omitted if their default value is acceptible +# +# Set the receive debounce time in milliseconds: +#debouncetime=123 +# +# set the transmit quiet dropoff burst time in milliseconds: +#bursttime=234 +# +# set the COR level threshold (specified in tenths of millivolts) +# valid values are {3125,6250,9375,12500,15625,18750,21875,25000} +#corthresh=12500 +# +# Invert COR signal {y,n} +#invertcor=y +# Set the external tone mode; yes, no, internal {y,n,i} +#exttone=y +# +# Now apply the configuration to the specified channels: +# +# We are all done with our channel parameters, so now we specify what +# channels they apply to +#channels=1-4 +# +# Overiding PCM encoding +# ++++++++++++++++++++++ +# Usually the channel driver sets the encoding of the PCM for the +# channel (mulaw / alaw. That is: g711u or g711a). However there are +# some cases where you would like to override that. 'mulaw' and 'alaw' +# set different such encoding. Use them for channels you have already +# defined with e.g. 'bchan' or 'fxoks'. +#mulaw=1-4 +#alaw=1-4 +# +# 'deflaw' is similar, but resets the encoding to the channel driver's +# default. It must be useful for something, I guess. +#mulaw=1-10 +#deflaw=5 +# +# Echo Cancellers +# +++++++++++++++ +# DAHDI uses modular echo cancellers that are configured per channel. The echo +# cancellers are compiled and installed as part of the dahdi-linux package. +# You can specify in this file the echo canceller to be used for each +# channel. The default behavior is for there to be NO echo canceller on any +# channel, so it is very important that you specify one here. +# +# Valid echo cancellers are: hwec, mg2, kb1, sec2, and sec. +# 'hwec' is a special echo canceller that should be used if hardware echo +# cancellation is desired on and available on the specified channels. +# If compiled, 'hpec' is also a valid echo canceller. +# +# To configure the default echo cancellers, use the format: +# echocanceller=, +# +# Example: +# Configure channels 1 through 8 to use the mg2 echo canceller +#echocanceller=mg2,1-8 +# +# And change channel 2 to use the kb1 echo canceller. +#echocanceller=kb1,2 +# diff --git a/timertest.c b/timertest.c new file mode 100644 index 0000000..6f72885 --- /dev/null +++ b/timertest.c @@ -0,0 +1,78 @@ +/* + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + * Primary Author: Mark Spencer + * Radio Support by Jim Dixon + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dahdi_tools_version.h" + +int main(int argc, char *argv[]) +{ + int fd; + int x = 8000; + int res; + fd_set fds; + struct timeval orig, now; + fd = open("/dev/dahdi/timer", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Unable to open timer: %s\n", strerror(errno)); + exit(1); + } + printf("Opened timer...\n"); + if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) { + fprintf(stderr, "Unable to set timer: %s\n", strerror(errno)); + exit(1); + } + printf("Set timer duration to %d samples (%d ms)\n", x, x/8); + printf("Waiting...\n"); + gettimeofday(&orig, NULL); + for(;;) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + res = select(fd + 1, NULL, NULL, &fds, NULL); + if (res != 1) { + fprintf(stderr, "Unexpected result %d: %s\n", res, strerror(errno)); + exit(1); + } + x = -1; + if (ioctl(fd, DAHDI_TIMERACK, &x)) { + fprintf(stderr, "Unable to ack timer: %s\n", strerror(errno)); + exit(1); + } + gettimeofday(&now, NULL); + printf("Timer Expired (%ld ms)!\n", (now.tv_sec - orig.tv_sec) * 1000 + (now.tv_usec - orig.tv_usec) / 1000); + } + exit(0); +} diff --git a/tonezone.c b/tonezone.c new file mode 100644 index 0000000..e31a803 --- /dev/null +++ b/tonezone.c @@ -0,0 +1,529 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Primary Author: Mark Spencer + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dahdi/user.h" +#include "tonezone.h" +#include "dahdi_tools_version.h" + +#define DEFAULT_DAHDI_DEV "/dev/dahdi/ctl" + +#define MAX_SIZE 16384 +#define CLIP 32635 +#define BIAS 0x84 + +#if 0 +# define PRINT_DEBUG(x, ...) printf(x, __VA_ARGS__) +#else +# define PRINT_DEBUG(x, ...) +#endif + +#ifndef ENODATA +#define ENODATA EINVAL +#endif + +struct tone_zone *tone_zone_find(char *country) +{ + struct tone_zone *z; + z = builtin_zones; + while(z->zone > -1) { + if (!strcasecmp(country, z->country)) + return z; + z++; + } + return NULL; +} + +struct tone_zone *tone_zone_find_by_num(int id) +{ + struct tone_zone *z; + z = builtin_zones; + while(z->zone > -1) { + if (z->zone == id) + return z; + z++; + } + return NULL; +} + +#define LEVEL -10 + +static int build_tone(void *data, size_t size, struct tone_zone_sound *t, int *count) +{ + char *dup, *s; + struct dahdi_tone_def *td=NULL; + int firstnobang = -1; + int freq1, freq2, time; + int modulate = 0; + float db = 1.0; + float gain; + int used = 0; + dup = strdup(t->data); + s = strtok(dup, ","); + while(s && strlen(s)) { + /* Handle optional ! which signifies don't start here*/ + if (s[0] == '!') { + s++; + } else if (firstnobang < 0) { + PRINT_DEBUG("First no bang: %s\n", s); + firstnobang = *count; + } + + if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) { + /* f1+f2/time format */ + PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); + } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) { + /* f1*f2/time format */ + PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); + modulate = 1; + } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) { + PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); + time = 0; + } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) { + PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); + modulate = 1; + time = 0; + } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) { + PRINT_DEBUG("f1/time format: %d, %d\n", freq1, time); + freq2 = 0; + } else if (sscanf(s, "%d@/%d", &freq1, &time) == 2) { + /* The "@" character has been added to enable an + * approximately -20db tone generation of any frequency This has been done + * primarily to generate the Australian congestion tone. + * Example: "425/375,0/375,425@/375,0/375" + */ + PRINT_DEBUG("f1 reduced amplitude/time format: %d, %d\n", freq1,time); + db = 0.3; + freq2 = 0; + } else if (sscanf(s, "%d", &freq1) == 1) { + PRINT_DEBUG("f1 format: %d\n", freq1); + firstnobang = *count; + freq2 = 0; + time = 0; + } else { + fprintf(stderr, "tone component '%s' of '%s' is a syntax error\n", s,t->data); + return -1; + } + + PRINT_DEBUG("Using %d samples for %d and %d\n", time * 8, freq1, freq2); + + if (size < sizeof(*td)) { + fprintf(stderr, "Not enough space for tones\n"); + return -1; + } + td = data; + + /* Bring it down -8 dbm */ + gain = db*(pow(10.0, (LEVEL - 3.14) / 20.0) * 65536.0 / 2.0); + + td->fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; + td->init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * gain; + td->init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * gain; + + td->fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; + td->init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * gain; + td->init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * gain; + + td->modulate = modulate; + + data += sizeof(*td); + used += sizeof(*td); + size -= sizeof(*td); + td->tone = t->toneid; + if (time) { + /* We should move to the next tone */ + td->next = *count + 1; + td->samples = time * 8; + } else { + /* Stay with us */ + td->next = *count; + td->samples = 8000; + } + *count += 1; + s = strtok(NULL, ","); + } + if (td && time) { + /* If we don't end on a solid tone, return */ + td->next = firstnobang; + } + if (firstnobang < 0) + fprintf(stderr, "tone '%s' does not end with a solid tone or silence (all tone components have an exclamation mark)\n", t->data); + + return used; +} + +char *tone_zone_tone_name(int id) +{ + static char tmp[80]; + switch(id) { + case DAHDI_TONE_DIALTONE: + return "Dialtone"; + case DAHDI_TONE_BUSY: + return "Busy"; + case DAHDI_TONE_RINGTONE: + return "Ringtone"; + case DAHDI_TONE_CONGESTION: + return "Congestion"; + case DAHDI_TONE_CALLWAIT: + return "Call Waiting"; + case DAHDI_TONE_DIALRECALL: + return "Dial Recall"; + case DAHDI_TONE_RECORDTONE: + return "Record Tone"; + case DAHDI_TONE_CUST1: + return "Custom 1"; + case DAHDI_TONE_CUST2: + return "Custom 2"; + case DAHDI_TONE_INFO: + return "Special Information"; + case DAHDI_TONE_STUTTER: + return "Stutter Dialtone"; + default: + snprintf(tmp, sizeof(tmp), "Unknown tone %d", id); + return tmp; + } +} + +#ifdef TONEZONE_DRIVER +static void dump_tone_zone(void *data, int size) +{ + struct dahdi_tone_def_header *z; + struct dahdi_tone_def *td; + int x; + int len = sizeof(*z); + + z = data; + data += sizeof(*z); + printf("Header: %d tones, %d bytes of data, zone %d (%s)\n", + z->count, size, z->zone, z->name); + for (x = 0; x < z->count; x++) { + td = data; + printf("Tone Fragment %d: tone is %d, next is %d, %d samples\n", + x, td->tone, td->next, td->samples); + data += sizeof(*td); + len += sizeof(*td); + } + printf("Total measured bytes of data: %d\n", len); +} +#endif + +/* Tone frequency tables */ +struct mf_tone { + int tone; + float f1; /* first freq */ + float f2; /* second freq */ +}; + +static struct mf_tone dtmf_tones[] = { + { DAHDI_TONE_DTMF_0, 941.0, 1336.0 }, + { DAHDI_TONE_DTMF_1, 697.0, 1209.0 }, + { DAHDI_TONE_DTMF_2, 697.0, 1336.0 }, + { DAHDI_TONE_DTMF_3, 697.0, 1477.0 }, + { DAHDI_TONE_DTMF_4, 770.0, 1209.0 }, + { DAHDI_TONE_DTMF_5, 770.0, 1336.0 }, + { DAHDI_TONE_DTMF_6, 770.0, 1477.0 }, + { DAHDI_TONE_DTMF_7, 852.0, 1209.0 }, + { DAHDI_TONE_DTMF_8, 852.0, 1336.0 }, + { DAHDI_TONE_DTMF_9, 852.0, 1477.0 }, + { DAHDI_TONE_DTMF_s, 941.0, 1209.0 }, + { DAHDI_TONE_DTMF_p, 941.0, 1477.0 }, + { DAHDI_TONE_DTMF_A, 697.0, 1633.0 }, + { DAHDI_TONE_DTMF_B, 770.0, 1633.0 }, + { DAHDI_TONE_DTMF_C, 852.0, 1633.0 }, + { DAHDI_TONE_DTMF_D, 941.0, 1633.0 }, + { 0, 0, 0 } +}; + +static struct mf_tone mfr1_tones[] = { + { DAHDI_TONE_MFR1_0, 1300.0, 1500.0 }, + { DAHDI_TONE_MFR1_1, 700.0, 900.0 }, + { DAHDI_TONE_MFR1_2, 700.0, 1100.0 }, + { DAHDI_TONE_MFR1_3, 900.0, 1100.0 }, + { DAHDI_TONE_MFR1_4, 700.0, 1300.0 }, + { DAHDI_TONE_MFR1_5, 900.0, 1300.0 }, + { DAHDI_TONE_MFR1_6, 1100.0, 1300.0 }, + { DAHDI_TONE_MFR1_7, 700.0, 1500.0 }, + { DAHDI_TONE_MFR1_8, 900.0, 1500.0 }, + { DAHDI_TONE_MFR1_9, 1100.0, 1500.0 }, + { DAHDI_TONE_MFR1_KP, 1100.0, 1700.0 }, /* KP */ + { DAHDI_TONE_MFR1_ST, 1500.0, 1700.0 }, /* ST */ + { DAHDI_TONE_MFR1_STP, 900.0, 1700.0 }, /* KP' or ST' */ + { DAHDI_TONE_MFR1_ST2P, 1300.0, 1700.0 }, /* KP'' or ST'' */ + { DAHDI_TONE_MFR1_ST3P, 700.0, 1700.0 }, /* KP''' or ST''' */ + { 0, 0, 0 } +}; + +static struct mf_tone mfr2_fwd_tones[] = { + { DAHDI_TONE_MFR2_FWD_1, 1380.0, 1500.0 }, + { DAHDI_TONE_MFR2_FWD_2, 1380.0, 1620.0 }, + { DAHDI_TONE_MFR2_FWD_3, 1500.0, 1620.0 }, + { DAHDI_TONE_MFR2_FWD_4, 1380.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_5, 1500.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_6, 1620.0, 1740.0 }, + { DAHDI_TONE_MFR2_FWD_7, 1380.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_8, 1500.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_9, 1620.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_10, 1740.0, 1860.0 }, + { DAHDI_TONE_MFR2_FWD_11, 1380.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_12, 1500.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_13, 1620.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_14, 1740.0, 1980.0 }, + { DAHDI_TONE_MFR2_FWD_15, 1860.0, 1980.0 }, + { 0, 0, 0 } +}; + +static struct mf_tone mfr2_rev_tones[] = { + { DAHDI_TONE_MFR2_REV_1, 1020.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_2, 900.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_3, 900.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_4, 780.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_5, 780.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_6, 780.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_7, 660.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_8, 660.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_9, 660.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_10, 660.0, 780.0 }, + { DAHDI_TONE_MFR2_REV_11, 540.0, 1140.0 }, + { DAHDI_TONE_MFR2_REV_12, 540.0, 1020.0 }, + { DAHDI_TONE_MFR2_REV_13, 540.0, 900.0 }, + { DAHDI_TONE_MFR2_REV_14, 540.0, 780.0 }, + { DAHDI_TONE_MFR2_REV_15, 540.0, 660.0 }, + { 0, 0, 0 } +}; + +static int build_mf_tones(void *data, size_t size, int *count, struct mf_tone *tone, int low_tone_level, int high_tone_level) +{ + struct dahdi_tone_def *td; + float gain; + int used = 0; + + while (tone->tone) { + if (size < sizeof(*td)) { + fprintf(stderr, "Not enough space for samples\n"); + return -1; + } + td = data; + data += sizeof(*td); + used += sizeof(*td); + size -= sizeof(*td); + td->tone = tone->tone; + *count += 1; + + /* Bring it down 6 dBm */ + gain = pow(10.0, (low_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; + td->fac1 = 2.0 * cos(2.0 * M_PI * (tone->f1 / 8000.0)) * 32768.0; + td->init_v2_1 = sin(-4.0 * M_PI * (tone->f1 / 8000.0)) * gain; + td->init_v3_1 = sin(-2.0 * M_PI * (tone->f1 / 8000.0)) * gain; + + gain = pow(10.0, (high_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; + td->fac2 = 2.0 * cos(2.0 * M_PI * (tone->f2 / 8000.0)) * 32768.0; + td->init_v2_2 = sin(-4.0 * M_PI * (tone->f2 / 8000.0)) * gain; + td->init_v3_2 = sin(-2.0 * M_PI * (tone->f2 / 8000.0)) * gain; + + tone++; + } + + return used; +} + +int tone_zone_register_zone(int fd, struct tone_zone *z) +{ + char buf[MAX_SIZE]; + int res; + int count = 0; + int x; + size_t space = MAX_SIZE; + void *ptr = buf; + int iopenedit = 1; + struct dahdi_tone_def_header *h; + + memset(buf, 0, sizeof(buf)); + + h = ptr; + ptr += sizeof(*h); + space -= sizeof(*h); + h->zone = z->zone; + + dahdi_copy_string(h->name, z->description, sizeof(h->name)); + + for (x = 0; x < DAHDI_MAX_CADENCE; x++) + h->ringcadence[x] = z->ringcadence[x]; + + for (x = 0; x < DAHDI_TONE_MAX; x++) { + if (!strlen(z->tones[x].data)) + continue; + + PRINT_DEBUG("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data); + + if ((res = build_tone(ptr, space, &z->tones[x], &count)) < 0) { + fprintf(stderr, "Tone %d not built.\n", x); + return -1; + } + ptr += res; + space -= res; + } + + if ((res = build_mf_tones(ptr, space, &count, dtmf_tones, z->dtmf_low_level, z->dtmf_high_level)) < 0) { + fprintf(stderr, "Could not build DTMF tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr1_tones, z->mfr1_level, z->mfr1_level)) < 0) { + fprintf(stderr, "Could not build MFR1 tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr2_fwd_tones, z->mfr2_level, z->mfr2_level)) < 0) { + fprintf(stderr, "Could not build MFR2 FWD tones.\n"); + return -1; + } + ptr += res; + space -= res; + + if ((res = build_mf_tones(ptr, space, &count, mfr2_rev_tones, z->mfr2_level, z->mfr2_level)) < 0) { + fprintf(stderr, "Could not build MFR2 REV tones.\n"); + return -1; + } + ptr += res; + space -= res; + + h->count = count; + + if (fd < 0) { + if ((fd = open(DEFAULT_DAHDI_DEV, O_RDWR)) < 0) { + fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_DAHDI_DEV); + return -1; + } + iopenedit = 1; + } + + x = z->zone; + if ((res = ioctl(fd, DAHDI_FREEZONE, &x))) { + if (errno != EBUSY) + fprintf(stderr, "ioctl(DAHDI_FREEZONE) failed: %s\n", strerror(errno)); + return res; + } + +#if defined(TONEZONE_DRIVER) + dump_tone_zone(h, MAX_SIZE - space); +#endif + +#if defined(__FreeBSD__) + if ((res = ioctl(fd, DAHDI_LOADZONE, &h))) { +#else + if ((res = ioctl(fd, DAHDI_LOADZONE, h))) { +#endif + fprintf(stderr, "ioctl(DAHDI_LOADZONE) failed: %s\n", strerror(errno)); + return res; + } + + if (iopenedit) + close(fd); + + return res; +} + +int tone_zone_register(int fd, char *country) +{ + struct tone_zone *z; + z = tone_zone_find(country); + if (z) { + return tone_zone_register_zone(-1, z); + } else { + return -1; + } +} + +int tone_zone_set_zone(int fd, char *country) +{ + int res=-1; + struct tone_zone *z; + if (fd > -1) { + z = tone_zone_find(country); + if (z) + res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); + if ((res < 0) && (errno == ENODATA)) { + tone_zone_register_zone(fd, z); + res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); + } + } + return res; +} + +int tone_zone_get_zone(int fd) +{ + int x=-1; + if (fd > -1) { + ioctl(fd, DAHDI_GETTONEZONE, &x); + return x; + } + return -1; +} + +int tone_zone_play_tone(int fd, int tone) +{ + struct tone_zone *z; + int res = -1; + int zone; + +#if 0 + fprintf(stderr, "Playing tone %d (%s) on %d\n", tone, tone_zone_tone_name(tone), fd); +#endif + if (fd > -1) { + res = ioctl(fd, DAHDI_SENDTONE, &tone); + if ((res < 0) && (errno == ENODATA)) { + ioctl(fd, DAHDI_GETTONEZONE, &zone); + z = tone_zone_find_by_num(zone); + if (z) { + res = tone_zone_register_zone(fd, z); + /* Recall the zone */ + ioctl(fd, DAHDI_SETTONEZONE, &zone); + if (res < 0) { + fprintf(stderr, "Failed to register zone '%s': %s\n", z->description, strerror(errno)); + } else { + res = ioctl(fd, DAHDI_SENDTONE, &tone); + } + } else + fprintf(stderr, "Don't know anything about zone %d\n", zone); + } + } + return res; +} diff --git a/tonezone.h b/tonezone.h new file mode 100644 index 0000000..07c5f98 --- /dev/null +++ b/tonezone.h @@ -0,0 +1,90 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Copyright (C) 2001-2008, Digium, Inc. + * + * Primary Author: Mark Spencer + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#ifndef _TONEZONE_H +#define _TONEZONE_H + +#include + +struct tone_zone_sound { + int toneid; + char data[256]; /* Actual zone description */ + /* Description is a series of tones of the format: + [!]freq1[+freq2][/time] separated by commas. There + are no spaces. The sequence is repeated back to the + first tone description not preceeded by !. time is + specified in milliseconds */ +}; + +struct tone_zone { + int zone; /* Zone number */ + char country[10]; /* Country code */ + char description[40]; /* Description */ + int ringcadence[DAHDI_MAX_CADENCE]; /* Ring cadence */ + struct tone_zone_sound tones[DAHDI_TONE_MAX]; + int dtmf_high_level; /* Power level of high frequency component + of DTMF, expressed in dBm0. */ + int dtmf_low_level; /* Power level of low frequency component + of DTMF, expressed in dBm0. */ + int mfr1_level; /* Power level of MFR1, expressed in dBm0. */ + int mfr2_level; /* Power level of MFR2, expressed in dBm0. */ +}; + +extern struct tone_zone builtin_zones[]; + +/* Register a given two-letter tone zone if we can */ +int tone_zone_register(int fd, char *country); + +/* Register a given two-letter tone zone if we can */ +int tone_zone_register_zone(int fd, struct tone_zone *z); + +/* Retrieve a raw tone zone structure */ +struct tone_zone *tone_zone_find(char *country); + +/* Retrieve a raw tone zone structure by id instead of country*/ +struct tone_zone *tone_zone_find_by_num(int id); + +/* Retrieve a string name for a given tone id */ +char *tone_zone_tone_name(int id); + +/* Set a given file descriptor into a given country -- USE THIS + INTERFACE INSTEAD OF THE IOCTL ITSELF. Auto-loads tone + zone if necessary */ +int tone_zone_set_zone(int fd, char *country); + +/* Get the current tone zone */ +int tone_zone_get_zone(int fd); + +/* Play a given tone, loading tone zone automatically + if necessary */ +int tone_zone_play_tone(int fd, int toneid); + +#endif diff --git a/wavformat.h b/wavformat.h new file mode 100644 index 0000000..c7b1626 --- /dev/null +++ b/wavformat.h @@ -0,0 +1,48 @@ +/* + * wavformat.h -- data structures and associated definitions for wav files + * + * By Michael Spiceland (mspiceland@digium.com) + * + * (C) 2009 Digium, Inc. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef WAVFORMAT_H +#define WAVFORMAT_H + +#include + +struct wavheader { + /* riff type chunk */ + char riff_chunk_id[4]; + uint32_t riff_chunk_size; + char riff_type[4]; + + /* format chunk */ + char fmt_chunk_id[4]; + uint32_t fmt_data_size; + uint16_t fmt_compression_code; + uint16_t fmt_num_channels; + uint32_t fmt_sample_rate; + uint32_t fmt_avg_bytes_per_sec; + uint16_t fmt_block_align; + uint16_t fmt_significant_bps; + + /* data chunk */ + char data_chunk_id[4]; + uint32_t data_data_size; +} __attribute__((packed)); + +#endif diff --git a/xpp/Makefile b/xpp/Makefile new file mode 100644 index 0000000..12909f2 --- /dev/null +++ b/xpp/Makefile @@ -0,0 +1,202 @@ +PEDANTIC = -ansi -pedantic -std=c99 + +INSTALL = install +INSTALL_DATA = install -m 644 + +# +# Ugly hack to find kernel directories before/after the split +# to kernel/user-space. +# +# These variables should be passed to us. But until then... +# +DAHDI_TOOLSDIR ?= .. +DAHDI_KERNELDIR = + +-include $(DAHDI_TOOLSDIR)/makeopts + +INSTALL_DATA = $(INSTALL) -m 644 + +# In 1.4 those are provided by autoconf through makeopts +prefix ?= /usr +datadir ?= $(prefix)/share +mandir ?= $(datadir)/man +sysconfdir ?= $(prefix)/etc +udevrulesdir ?= $(sysconfdir)/udev/rules.d +INSTALL ?= install + +INSTALL_DATA = $(INSTALL) -m 644 + +SBINDIR = $(prefix)/sbin +DATADIR = $(datadir)/dahdi +MANDIR = $(mandir)/man8 +HOTPLUG_USB_DIR = $(sysconfdir)/hotplug/usb +PERLLIBDIR := $(shell eval `perl -V:sitelib`; echo "$$sitelib") +PERL_DIRS := $(shell cd perl_modules; find * -name '[A-Z]*' -type d| xargs) +PERL_MODS_PAT := *.pm $(PERL_DIRS:%=%/*.pm) +PERL_MODS := $(shell cd perl_modules; echo $(PERL_MODS_PAT)) + +# Variables that should be defined above, but need sane defaults: +# FIXME: Are those values really sane? +HOSTCC ?= $(CC) + +USE_OCTASIC := yes +OCTASIC_DIR := oct612x + +ifneq (no,$(USE_OCTASIC)) + +OCT_OBJS = $(shell $(OCTASIC_DIR)/octasic-helper objects $(OCTASIC_DIR)) +OCT_SRCS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's/\.o$$/.c/g') +OCT_HERE_OBJS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's,^.*/,,') +OCT_CFLAGS = $(shell $(OCTASIC_DIR)/octasic-helper cflags $(OCTASIC_DIR)) +OCT_DEFINES = \ + -DPTR_TYPE=uint32_t \ + -DcOCT6100_INTERNAL_SUPER_ARRAY_SIZE=1024 \ + -DcOCT6100_MAX_ECHO_CHANNELS=672 \ + -DcOCT6100_MAX_MIXER_EVENTS=1344 + +ECHO_LOADER_SRC = echo_loader.c parse_span_specs.c +ECHO_LOADER = $(ECHO_LOADER_SRC:.c=.o) +endif + +%.8: % + pod2man --section 8 $^ > $@ || $(RM) $@ +PERL_SCRIPTS = \ + dahdi_registration \ + xpp_sync \ + lsdahdi \ + xpp_blink \ + dahdi_genconf \ + dahdi_hardware \ + twinstar \ + # + +PERL_MANS = $(PERL_SCRIPTS:%=%.8) + +# List all our sources +XUSB_SRCS = xtalk/xusb.c xtalk/xlist.c xtalk/debug.c +XTALK_SRCS = xtalk/xtalk.c +MPPTALK_SRCS = mpptalk.c +ASTRIBANK_SRCS = astribank_usb.c +ABHEXLOAD_SRCS = astribank_hexload.c hexfile.c pic_loader.c +ABTOOL_SRCS = astribank_tool.c +ABALLOW_SRCS = astribank_allow.c astribank_license.c + +SRCS = \ + $(XUSB_SRCS) \ + $(XTALK_SRCS) \ + $(MPPTALK_SRCS) \ + $(ASTRIBANK_SRCS) \ + $(ABHEXLOAD_SRCS) \ + $(ABTOOL_SRCS) \ + $(ABALLOW_SRCS) \ + $(ECHO_LOADER_SRC) + +# Derive object files from source list +XUSB_OBJS = $(XUSB_SRCS:.c=.o) +XTALK_OBJS = $(XTALK_SRCS:.c=.o) $(XUSB_OBJS) +MPPTALK_OBJS = $(MPPTALK_SRCS:.c=.o) $(XTALK_OBJS) +ASTRIBANK_OBJS = $(ASTRIBANK_SRCS:.c=.o) $(MPPTALK_OBJS) +ABHEXLOAD_OBJS = $(ABHEXLOAD_SRCS:.c=.o) $(ASTRIBANK_OBJS) $(ECHO_LOADER) $(OCT_HERE_OBJS) +ABTOOL_OBJS = $(ABTOOL_SRCS:.c=.o) $(ASTRIBANK_OBJS) +ABALLOW_OBJS = $(ABALLOW_SRCS:.c=.o) $(ASTRIBANK_OBJS) + +TARGETS = .perlcheck astribank_is_starting +PROG_INSTALL = astribank_is_starting +MAN_INSTALL = $(PROG_INSTALL:%=%.8) +ifeq (1,$(PBX_USB)) +TARGETS += \ + astribank_tool \ + astribank_hexload \ + astribank_allow \ + test_parse +PROG_INSTALL += astribank_tool astribank_hexload astribank_allow +endif +ifneq (,$(PERLLIBDIR)) +PROG_INSTALL += $(PERL_SCRIPTS) +TARGETS += $(PERL_MANS) +endif + +all: $(TARGETS) + +docs: $(PERL_MANS) + +install: all + $(INSTALL) -d $(DESTDIR)$(SBINDIR) + $(INSTALL) $(PROG_INSTALL) $(DESTDIR)$(SBINDIR)/ + $(INSTALL) -d $(DESTDIR)$(DATADIR) + $(INSTALL) xpp_fxloader astribank_hook $(DESTDIR)$(DATADIR)/ + $(INSTALL) waitfor_xpds $(DESTDIR)$(DATADIR)/ + $(INSTALL) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_DATA) xpp.rules $(DESTDIR)$(udevrulesdir)/ + $(INSTALL) -d $(DESTDIR)$(MANDIR) + $(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/ + $(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR) + $(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/ + # for backward compatibility and for hotplug users: + ln -sf $(DATADIR)/xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/ +ifneq (,$(PERLLIBDIR)) + $(INSTALL) -d $(DESTDIR)$(PERLLIBDIR) + for i in $(PERL_DIRS); \ + do \ + $(INSTALL) -d "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ + done + for i in $(PERL_MODS); \ + do \ + $(INSTALL_DATA) "perl_modules/$$i" "$(DESTDIR)$(PERLLIBDIR)/$$i"; \ + done +endif + +CFLAGS += -I. -Ixtalk -Wall -Werror + +astribank_hexload: $(ABHEXLOAD_OBJS) +astribank_hexload: LIBS+=$(EXTRA_LIBS) $(USB_LIB) +astribank_hexload: CFLAGS+=$(OCT_CFLAGS) + +astribank_tool: $(ABTOOL_OBJS) +astribank_tool: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +astribank_allow: $(ABALLOW_OBJS) +astribank_allow: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +astribank_is_starting: astribank_is_starting.o +astribank_is_starting: LIBS+=$(EXTRA_LIBS) + +hex2iic: hex2iic.o iic.o hexfile.o + +test_parse: test_parse.o hexfile.o +test_parse: LIBS+=$(EXTRA_LIBS) $(USB_LIB) + +ifneq (no,$(USE_OCTASIC)) +.octasic.depend: $(OCTASIC_DIR)/octasic-helper Makefile ../config.status + $(CC) -MM $(OCT_CFLAGS) \ + `$(OCTASIC_DIR)/octasic-helper objects | \ + tr -s ' ' '\n' | \ + sed -e 's,.*,$(OCTASIC_DIR)/&,' -e 's/\.o$$/.c/'` > $@ + +-include .octasic.depend + +$(OCT_HERE_OBJS): Makefile + $(CC) -c $(CFLAGS) $(OCT_CFLAGS) $(OCT_DEFINES) $(OCT_SRCS) + +endif + + +%: %.o + $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + +.perlcheck: $(PERL_SCRIPTS) + for i in $^; do perl -I./perl_modules -c $$i || exit 1; done + touch $@ + +clean: + $(RM) .depend .octasic.depend *.o xtalk/*.o $(OCT_HERE_OBJS) $(TARGETS) + +.PHONY: depend +ifeq (1,$(PBX_USB)) +depend: .depend +.depend: *.c *.h xtalk/*.c + @echo "Calculating dependencies" + @if ! $(CC) $(CFLAGS) $(OCT_CFLAGS) -MM $(SRCS) > $@; then $(RM) $@; exit 1; fi + +include .depend +endif diff --git a/xpp/README.Astribank b/xpp/README.Astribank new file mode 100644 index 0000000..2e0001f --- /dev/null +++ b/xpp/README.Astribank @@ -0,0 +1,1677 @@ +Xorcom Astribank Documentation +============================== +Xorcom Team +$Revision$, $Date$ + +This file documents the DAHDI drivers for the Xorcom Channel Bank. + +It is generally a more technical document than the +http://www.xorcom.com/product-manuals/product-manuals.html[Astribank +User Manual] + +An HTML version of the latest version of this document could be found at +http://docs.tzafrir.org.il/dahdi-tools/README.Astribank.html[] + +Introduction +------------ +The Xorcom Astribank is a USB-connected channel-bank. An Astribank may +have up to 4 modules: + +PRI:: + 1, 2 or 4 ports of E1 or T1. Can only be the first (left-most) module + of the Astribank. Note that each port has physically a pair of ports, + where the top one has crossed wiring. + +BRI:: + 2, 4 or 8 ports of BRI. Can only be used as the first (left-most) + module of the Astribank. + +FXO:: + 8 ports of FXO (connector to an analog PSTN line). + +FXS:: + 8 ports of FXS (connector to an analog phone). If used as the first + (left-most) module, it will also have 2 output lines and 4 input lines + that will appear on DAHDI like standard DAHDI ports. The input and + output ports are connected from the two RJ-45 connectors on the right + side of the module. + +There is also a 6FXS-2FXO module that is essentially an FXS module with +six lines instead of 8 (but still with the input and output ports) and +an FXO module of two ports. + + +Building and Installation +------------------------- +Apart from the standard DAHDI build requirements, you also need: + +* *libusb development headers* to build the Astribank firmware tools + (astribank_tool, astribank_hexload, astribank_allow). + This is typically the package libusb-dev on Debian (and derivatives + like Ubuntu) or libusb-devel on RedHat (and derivatives like + CentOS/Trixbox). +* *Echo Canceller Module firmware*: If you have an Astribank with an + echo canceller module, see the following section. + +Follow the build instructions of DAHDI-linux and DAHDI-tools. But +Basically, in dahdi-linux run: + + make + make install # as root + +And later in dahdi-tools: + + ./configure + make + make install # as root + + +Echo Canceller Firmware +~~~~~~~~~~~~~~~~~~~~~~~ +If you install from source, you should copy OCT6104E-256D.ima to the +source tree (before running make install: + + wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima + mv OCT6104E-256D.ima drivers/dahdi/xpp/firmwares/ + +Alternatively, if you have already installed DAHDI-linux (e.g. from a +binary package that does not include the firmware) you can just copy +it directly to the target directory, /usr/share/dahdi using: + + cd /usr/share/dahdi + wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima + + +Installation Scenarios +~~~~~~~~~~~~~~~~~~~~~~ +Below are some commented sequences of commands that can be used at some +common scenarios. Those scenarios begin only after you installed the +software (dahdi-linux, dahdi-tools, asterisk, etc.). + +New Installation Scenario +^^^^^^^^^^^^^^^^^^^^^^^^^ +Installing Astribank on a system where there's no existing Astribank. +You install the driver when the Astribank was already connected: + +-------------------------------------------- +# If you had the hardware already connected: Load just the USB firmware +/usr/share/dahdi/xpp_fxloader usb +# (you could use 'load' instead of 'usb' but this is also a good test +# that automatic load through firmware is also in place) +dahdi_hardware -v +# wait until the Astribank has a product ID of 11x2 +sleep 5 # Just wait a little bit +dahdi_hardware -v # now that you see that all's well: +/etc/init.d/dahdi start +# generate configuration: +dahdi_genconf +# Apply it: +dahdi_cfg + +# edit /etc/asterisk/chan_dahdi.conf to #include dahdi-channels.conf or +# copy its content to the end of chan_dahdi.conf +# +# This stops existing DAHDI calls, if any, but does no other harm: +asterisk -rx 'dahdi restart' +-------------------------------------------- + + +Upgrade Scenario +^^^^^^^^^^^^^^^^ +Upgrading is roughly the same as a new installation. But in many cases +you begin with resetting the firmware. + +I also assume here that the configuration is valid, and hence I don't +generate it. + +-------------------------------------------- +# If you need to reset the firmware: +/usr/share/dahdi/xpp_fxloader reset +# (you could use 'load' instead of 'usb' but this is also a good test +# that automatic load through firmware is also in place) +dahdi_hardware -v +# wait until the Astribank has a product ID of 11x2 +sleep 5 # Just wait a little bit +dahdi_hardware -v # now that you see that all's well: +/etc/init.d/dahdi start +# +# This stops existing DAHDI calls, if any, but does no other harm: +asterisk -rx 'dahdi restart' +-------------------------------------------- + + +Sample Configurations +--------------------- +We generally recommend to generate the configuration by using utility +dahdi_genconf which are included with DAHDI. Nevertheless, the following +can serve as reference configurations for a system where Astribank devices +are used. + +Also refer to the general README for documentation of the other DAHDI +configuration files. + +xpp.conf: Astribank Initialization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/etc/dahdi/xpp.conf is read by the initialization scripts of Astribank +modules: +----------------------------------------------------------- +# /etc/dahdi/xpp.conf +# +# This file is used to configure the operation +# of init_card_* initialization scripts. +# + +# Adds many more tracing messages that are sent to syslog: +#debug 1 + +# xpd_pri: E1 or T1. The default is E1 for all the ports. +# Setting T1 instead: +#pri_protocol T1 +# +# Or if you actually want to mix E1 and T1: +#pri_protocol/xbus-00/xpd-02 T1 +#pri_protocol/connector:usb-0000:00:1d.7-7/xpd-03 T1 +#pri_protocol/label:usb:0000183/xpd-03 T1 +# If several definitions can refer to a port, the last wins. +# If none applies, the default of E1 holds. + +# FXO: country to adjust settings to: +#opermode FRANCE + +# Don't run power calibration on the FXS units. This can save time +# but can also get you unit randomly disconnect, if badly used: +#fxs_skip_calib 1 +----------------------------------------------------------- + + +xpp_order: Explicitly order Astribanks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(This feature is available as of DAHDI 2.2) + +On a system with multiple Astribank you would normally want to guarantee +that Astribanks are registered in the same order regardless of the order +in which they are connected or detected. Assuming that you register them +all at the same time. In order to do that, you should list the +Astribanks explicitly under /etc/dahdi/xpp_order . + +Astribanks that are listed there are registered first (according to the +order of lines in the files). Astribanks not listed there are added +last, and sorted by the 'USB connector' string. + +You can identify an Astribank in two ways: + +Label:: + each Astribank (except some really old ones) has a label . This + identifies the actual Astribank box. + +Connector:: + Identify the path the Astribank is connected through. E.g.: to what + USB port you connected it. + +Identifying an Astribank by the label seems simpler and more +predictable. Though it may have some slightly surprising effects if +replace one Astribank with another. + +The sample configuration file: +----------------------------------------------------------- +# +# This is an optional configuration file for ordering +# Dahdi registration. +# +# It is read from /etc/dahdi/xpp_order. This location +# may be overriden via the environment variable XPPORDER_CONF +# +# Lines may contain: +# - The Astribank label (verbatim) +# - The Astribank connector string (prefixed with @) +# Ordering number of each listed Astribank is determined +# by its position in this file. +# Astribanks not listed in this file, get an ordering +# number of 99 (last). +# +# Astribanks with same ordering number are sorted by their +# connectors (to preserve legacy behaviour). +# +# Examples: +#usb:1234 +#@usb-0000:06:02.2-2 +----------------------------------------------------------- + +In order to generate one that includes all the Astribanks in the system +with the current order in which they are connected, use: + + dahdi_genconf xpporder + +For more technical details see the section <<_registering_in_dahdi>> +below. + + +/etc/dahdi/system.conf +~~~~~~~~~~~~~~~~~~~~~~ + +Astribank 8 +^^^^^^^^^^^ + fxoks=1-14 + +Astribank 6FXS/2FXO +^^^^^^^^^^^^^^^^^^^ + fxoks=1-12 + fxsks=13-14 + +Astribank 16: 8FXS/8FXO +^^^^^^^^^^^^^^^^^^^^^^^ + fxoks=1-14 + fxsks=15-22 + +Astribank 4 BRI +^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE + # Ports 2,4: NT + span=1,1,1,ccs,ami + span=2,0,1,ccs,ami + span=3,2,1,ccs,ami + span=4,0,1,ccs,ami + bchan=1-2,4-5,7-8,10-11 + ; if you applied the bri_dchan patch: + ;dchan=3,6,9,12 + hardhdlc=3,6,9,12 + +Astribank 4 PRI E1 +^^^^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE (CPE) + # Ports 2,4: NT (Net) + span=1,1,1,ccs,hdb3,crc4 + span=2,0,1,ccs,hdb3,crc4 + span=3,2,1,ccs,hdb3,crc4 + span=4,0,1,ccs,hdb3,crc4 + bchan=1-15,17-30,31-45,47-60,61-75,77-90,91-105,107-120 + dchan=16,46,76,106 + +Astribank 4 PRI T1 +^^^^^^^^^^^^^^^^^^ + # Assumed ports settings: + # Ports 1,3: TE (CPE) + # Ports 2,4: NT (Net) + span=1,1,1,esf,b8zs + span=2,0,1,esf,b8zs + span=3,2,1,esf,b8zs + span=4,0,1,esf,b8zs + bchan=1-23,25-47,49-71,73-95 + dchan=24,48,72,96 + + +/etc/asterisk/chan_dahdi.conf +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Astribank 8 +^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-8 + + ; output ports: + context=astbank-output + channel => 9-10 + ; input ports: + immediate=yes + context=astbank-input + channel => 11-14 + immediate=no + +Astribank 6FXS/2FXO +^^^^^^^^^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-6 + + ; output ports: + context=astbank-output + channel => 7-8 + ; input ports: + immediate=yes + context=astbank-input + channel => 9-12 + immediate=no + + ; FXO ports + signalling=fxs_ks + context=from-pstn + callerid=asreceived + channel => 13-14 + +Astribank 16: 8FXS/8FXO +^^^^^^^^^^^^^^^^^^^^^^^ + [channels] + signalling=fxo_ks + ; The real analog ports: + context=from-internal + echocancel=yes + ; echocancelwhenbriged=yes + ; echotraining=no + channel => 1-8 + + ; output ports: + context=astbank-output + channel => 9-10 + ; input ports: + immediate=yes + context=astbank-input + channel => 11-14 + immediate=no + + ; FXO ports + signalling=fxs_ks + context=from-pstn + callerid=asreceived + channel => 15-22 + +Astribank 4 BRI +^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = euroisdn + callerid = asreceived + + ; TE ports: + signalling = bri_cpe_ptmp + ;signalling = bri_cpe + context = from-pstn + group = 1,11 + channel => 1,2 + + group = 1,13 + channel => 7,8 + + ; NT ports: + signalling = bri_net_ptmp + ;signalling = bri_net + context = from-internal + group = 2,12 + channel => 4,5 + + group = 2,14 + channel => 10,11 + +Astribank 4 PRI E1 +^^^^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = euroisdn + callerid = asreceived + + ; TE ports: + signalling = pri_cpe + context = from-pstn + group = 1,11 + channel => 1-15,17-30 + + group = 1,13 + channel => 61-75,77-90 + + ; NT ports: + signalling = pri_net + ;signalling = pri_net + context = from-internal + group = 2,12 + channel => 31-45,47-60 + + group = 2,14 + channel => 91-105,107-120 + +Astribank 4 PRI T1 +^^^^^^^^^^^^^^^^^^ + ; Assumed ports settings: + ; Ports 1,3: TE + ; Ports 2,4: NT + [channels] + switchtype = national + callerid = asreceived + + ; TE ports: + signalling = pri_cpe + context = from-pstn + group = 1,11 + channel => 1-23 + + group = 1,13 + channel => 49-71 + + ; NT ports: + signalling = pri_cpe + ;signalling = pri_net + context = from-internal + group = 2,12 + channel => 25-47 + + group = 2,14 + channel => 73-95 + + +/etc/asterisk/extensions.conf +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sample dialplan (extensions.conf) for all the above: + +----------------------------------------------------------- +[phones-dahdi] +; With Asterisk 1.4 you will may need to use here 'Zap' instead of +; DAHDI. See Zaptel-to-DAHDI.txt . +; +; 6001 will dial to channel 1, 6020, to DAHDI channel 20, etc. +exten => _6XXX,1,Dial(DAHDI/${EXTEN:1}) +; Useful for debugging trunks. Will potentially allow users to +; bypass context limitations. +;exten => _6XXX.,1,Dial(DAHDI/${EXTEN:1:3}/${EXTEN:4}) + +[trunk] +; A number that begins with 9: dial it through a trunk +; (we put FXO channels and TE channels in group 0). +; The leading 9 is stripped. +exten => _9.,1,Dial(DAHDI/g0/${EXTEN:1}) +; dialing a number that begins with 83 will dial it through +; span 3, and so forth. The two leading digits are stripped. +; (Each digital span is also added to group 10+span number). +exten => _8X.,1,Dial(DAHDI/g1${EXTEN:1:1}/${EXTEN:2}) + +[from-internal] +; The context of FXS ports: analog phones. +; They are allowed to dial to all other phones +include => phones-dahdi +; They are also allowed to call through the trunk: +include => trunk +; some simple tests: +include => astbank-test + +[from-pstn] +; Calls from the PSTN enter here. Redirect calls to an IVR +; or a default extension in the s context here. In this case we +; redirect calls to DAHDI channel 1: +exten => s,1,Dial(DAHDI/1) + +; Alternatively, the following will redirect you to the demo IVR +; from the sample extensions.conf of Asterisk: +include => demo + +; An extra context with some simple tests +[astbank-test] +; 200: echo test +exten => 200,1,Answer +exten => 200,n,Wait(1) +exten => 200,n,Echo() +exten => 200,n,Hangup + +; 203: say extension number. Will only work if caller ID +; is properly set in chan_dahdi.conf / dahdi-channels.conf +exten => 203,1,Answer +exten => 203,n,Wait(1) +exten => 203,n,SayNumber(${CALLERID(num)}) +exten => 203,n,Hangup + +[astbank-input] +exten => s,1,Set(DAHDI_CHAN=${CUT(CHANNEL,-,1)}) +exten => s,n,Set(DAHDI_CHAN=${CUT(DAHDI_CHAN,/,2)}) +; 11 is the number of the first input port. At least in the sample +; configuration below. +;exten => s,n,Set(INPUT_NUM=$[${DAHDI_CHAN}-11)]) +; The sample below just logs the signal. +exten => s,n,NoOp(Got signal from DAHDI Channel ${DAHDI_CHAN}) +; Alternatively: +;exten => s,n,System(run something) + +; No. We did not forget the context astbank-outputs. Output +; ports only get calls from the PBX. Thus they don't need a context +; of their own. Sending them to a context of their on makes +; 'dahdi show channels' in the CLI provide useful display, though. +----------------------------------------------------------- + + +Troubleshooting +--------------- +The following commands provide useful information for debugging: + +lsusb Test +~~~~~~~~~~ +Check USB level status. You can use one of the following utilities for it: + + dahdi_hardware -v + or + lsusb | grep e4e4 + +- Look for the USB Product ID (the second number after e4e4). +- If you see *11x2* (e.g: 1152)- the FPGA firmware has been loaded. + Move on. + dahdi_hardware will also show you some more details if the driver + is loaded while the lsusb will just list the device. +- If it shows something as product ID *11x0* - the USB firmware is not + loaded. Maybe you need to run fxload. Or maybe just unplug and plug again + the device. Also make sure that you have fxload installed. +- If lsusb shows the Product ID as *11x1* - only the USB firmware is loaded + and not the FPGA firmware is loaded. If this is still the case after + a while - either the firmware loading has failed or you don't have + astribank_hexload/astribank_tool. Make sure you have libusb-dev(el) + installed when building DAHDI. After you have installed it, you may need + to re-run ./configure . +- It should list all of your Astribank devices. If it doesn't (for + more than period of time needed for the initial firmware + loading) - Check that the Astribank is connected indeed. + + +DAHDI Registration +~~~~~~~~~~~~~~~~~~ +Check if the Astribank spans are registered with DAHDI: + + dahdi_registration + +- This should give useful results after the drivers have identified + and your devices are initialized. +- It should list all Astribank XPDs. For each of them it should write + "on" or "off". If the registration status is "off", then it means that + the span has not been registered in DAHDI and therefore can not be used + yet. +- Registration is normally done as part of `/etc/init.d/dahdi start`. + If you want to register the spans manually, then run command: + `dahdi_registration on` . + + +DAHDI Level Information +~~~~~~~~~~~~~~~~~~~~~~~ +You can get some information regarding DAHDI channels by running one of the +following commands: + + lsdahdi + or + cat /proc/dahdi/* + +- Those two are almost the same. The lsdahdi produced more correctly sorted + output if you have more than 10 spans, and also make the output listing + looks a little bit nicer. +- You can see if your DAHDI spans and channels were loaded, if + they were configured by dahdi_cfg and if they are in use (typically by + Asterisk). + For example: + Not configured Astribank FXS channel will be displayed as: + + 42 FXS + +- When *dahdi_cfg* has applied the configuration of the channel (from + /etc/dahdi/system.conf), you will see an extra column for the signalling + type of the channel. The same channel after it has been configured: + + 42 FXS FXOKS + +- If a program (which is typically Asterisk) uses it, you'll see: + + 42 FXS FXOKS (In use) + + + +Asterisk Level Information +~~~~~~~~~~~~~~~~~~~~~~~~~~ + asterisk -rx 'dahdi show channels' + +- If you get error "Unable to connect to remote asterisk" then it + means that the Asterisk is not running. It is possible that Asterisk + has failed to start due to misconfigured chan_dahdi.conf or whatever reason. + Check /var/log/asterisk/messages or /var/log/asterisk/full . +- If you get the error that "there is no such command" then it means that + chan_dahdi.so is not loaded. There are two reasons for such problem: + * chan_dahdi.so is not even built. Check if the file exists: + + ls -l /usr/lib/asterisk/modules/chan_dahdi.so + + * the chan_dahdi.so file exists but it is not loaded. Try to load it manually: + + asterisk -rx 'module load chan_dahdi.so' + + * In some cases chan_dahdi failed to load properly and needs to be unloaded + before re-loading: + + asterisk -rx 'module unload chan_dahdi.so' + asterisk -rx 'module load chan_dahdi.so' + +- You see "pseudo" channel only. It means that you have not configured any + channels. If you have configured channels in chan_dahdi.conf, you may + need either to restart the Asterisk or unload/load chan_dahdi.so manually. + You can use the following Asterisk CLI commands for it: `unload chan_dahdi.so` + and `load chan_dahdi.so` + + +Known Issues +~~~~~~~~~~~~ +Empty /proc dir +^^^^^^^^^^^^^^^ +.Symptoms: +- Error message: + + "ERR-xpd_fxo: XBUS-00/XPD-00: Failed initializing registers (-22)" + +- Likewise for all XPDs. +- The directory /proc/xpp exists but is empty (not even the files + 'xbuses' and 'sync'). + +.Cause: +The driver failed to recreate the procfs directory /proc/xpp and hence +everything under it. This is because it has already existed. And it +existed because a process still uses it. This is typically because you +have a shell whose working directory is /proc/xpp or somewhere under +it: + + # lsof /proc/xpp + COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME + bash 2741 root cwd DIR 0,3 0 4026532684 /proc/xpp + +.Fix: +Move that process from that directory, or close the file it uses from +under /proc/xpp and reload the dahdi / xpp drivers. + + +Bad Firmware Version +^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +- An Astribank finishes initialization quickly, the /proc/XBUS-nn + directory has no XPD-mm subdirectories. +- Error in the kernel logs about: + + NOTICE-xpp: XBUS-00: XPD at 00: type=6.0 has bad firmware revision 2.6 + +.Cause: +This is normally caused by an Astribank with an older firmware connected +to a + +The protocol version supported by the firmware will typically be the same +one as in the device initialization scripts installed to +/usr/share/dahdi . Hence if this version installed +`/usr/share/dahdi/init_card_3_29` it will probably include firmware of +protocol version 29. + +.Fix: +Reset the firmware: + + /usr/share/dahdi/xpp_fxloader reset + +Or disconnect the Astribank from the power and reocnnect. On some older +versions of the USB firmware resetting the firmware (or any operation of +astribank_tool) would fail if the driver is loaded. Hence you would need to +run `rmmod xpp_usb` . In the end, reload the drivers. + + +USB Errors at Shutdown +^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +You see USB-related errors similar to the following whenever you shut +down the drivers of the Astribank or disconnect its drivers: + + ERR-xpp_usb: XBUS-00: Failed to submit a receive urb + +.Cause: +This is a normal part of the shutdown of the USB connection. + +.Fix: +Ignore them. Unless the USB should not have disconnected at that time. + + +BRI Layer 1 Down +^^^^^^^^^^^^^^^^ +.Symptoms: +With the BRI module only, and not in the middle of an active call, you +notice that suddenly the line goes down. The LED of the port stops +blinking, layer1 not listed as "active" in the bri_info file in +/proc/xpp, and the span is in RED alarm in DAHDI. + +You may also see an error message such as: + + NOTICE-xpd_bri: XBUS-00/XPD-02: D-Chan RX Bad checksum: [2A:01=FC] (252) + +from the exact time of the disconnecting. + +.Cause: +This is expected with most european BRI PtMP providers. If they support +PtMP, they are normally also expected to support ISDN phones, that get +the power from the provider. And thus they shut down the line whenever +there's no active call. + +Sometimes the line is shut down in the middle of a layer 2 message. In +the BRI driver the HDLC decoding/encoding is done in the card. In that +case we may get the above error. + +.Fix: +Normaly this is not a problem. The driver will re-establish a connection +once a new call needs to be made. + + +Astribank in lsusb but not in dahdi_hardware +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +You fail to find an Astribank device in the output of lsusb . But you +see it in `lsusb | grep e4e4` + +.Cause: +The perl module Dahdi::Hardware currently relies on +/proc/bus/usb/devices (from usbfs) whereas lsusb can use either that or +/dev/bus/usb . + +.Fix: +Usbfs is generally deprecated and some distributions (OpenSUSE, Ubuntu) no +longer mount it by default. Try: + + mount /proc/bus/usb + +and if that doesn't work: + + mount -t usbfs usbfs /proc/bus/usbfs + +However this is generally a cosmetic issue that only affects the listing +in dahdi_hardware. + + +Astribank not initialized: Premature packet end +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.Symptoms: +After upgrading to Zaptel 1.4.12 / 1.2.25 the initialization of the +Astribank times out. In the logs you see: + + kernel: NOTICE-xpp: XBUS-00(00): FIRMWARE: ERROR_CODE CODE = 0x3 (Premature packet end) + +.Cause: +When an Astribank is detected, the driver asks it what is its version +and what components it has. Normally if the version of the firmware and +of the driver does not match the driver gives an ugly message and fails +the initialization. + +However in the change of the protocol between versions 2.9 (29) and 3.0 +(30), the response that the new driver receives from a device with the +old version is now considered to be an illegal packet and gets +discarded. As a result, the Astribank waits till time-out for the +initialization to end. + +.Fix: +Reset the firmware of the Astribank by either: + + /usr/share/dahdi/xpp_fxloader reset + +or disconnecting it from the power and reconnecting it. + + +Reference +--------- +LEDs Indication +~~~~~~~~~~~~~~~ +The Astribank has 4 global indication leds and one or two per-port leds. +On some of the models the LEDs are located on the left side on the front +panel. If there are no separate LEDs there, then the red LEDs of the +upper left-most ports of the device are used as the indication LEDs. Don't +confuse them with green port status LEDs. + +The first led is the "Power" led. It is on if the unit gets power. +The second led is the "Active" led, which is on when there is at +least one "active" port (in a call / off-hook, though the meaning of this is +different in BRI). +The last led is called "Hardware OK", but is actually only is on in case of +the hardware failure. + +The third led is the "Sync" led. If it blinks, the device is synchronized +with the driver on the computer. If the device is selected to be the +synchronization source for all of the Astribank devices then it will blink +a quick single blink. +If the device gets synchronization from the driver, it will blink in a +more steady frequency. + +"Double blink" indicates that the unit has an FXO module, and still is +getting synchronization from the computer, and is not the synchronization +source. + +The per-port green led on analog (both FXS and FXO) indicates that the +port is off-hook. + +On the BRI, the green led indicates a TE port whereas an orange led +indicates an NT port. If the led is solid, the port is down (not even +layer-1 connection is up). If it is blinking a double blink, layer 1 +is up. A slower single blinking indicates that layer 2 is up as well +(which means that Asterisk is driving the port). + +As for the leds of the PRI ports, see the next section. + + +PRI Ports Configuration +~~~~~~~~~~~~~~~~~~~~~~~ +Astribank PRI module has two RJ-45 sockets for each PRI port. The lower +socket provides typical PRI CPE side wiring: Rx- pins 1,2; Tx - pins +4,5. The upper socket provides typical PRI Network side wiring: Rx- pins +4,5; Tx - pins 1,2. The both sockets are permanently active and you can +use any of them regardless of any configuration parameters (Both +connectors are live. And connecting both of them with a flat 8-wire +ethernet cable is a simple way to do a loop test for the port). + +Each port in the PRI module can be configured either as E1 or T1. +The default is E1, but it can be changed in xpp.conf (See the section +above). + +In addition to that, a port defaults to consider itself a CPE, or +rather, to accept timing from the remote party. To override that you +need to set the timing value to 0 (second parameter in the 'span=' line +in system.conf). + +Thus the following in system.conf will also set an orange LED: + + span=2,0,3,ccs,hdb3,crc4 + +Note that as this is only applied when dahdi_cfg is run, the port will have +the default green LED lit at the bottom until it is configured. + + +Voicemail Indication +~~~~~~~~~~~~~~~~~~~~ +Asterisk supports several forms of voicemail message waiting indication +(VMWI) on a phone connected to a FXS port. One of them is a stutter tone +sent when the phone is picked up. Another one is an FSK tone that +encodes the number of messages waiting (or 0, for none). Alternatively it +may send an ioctl call on the channel (DAHDI_VMWI) to indicate the VMWI +status on the channel. + +The DAHDI FXS device may implement any of extra three VMWI notification +methods. The Astribank currently only supports one of them (AC neon LED). +With Asterisk, as of 1.6.2 you can enable that using the following line +in the channel's config in chan_dahdi.conf: + + mwisendtype = neon + +Versions of Asterisk before 1.6.0 did not support this ioctl. You will +need to reset the module parameter <<_vmwi_ioctl,vmwi_ioctl>>. + + +Device Startup +~~~~~~~~~~~~~~ +This section describes in great depth the initialization of the Xorcom +Astribank. Normally it would not be really needed, as the standard +installation of DAHDI should put everything in place. This is generally +some documentation to read when things fail. + +Terminology +^^^^^^^^^^^ +There are some technical terms that are used in this document and in the +driver / dahdi. + +span:: + DAHDI breaks the channels it knows about to logical units called + "spans". A port in a E1/T1/ISDN card is usually a span. An whole + analog card is also a "span". You can see the list of spans as the list + of files under /proc/dahdi directory or in output of the dahdi_tool + utility. + +XBUS:: + A funny way to call an Astribank device. + +XPD:: + Basically this is a logical unit of the Astribank. It will be + registered in DAHDI as a single span. This can be either an analog + (FXS or FXO) module or a single port in case of a BRI module. + + +Loading Firmware +^^^^^^^^^^^^^^^^ +Normally this is done using the script /usr/share/dahdi/xpp_fxloader. +If it works fine, you don't need to bother reading this section. +Once the firmware is loaded the USB Vendor ID and Product ID of the Astribank +became to be e4e4 11x2, and now the driver can pick it up. + +First and foremost: the simplest and most useful tool to debug problems +is lsusb. The output of lsusb should show you if the device is connected +if its firmware is loaded. + +The firmware files are named *.hex. They are presented in the Intel hex +format. The files are copied from xpp/utils to /usr/share/dahdi folder +during the DAHDI installation. + +The Astribank needs a firmware loaded into it. Without the firmware, +the device will appear in lsusb with Vendor ID e4e4 and Product ID 11x0 +(1130, 1140, 1150, 1160 or 1163. 1163 behaves almost exactly as 1160). +The firmware loading process consists of two +stages. In the first stage the "USB" firmware is loaded by using program +fxload. When the first stage is completed the Vendor ID is e4e4 and the +Product ID is 11x1. (e.g. 1151 if it were 1150 previously). + +You can use the following command in order to load the "USB" firmware +manually: + + fxload -t fx2 -D /dev/bus/usb/MMM/NNN -I /usr/share/dahdi/USB_FW.hex + +where, + +fxload:: + A standard program that is typically part either of package 'fxload' + or 'hotplug-utils' . +/dev/bus/usb:: + On some old systems it is missing . /proc/bus/usb (usbfs) could be + used instead. +MMM:: + the first number (bus number) +NNN:: + the second number (device number) you see for the device in lsusb + +If the loading process has been completed successfully, the device +disconnects and then connects again itself with USB Product ID 11x1 +(and a new device number). + +In the second stage, the "FPGA" firmware is loaded. +The second-stage firmware loading is performed by using program +astribank_hexload and astribank_tool, which are built in the directory +xpp/utils and then copied to folder /usr/sbin during DAHDI installation. + +The command syntax is similar to the syntax of fxload. You can use the +following command in order to load the FPGA firmware manually: + + # pick the right name according to the device ID. FPGA_1161.hex is for + # 116x Astribanks: + astribank_hexload -D /dev/bus/usb/MMM/NNN -F /usr/share/dahdi/FPGA_1161.hex + # If the device has an echo canceller unit (If the unit is BRI/E1, you + # need to add an extra -A to the command-line after the -O) + #astribank_hexload -D /dev/bus/usb/MMM/NNN -O /usr/share/dahdi/OCT6104E-256D.ima + # Note the shell expantion in this line: + astribank_hexload -D /dev/bus/usb/MMM/NNN -p /usr/share/dahdi/PIC_TYPE_[1-4].hex + # reenumerate (disconnect and reconnect) + astribank_tool -D /dev/bus/usb/MMM/NNN -n + +Please note, that NNN value differs from that that was used for the +fxload command due to the fact that device has "reconnected" itself +with another Product ID number. So you need to run lsusb again and get +the new NNN value. Usually, the new value is equal to the old value +incremented by 1. + +On newer systems (e.g. Centos 4) /dev/bus/usb may not be available. In +that case, use /proc/bus/usb . usbfs should be mounted there. + + +Automatic Firmware Loading +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Udev is a framework for dynamic device nodes, which is supported in +kernel 2.6. if your udev rules are properly configured then the +firmware should be loaded automatically and you will see product ID 11x2 +(e.g.: 1152). + +Udev is mostly configured by files under /etc/udev/rules.d . The +installer of dahdi-linux installs drivers/dahdi/xpp/xpp.rules into that +directory. + +This file instructs udev to run /usr/share/dahdi/xpp_fxloader for each +time an Astribank connects and needs firmware. When the Astribank loads +firmware or when it resets its firmware it "reenumerates" - disconnects +and reconnects as a new device. + +Below are kernel log messages of an Astribank loading firmware. It firs +connects without any firmware (device no. 44). Udev tells it to load the +USB firmware. It disconnects and reconnects (45). This Udev gets the +FPGA firmware loaded into it. It disconnects again, and when it +reconnects it is now ready to talk with the driver. The last message is +from the driver. +------------------------------------- +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: New USB device found, idVendor=e4e4, idProduct=1150 +usb 7-1: New USB device strings: Mfr=0, Product=0, SerialNumber =0 +usb 7-1: USB disconnect, address 44 +usb 7-1: new high speed USB device using ehci_hcd and address 45 +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: New USB device found, idVendor=e4e4, idProduct=1151 +usb 7-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +usb 7-1: Product: Astribank +usb 7-1: Manufacturer: Xorcom LTD +usb 7-1: SerialNumber: 00000123 +usb 7-1: USB disconnect, address 45 +usb 7-1: new high speed USB device using ehci_hcd and address 46 +usb 7-1: configuration #1 chosen from 1 choice +usb 7-1: reset high speed USB device using ehci_hcd and address 46 +INFO-xpp_usb: XUSB: Xorcom LTD -- Astribank -- FPGA +------------------------------------- + +Another useful tool for tracing UDEV-related issue is the udev monitor: + + udevadm monitor + +Or with some older versions of udev: + + udevmonitor + + +Firmware Loading with Hotplug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Hotplug is an obsolete framework for doing some of the things done by +udev today. Specifically, handling kernel hotplug events. It is used in +systems with kernel < 2.6.13 (e.g. RHEL4 / Centos4 and Debian 3.1). As +such DAHDI still installs support for those. However if you package +DAHDI for a more recent distribution, you should probably avoid +including those obsolete config files. + +The relevant files installed under /etc/hotplug/usb and are +xpp/xpp_fxloader.usermap and xpp_fxloader (which is a symlink to +/usr/share/dahdi/xpp_fxloader). the usermap file has the same format as +modules.usbmap in the main kernel modules directory: it is intended to +identify a (hotplugged) device. + + +Loading The Modules +^^^^^^^^^^^^^^^^^^^ +Here is what should happen: +In short: you should plug the Astribank device(s) or have them plugged in at +the boot time. Then all the modules should be loaded automatically. +You will see xpp_usb, xpp, and some xpd_* modules in the modules list +(the output of lsmod). + +After the module xpp is loaded, you'll also be able to see the directory +/proc/xpp. For any Astribank device discovered, you will see there a +directory /proc/xpp/XBUS-n (where n is a number: typically 0). Once a unit have +been discovered you'll see subdirectories: /proc/xpp/XBUS-n/XPD-m (where +m may be another number: 0, 1 ,etc). + +Now to the ugly details: + +The driver of the Astribank is composed of several modules: + +xpp:: + The basic module, that communicates with DAHDI and provides some + common services to other modules. +xpd_fxs:: + FXS modules (analog phones). Module type 1. +xpd_fxo:: + FXO modules (Analog PSTN lines). Module type 2. +xpd_bri:: + BRI ("ISDN") modules. Module type 3. +xpd_pri:: + The module for controlling E1/T1 modules. Module type 4. +xpd_echo:: + The module for controlling hardware echo canceller modules. Module type 5. + Does not generate a span. +xpp_usb:: + The functionality needed to connect to the USB bus. + +All modules depend on xpp, and modprobing them will install xpp as well. +However the xpd_* modules are installed on-demand: no need to load +xpd_fxs if you have only Astribank FXS. + +Once an Astribank device connected and the firmware is loaded, the +Vendor-ID/Product-ID of the device will be e4e4/11x2 . The handler for that +combination is listed as the kernel module xpp_usb. Therefore, the system +runs 'modprobe xpp_usb' if that module is not already loaded. + +The module xpp_usb depends on the dahdi and xpp modules. Both of them +are loaded before xpp_usb. As usual, parameters and rules form +/etc/modprobe.conf and/or from /etc/modprobe.d/* will be applied to +the module. + +When command 'modprobe xpp_usb' returns, the span type specific modules +(e.g., xpd_fxs, xpd_fxo) may or may not have been loaded yet. + +At this point the xpp driver "asks" the box about its software +(firmware) version) and the type of telephony modules it has. According +to the answers it receives, the xpp driver will "modprobe" the required +xpd_* modules. + +When an Astribank connects, it tells the driver what ports it has. For +instance, a system with 8BRI (=type 3) ports and 3 modules of 8FXS +(=type 1) ports: +---------------------------------------------- +INFO-xpp: XBUS-00: DESCRIPTOR: 4 cards, protocol revision 30 +INFO-xpp: XBUS-00: CARD 0 type=3.0 ports=8 (2x4), port-dir=0xCC +INFO-xpp: XBUS-00: CARD 1 type=1.0 ports=8 (8x1), port-dir=0xFF +INFO-xpp: XBUS-00: CARD 2 type=1.0 ports=8 (8x1), port-dir=0xFF +INFO-xpp: XBUS-00: CARD 3 type=1.0 ports=8 (8x1), port-dir=0xFF +---------------------------------------------- + +If dahdi, xpp or xpp_usb is missing or defective, you'll get relatively +clear error messages. However if an xpd_* module fails to load (e.g.: +because it is missing), the error is less intuitive: +-------------------------------------------------- +NOTICE-xpp: xproto_get: Failed to load module for type=3. exit status=256. +NOTICE-xpp: XBUS-00: CARD 0: missing protocol table for type 3. Ignored. +-------------------------------------------------- +In this case it was because I maliciously removed the module xpd_bri +(type 3) from the system. + +This can also happen if you accidentally blacklist the relevant xpd-* +module. 'blacklist some_module' in modprobe.conf or modprobe.d/*.conf +means that a direct insmod or modprobe of their name will work, but any +attempt to load a module through its aliases will fail. Recall that the +cpd-* modules are loaded on-demand using the alias 'xpd-type-N' . + + +Device Initializations Scripts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The chips in the device need to be initialized. This requires sending a +bunch of values to certain registers in those chips. We decided that +hardwiring those values in the driver code is not a good idea. +Before registering a XPD as a span in DAHDI, we run an initialization +script: /usr/share/dahdi/init_card_N_MM where, + +* N is telephony module type: 1 for an FXS span and 2 for an FXO span, + 3 for BRI and 4 for PRI. +* MM - is a version number. Currently it equals 30. + +Those scripts must be executable. If they are not, the initiallization +will do nothing but will give no error, and the device will work in an +unexpected way, if at all. + +If because of some reasons this fails (the script is not in the place, +or the running it produced an error), then you will get an error message +in the logs and the XPD will then be removed (you won't see directory +for that XPD under the corresponding /proc/xpp/XBUS-* directory) and +will not be registered with DAHDI. + +As the XPD is initialized, you'll see the green LEDs of the ports steadily +turn on and later off ("a train of lights"). This is a bit slower than the +faster "blinking" when the XPDs register as DAHDI spans. The initialization +of an FXS XPD may take a few seconds. + + +Connect / Disconnect Hook +^^^^^^^^^^^^^^^^^^^^^^^^^ +When the Astribank has finished initialization it also notifies +userspace applications. This can be used to run a custom command when an +Astribank is connected (after it has finished initialization) or when it +has disconnected. The hook script is installed by default to +/usr/share/dahdi/astribank_hook . + + +Registering in DAHDI +^^^^^^^^^^^^^^^^^^^^ +The XPDs will not automatically register as DAHDI spans. This is +intended to allow you to set the registration order (and hence the order +of DAHDI spans and channels) among multiple Astribank devices, +or between an Astribank and a different DAHDI device. + +When the XPD registers with DAHDI, all the green LEDs will be lit for a +short while. + +Spans are normally registered with the utility dahdi_registration. Simply +running 'dahdi_registration' shows the available XPDs and whether or not +they are registered. To register: + + dahdi_registration on + +For a system with several spans you'll see a "fast train of lights". + +If you have multiple Astribank devices, dahdi_registration will +register them by the ascending order of the USB connector ID. This +means that as long as the same Astribank is connected to the same +port, the order of plugging is not important. + +You can see the USB connector ID in the verbose output of the +dahdi_hardware utility when xpp drivers are loaded. See CONNECTOR value +in the example below: + +------------------------------------------------------ +# dahdi_hardware -v +usb:004/006 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:0000148] CONNECTOR=usb-0000:00:03.3-2 + XBUS-00/XPD-00: E1_TE Span 1 DAHDI-SYNC + XBUS-00/XPD-10: FXS Span 2 + XBUS-00/XPD-20: FXS Span 3 +usb:004/007 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:0000150] CONNECTOR=usb-0000:00:03.3-6 + XBUS-01/XPD-00: FXS Span 4 + XBUS-01/XPD-10: FXO Span 5 +------------------------------------------------------ + +If you have multiple Astribank devices, dahdi_registration will register +them by the order of the "connector" field. This means that as long as +the same Astribank is connected to the same port, the order of plugging +is not important. Alternatively you can set an explicit registration +order using /etc/dahdi/xpp_order . See above in section about +<<_xpp_order_explicitly_order_astribanks,xpp_order>>. + +The registration is performed through the sysfs interface. See below +<<_sys_devices_xpp_xbus_nn_nn_m_p_span,the span attribute>>. Also note +that dahdi_registration also allows you to unregister spans, which will +work for all spans that are not in use (That is: none of their channels +is in use). + +By default, the Astribank drivers don't perform automatic span +registration on DAHDI. It is in contrast to the all known drivers of +PCI boards. Because of that, DAHDI channels related to the PCI board +spans will get lower numbers than the channels related to Astribank +devices. + +You may choose to register the XPDs with DAHDI automatically. This may +make the startup sequence a bit simpler, but is generally not +recommended on a system with more than one Astribank or an Astribank and +a different DAHDI device. This behavior may be defined by setting +parameter <<_dahdi_autoreg>> in the modprobe configuration file (A file under +/etc/modprobe.d or /etc/modprobe.conf): + + options xpp dahdi_autoreg=1 + + +Astribanks Synchronization Source +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If there is more than one Astribank on the system, all the Astribanks +keep their clock in sync. Optionally the Astribanks can synchronize +their clock to the master DAHDI device (in case it is a different DAHDI +device). Normally you just use the default init.d script or run +explicitly: + + xpp_sync auto + +(For now see the man page of xpp_sync for more information) + + +DAHDI And Above +^^^^^^^^^^^^^^^ +From here you get a standard DAHDI span. The next step is to configure +the span by running the dahdi_cfg utility. You would also need to +configure the channels in the Asterisk chan_dahdi.conf file. Only after +that you will be able to make calls through the telephony ports. + +You can use dahdi_genconf, which is included with dahdi-tools, to +generate a DAHDI and Asterisk configuration for your system. +For analog channels it works quite well, and likewise for BRI. For E1/T1 +it will probably take some tuning. + +Please refer to the general DAHDI documentation for more deatils about +DAHDI and Asterisk configuration. E.g, the README file in the +top-level directory, and + + http://voip-info.org/wiki/view/Asterisk+config+chan_dahdi.conf[] + +Alternatively, write you own configuration, based on the sample from the +"Sample Configurations" section. + + +/proc Interface +~~~~~~~~~~~~~~~ +The Astribank drivers provide their own /proc interface under /proc/xpp. +Here we review the more useful details of the procfs interface. There +are many other debugging details that are exposed through the procfs +interface. + +Also note that those details are subject to changes. Generally the +recommended stable interface are the DAHDI-perl modules and utilities +from the xpp/ directory. + + +/proc/xpp/xbuses +^^^^^^^^^^^^^^^^ +File /proc/xpp/xbuses lists the connected Astribank devices (one line +per device). + +A device is normally has status "connected". The status "missing" means that +the device has been disconnected, but Asterisk still holds channels from it +open. + + +For each Astribank device there is folder /proc/xpp/XBUS-nn and for each device +module (span in the terms of DAHDI) there is folder /proc/XBUS-nn/XPD-mm. + +/proc/xpp/XBUS-nn/XPD-mm/summary +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Contains detailed information about port statuses of the device module +(off-hook, on-hook etc.) For example, you can run the following command +in order to monitor the port statuses in the real time: + + watch -n1 cat /proc/xpp/XBUS-00/XPD-00/summary + + +/proc/xpp/XBUS-nn/XPD-mm/fxo_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Only for FXO modules. Apart from showing the status of the LEDs, it also +shows for each FXO port if it is connected to a provider: look for the +value of "battery" for that specific port, and a bunch of other +characteristics of the port. + + +/proc/xpp/XBUS-nn/XPD-mm/bri_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In addition to the usual information about the LEDs, this file also +provides useful information regarding ISDN Layer 1 and Layer 2 status. +For example, you can run the following command in order to monitor +the Layer 1 port statuses for all BRI devices in the real time: + + watch -n1 -d 'grep "Layer 1:" /proc/xpp/XBUS-*/XPD-*/bri_info' + +For the status of the D channel of the ports on all BRI spans, run: + + watch -n1 -d 'grep D-Channel: /proc/xpp/XBUS-*/XPD-*/bri_info' + + +/proc/xpp/XBUS-nn/XPD-mm/pri_info +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In addition to the usual information about the LEDs, this file also +provides useful information regarding ISDN Layer 1 and Layer 2 status. +For example, you can run the following command in order to monitor +the Layer 1 port statuses for all E1/T1 devices in the real time: + + watch -n1 -d 'grep "Layer 1:" /proc/xpp/XBUS-*/XPD-*/pri_info' + +For the status of the D channel of the ports on all PRI spans, run: + + watch -n1 -d 'grep D-Channel: /proc/xpp/XBUS-*/XPD-*/pri_info' + +Note: the layer 2 status is much more of a guesswork based on changes in +the contents of the channel that is supposed to be the D channel. + + +There are a bunch of other status files under /proc/xpp/. + + +/sys Interface +~~~~~~~~~~~~~~ +Astribanks on the system and the xpds themselves are also represented +in SysFS. SysFS is a virtual file system mounted under /sys and provides +information in a more structured way than ProcFS. In sysfs objects are +represented as directories, simple attributes are shown as files in +the directory of the object and more complex objects are subdirectories +or symbolic links to other directories. + +As with the procfs interface, we only document some interesting +attribuets. Some attributes are writable and hence writing to them +without knowing what you do is not exactly wise. + +Like the procfs interface, this interface is subject to changes and +should not be considered a stable interface. Please use the DAHDI-perl +modules and utilities. + + +Astribanks in SysFS +^^^^^^^^^^^^^^^^^^^ +Each astribank is represented as a device under +/sys/bus/astribanks/devices , with the name xbus-NN, where NN is its +two-digit number (e.g.: 00, 01). + +===== /sys/bus/astribanks/devices/xbus-NN/cls +CLear Statistics: writing to this file clear the procfs statistics for +this Astribank. + +===== /sys/bus/astribanks/devices/xbus-NN/connector +Connector string for the device. The place to which the Astribank is +connected. e.g: usb-0000:00:03.3-2 + +===== /sys/bus/astribanks/devices/xbus-NN/label +The label string of the Astribank unit. E.g: usb:00000135 + +===== /sys/bus/astribanks/devices/xbus-NN/status +'connected' (normal operation) or 'disconnected' (has been disconnected, +some channels are still open). + +===== /sys/bus/astribanks/devices/xbus-NN/timing +Provides some statistics in case the Astribank is not the sync source. +The format of this file is subject to future changes. + +===== /sys/bus/astribanks/devices/xbus-NN/waitfor_xpds +Reading from this file only returns when the Astribank has finished +initialization of the XPDs or in case of a timeout. It prints the number +of XPDs to initialize, and the number initialize. Unless something went +wrong, those two numbers are the same. Once the span was initialized, +reading from this file returns immediately: + + XPDS_READY: XBUS-00: 3/3 + +===== /sys/bus/astribanks/devices/xbus-NN/xbus_state +Reading from it prints the name and number of the state of the +Astribank. This file is also writable: you can write either 'stop' to +disconnect the specific Astribank, or 'start' to reconnect it. + +===== /sys/bus/astribanks/drivers/xppdrv/sync +(An attribute of the generic Astribanks driver) + +The synchronization source. Normally the number of the astribank that is +the synchronization master, or 'SYNC=DAHDI' if Astribanks are +synchronized from a different DAHDI device. Normally you should just use +xpp_sync, though. + +Current possible writable values: + +:: + Make the Astribank XBUS- the sync source for other Astribanks. + +DAHDI:: + Make the Astribanks synchronize with the DAHDI timing master span. + You probably need this to get faxes from a non-Astribank adapter to an + Astribank. + + +XPDs in SysFS +^^^^^^^^^^^^^ +Under the Astribank you'll find a subdirectory for each of its XPDs +("spans"). The name of the directory is composed of three numbers: + +:: + +astribank:: + Two-digit name of the Astribank in which this XPD is in. If it is + xbus-03, you will see there '03'. + +module:: + The number of the Astribank module: from 0 (left-most) to 3 + (right-most). + +subunit:: + In a module that has several spans: the number of the span. In + practice this is only for BRI and PRI and hence the module number will + always be 0 in this case. + +The two-digit number of the XPD in the procfs interface is in fact +. + +Under this you see several attributes. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/blink +You can write here a number which will be considered to be a bitmask +of the ports that should blink (0 - no blinking). Reading from here +shows that bitmask. If you think that this is complicated, just use +xpp_blink. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/chipregs +Provides direct read/write interface to the registers of each chip. +Reading from the file shows the result of the last read request. To make +either a read request or a write request you need to write to that file. + +It is mainly used by the initialization scripts (init_card_*). + +Incorrect usage of this file is one possible way of damaging the +Astribank. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/fxo_battery +(Only on FXO) - shows ports that have (+) or don't have (-) battery +current. That is: which ones are connected to an active FXS on the +other side. + +current. That is: which ones are connected to an active FXS on the +other side. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/offhook +Shows ports that are (1) or are not (0) off-hook. When a channel is +not off-hook. For BRI and E1/T1 the value is 1 if the span is in use. +This value can also be used to get the number of lines (channels) in +this XPD: the count of items in this list. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/span +is a read/write file. Reading from it gives 0 if the span is +unregistered, or the span number if it is registered. + +Writing to it allows manual registration / unregistration from DAHDI: +writing 1 registers a span (if it wasn't already registered) and writing +0 attempts to unregister it (if it is registered. Span unregistration +will fail if some channels from the span are used (e.g: by Asterisk). + +A more convenient interface to this is the command dahdi_registration that +registers or unregisters all the spans at once with a predefined order, +and this is what you should normally use. + +Alternatively you can use the parameter dahdi_autoreg to register spans +automatically. But this is only recommended on a system with a single +Astribank and no other DAHDI device. + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/driver +This is a standard sysfs feature: from the directory of the device you +have a link called "driver" to the directory of the driver that +handles it. One specific interesting thing is that this allows you to +easily see all the XPDs of the same type, as they are linked again +from the driver's directory. + + +===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/pri_protocol +Can have either of those two: + +E1:: + Provides 31 channels, of which channel 16 is normally the D-channel. + Common in places outside of North America and Japan. This is the + default setup. + +T1:: + T1 provides 24 channels. The last one is normally the D-Channel. + Common in North America. + +This can also be set by writing the strings explicitly to the file. But +can only be done when an XPD is not a registered span. + +This writing is normally done by the device initialization script, based +on the 'pri_protocol' settings in +xref:_xpp_conf_astribank_initialization[/etc/dahdi/xpp.conf] . + + +Useful Module Parameters +~~~~~~~~~~~~~~~~~~~~~~~~ +Compilation-time defaults for the all modules can be shown as part of the +description line for the parameter in the "modinfo" command output. + +==== dahdi_autoreg +(xpp) + +Register spans automatically (1) or not (0). Default: 0. +Setting it simplifies operations with a single Astribank and no other +DAHDI hardware. However if you have such systems, automatic +registration can cause the order of spans to be unpredictable. +The standard startup scripts use 'dahdi_registration on' instead of this. + +==== initdir +(xpp) + +This is the directory containing the initialization scripts. +The default is /usr/share/dahdi . +Setting this value could be useful if that location is inconvenient for you. + +==== rx_tasklet +(xpp) + +Enable (1) or disable (0) doing most of the packets processing in +separate tasklets. This should probably help on higher-end systems with +multiple Astribanks. + +==== debug +(all modules) + +It will make the driver to print tons of debugging messages. You can +set/unset the parameter at run-time. The parameter value is a bitmask +of several values. The different bits meaning as it defined in +xpp/dahdi_debug.h: + +* 0 - Disable debug messages +* 1 - GENERAL - General debug comments. +* 2 - PCM - PCM-related messages. Tends to flood logs. +* 4 - LEDS - Anything related to the LEDs status control. The driver + produces a lot of messages when the option is enabled. +* 8 - SYNC - Synchronization related messages. +* 16 - SIGNAL - DAHDI signalling related messages. +* 32 - PROC - Messages related to the procfs interface. +* 64 - REGS - Reading and writing to chip registers. Tends to flood + logs. +* 128 - DEVICES - Device instantiation, destruction and such. +* 256 - COMMANDS - Protocol commands. Tends to flood logs. + +For example, + + echo 33 >/sys/modules/xpp/parameters/debug + +forces module xpp to print general debugging messages (1) and procfs +debugging messages (32). + +==== vmwi_ioctl +(xpd_fxs) + +Does userspace support VMWI notification via ioctl? Default: 1 (yes). + +Disable this (0) to have the driver attempt to detect the voicemail +message waiting indication status for this port from FSK messages +userspace (Asterisk) sends. Set the ports to use AC neon-lamp style +message waiting indication. The detection from the FSK messages takes +extra CPU cycles but is required with e.g. Asterisk 1.4.x . + +Also note that in order for this parameter to take effect, it must be +set before the span is registered. This practically means that it +should be set through modprobe.d files. + +See also <<_voicemail_indication,Voicemail Indication>>. + +==== usb1 +(xpp_usb) + +Enable (1) or disable (0) support of USB1 devices. Disabled by default. + +USB1 devices are not well-tested. It seems that they don't work at all +for Astribank BRI. Generally they should work with the current code, but +we expect the voice quality issues. Hence we would like to make it +very clear that you if you have a USB1 port (rather than a USB2 one, as +recommended) you will have to take an action to enable the device. + +==== poll intervals +(various) + +There are various values which the driver occasionally polls the +device for. For instance, the parameter poll_battery_interval for +xpd_fxo to poll the battery, in order to know if the telco line is +actually connected. + +The value of those parameters is typically a number in milliseconds. +0 is used to disable polling. Under normal operation there should be +no reason to play with those parameters. + +==== dtmf_detection +(xpd_fxs) + +Enable (1) or disable (0) support of hardware DTMF detection by the +Astribank. + +==== caller_id_style +(xpd_fxo) + +Various types of caller ID signalling styles require knowing the PCM +even when the line is on-hook (which is usually a waste of CPU and +bandwidth). This parameter allows fine-tuning the behaviour here: + +* 0 (default) - Don't pass extra PCM when on-hook. +* 1 ETSI-FSK: Wait for polarity reversal to come before a ring and + then start passing PCM until the caller ID has been passed. +* 2 Always: Always pass PCM. + +This parameter is read-only. It cannot be changed at run-time. + +==== battery_threshold +(xpd_fxo) + +Minimum voltage that shows there is battery. Defaults to 3. Normally you +should not need to change this, unless dealing with a funky PSTN +provider. + +==== battery_debounce +(xpd_fxo) + +Minimum interval (msec) for detection of battery off (as opposed to e.g. +a temporary power denial to signal a hangup). Defaults to 1000. As with +battery_threshold above, there's normally no need to tweak it. + + +NOTE: XPP here does not stand for X Printing Panel, XML Pull Parser, +X-Windows Phase Plane or XML Professional Publisher. It is simply the +Xorcom Peripheral Protocol, which connects a computer to a XPD (Xorcom +Peripheral Device). An XBUS (originally XPP Bus) is actually a single +Astribank device and the XPDs have become the single modules in it. diff --git a/xpp/astribank_allow.8 b/xpp/astribank_allow.8 new file mode 100644 index 0000000..2ad8d22 --- /dev/null +++ b/xpp/astribank_allow.8 @@ -0,0 +1,80 @@ +.TH "ASTRIBANK_ALLOW" "8" "29 March 2009" "" "" + +.SH NAME +astribank_allow \- License Xorcom Astribank (xpp) capabilities. +.SH SYNOPSIS +.B astribank_allow \-D \fIdevice-path\fR [ options ] + +.B astribank_allow [\-h] + +.SH DESCRIPTION +Modern Astribanks (with USB product id's 116x) contain capabilities +that may be licensed. + +.B astribank_allow +is used to upload/download the licensing information to/from the device. + +Uploading a valid license file to an Astribank, changes its capabilities. +The change becomes effective after a firmware reset (either by powering +the device off and on again, or via the \fBastribank_tool\fR full reset option). + +Downloading license from the device, produces a valid license file for its +current capabilities. This may be backed up, so the device may be later +restored to its previous capabilities. + +The license file contains both a human readable description of the +device capabilities for the end user and a hash of the licensing +information used by Xorcom to generate/modify licensed capabilities. + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +.B \-w +.RS +Write capabilities to EEPROM, otherwise read capabilities +.RE + +.B \-f \fIfilename\fR +.RS +License filename (stdin/stdout if not specified) +.RE + +.B \-m \fInum\fR +.RS +Choose the numeric code of license markers to generate. +This code select the type of \fIBEGIN\fR.../\fIEND\fR... strings +that delimit the license body. + +Valid marker codes are listed with the \fB-h\fR option. +The default (and first) code is \fB1\fR. Zero is illegal value. +.RE + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_hexload(8), astribank_tool(8) + +.SH AUTHOR +Alex Landau diff --git a/xpp/astribank_allow.c b/xpp/astribank_allow.c new file mode 100644 index 0000000..8f1ea92 --- /dev/null +++ b/xpp/astribank_allow.c @@ -0,0 +1,185 @@ +/* + * Written by Oron Peled and + * Alex Landau + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpp.h" +#include "mpptalk.h" +#include +#include "astribank_license.h" + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x80 + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}// options\n", progname); + fprintf(stderr, "\tOptions:\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n"); + fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n"); + fprintf(stderr, "\t\t[-m num] # Numeric code of License markers to generate\n"); + license_markers_help("\t", stderr); + exit(1); +} + +static int capabilities_burn( + struct astribank_device *astribank, + struct eeprom_table *eeprom_table, + struct capabilities *capabilities, + struct capkey *key) +{ + int ret; + + INFO("Burning capabilities\n"); + ret = mpp_caps_set(astribank, eeprom_table, capabilities, key); + if(ret < 0) { + ERR("Capabilities burning failed: %d\n", ret); + return ret; + } + INFO("Done\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + struct astribank_device *astribank; + struct eeprom_table eeprom_table; + struct capabilities caps; + struct capkey key; + const char options[] = "vd:D:wf:m:"; + int do_write = 0; + unsigned int marker = LICENSE_MARKER_GENERIC; + FILE *file; + char *filename = NULL; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'w': + do_write = 1; + break; + case 'f': + filename = optarg; + break; + case 'm': + marker = strtoul(optarg, NULL, 0); + if (!license_marker_valid(marker)) + usage(); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + if(!devpath) { + ERR("Missing device path\n"); + usage(); + } + DBG("Startup %s\n", devpath); + if((astribank = mpp_init(devpath, 1)) == NULL) { + ERR("Failed initializing MPP\n"); + return 1; + } + if(astribank->eeprom_type != EEPROM_TYPE_LARGE) { + ERR("Cannot use this program with astribank EEPROM type %d (need %d)\n", + astribank->eeprom_type, EEPROM_TYPE_LARGE); + return 1; + } + ret = mpp_caps_get(astribank, &eeprom_table, &caps, &key); + if(ret < 0) { + ERR("Failed to get original capabilities: %d\n", ret); + return 1; + } + if (do_write) { + unsigned int used_marker; + /* update capabilities based on input file */ + file = stdin; + if (filename) { + file = fopen(filename, "r"); + if (file == NULL) { + ERR("Can't open file '%s'\n", filename); + return 1; + } + } + ret = read_from_file(&eeprom_table, &caps, &key, &used_marker, file); + if (ret < 0) { + ERR("Failed to read capabilities from file: %d\n", ret); + return 1; + } + show_capabilities(&caps, stderr); + if (capabilities_burn(astribank, &eeprom_table, &caps, &key) < 0) + return 1; + if (file != stdin) + fclose(file); + } else { + /* print capabilities to stdout */ + file = stdout; + if (filename) { + file = fopen(filename, "w"); + if (file == NULL) { + ERR("Can't create file '%s'\n", filename); + return 1; + } + } + ret = write_to_file(&eeprom_table, &caps, &key, marker, file); + if (ret < 0) { + ERR("Failed to write capabilities to file: %d\n", ret); + return 1; + } + if (file != stdout) + fclose(file); + } + mpp_exit(astribank); + return 0; +} diff --git a/xpp/astribank_hexload.8 b/xpp/astribank_hexload.8 new file mode 100644 index 0000000..27913ff --- /dev/null +++ b/xpp/astribank_hexload.8 @@ -0,0 +1,133 @@ +.TH "ASTRIBANK_HEXLOAD" "8" "30 May 2011" "" "" + +.SH NAME +astribank_hexload \- Xorcom Astribank (xpp) firmware loader +.SH SYNOPSIS +.B astribank_hexload \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-O [-A] [-S \fIspan-specs\fR] [\fIoptions\fR] \fIimagefile\fR + +.B astribank_hexload \-D \fIdevice-path\fR \-o [\fIoptions\fR] + +.B astribank_hexload \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR + +.B astribank_hexload \-h + +.SH DESCRIPTION +.B astribank_hexload +is a second-stage firmware loader for Xorcom Astribanks. + +Note that some very old models use fpga_load(8) instead. +This legacy tool hasn't been used for several releases. +It can be found in version 2.6 and below of dahdi-tools. + +The astribank_hexload(8) program is used to load a file in the +Intel HEX format into a Xorcom Astribank. +It can be used to load either an FPGA firmware or a PIC +firmware. It is normally run by the script xpp_fxloader. + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +One of the following is required: + +.B \-F +.RS +The firmware to load is a FPGA firmware. +.RE + +.B \-p +.RS +The firmwares to load is are PIC firmwares. All (typically 4) should be +on the command-line. +.RE + +.B \-O +.RS +The firmware to load is an Octasic echo canceller firmware image file. +.RE + +.B \-o +.RS +Don't load firmware. Just print the version number of the currently-loaded +Octasic echo canceller firmware. +.RE + +.B \-E +.RS +The firmware to load is a special EEPROM burning one. +.RE + + +Other options: + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.B \-A +.RS +When loading a Octasic echo canceller firmware, set the channels of the +first Astribank module to use aLaw (G.711a). This is what you'd normally +use for BRI and E1. If not set, the default mu-Law (G.711u), which is +what you'd normally use for FXS, FXO and T1. +.RE + +.B \-S \fIspan-specs\fR +.RS +This option should only be used when loading Octasic echo canceller firmware +and only if the first Astribank module is PRI. + +Its goal is to allow specifying different \fIline-mode\fR (E1/T1/J1) in different +ports of the PRI module. \fBastribank_hexload\fR use the \fIspan-specs\fR argument +to select aLaw/uLaw for each of the PRI ports in the module. + +The \fIspan-specs\fR is a list of items separated by whitespace or commas. +Each item is composed of a port selector, colon and a \fIline-mode\fR specifier. +This syntax follows the syntax of specifiers in \fB/etc/dahdi/span-types.conf\fR. + +Examples: +.RS +3:E1 \- The 3'rd port is E1. + +*:T1 \- Any unspecified port is T1 (wildcard match). + +1:T1,2:T1,*:E1 \- First and second ports are T1, the rest are E1. +.RE + +If the \fB\-S\fR is not given, the PRI default is determined by the existance of the \fB\-A-fR option. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_tool(8) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_hexload.c b/xpp/astribank_hexload.c new file mode 100644 index 0000000..643fe57 --- /dev/null +++ b/xpp/astribank_hexload.c @@ -0,0 +1,316 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "mpptalk.h" +#include "pic_loader.h" +#include "echo_loader.h" +#include "astribank_usb.h" +#include "../autoconfig.h" + +#define DBG_MASK 0x80 +#define MAX_HEX_LINES 64000 +#define HAVE_OCTASIC 1 +#define DEF_SPAN_SPEC_FORMAT "*:%c1" /* %c: 'E' or 'T' */ + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}// hexfile...\n", progname); + fprintf(stderr, "\tOptions: {-F|-p}\n"); + fprintf(stderr, "\t\t[-E] # Burn to EEPROM\n"); +#if HAVE_OCTASIC + fprintf(stderr, "\t\t[-O] # Load Octasic firmware\n"); + fprintf(stderr, "\t\t[-o] # Show Octasic version\n"); + fprintf(stderr, "\t\t[-S ] # Set PRI type specification string\n"); +#endif + fprintf(stderr, "\t\t[-F] # Load FPGA firmware\n"); + fprintf(stderr, "\t\t[-p] # Load PIC firmware\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-A] # Set A-Law for 1st module\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + exit(1); +} + +int handle_hexline(struct astribank_device *astribank, struct hexline *hexline) +{ + uint16_t len; + uint16_t offset_dummy; + uint8_t *data; + int ret; + + assert(hexline); + assert(astribank); + if(hexline->d.content.header.tt != TT_DATA) { + DBG("Non data record type = %d\n", hexline->d.content.header.tt); + return 0; + } + len = hexline->d.content.header.ll; + offset_dummy = hexline->d.content.header.offset; + data = hexline->d.content.tt_data.data; + if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) { + ERR("Failed hexfile send line: %d\n", ret); + return -EINVAL; + } + return 0; +} + +void print_parse_errors(int level, const char *msg, ...) +{ + va_list ap; + + if (verbose > level) { + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); + } +} + +static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest) +{ + struct hexdata *hexdata = NULL; + int finished = 0; + int ret; + unsigned i; + char star[] = "+\\+|+/+-"; + const char *devstr; + + parse_hexfile_set_reporting(print_parse_errors); + if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) { + perror(hexfile); + return -errno; + } + devstr = xusb_devpath(astribank->xusb); + INFO("%s [%s]: Loading %s Firmware: %s (version %s)\n", + devstr, + xusb_serial(astribank->xusb), + dev_dest2str(dest), + hexdata->fname, hexdata->version_info); + if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) { + ERR("%s: Failed hexfile send start: %d\n", devstr, ret); + return ret; + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + + if(!hexline) + break; + if(verbose > LOG_INFO) { + printf("Sending: %4d%% %c\r", (100 * i) / hexdata->last_line, star[i % sizeof(star)]); + fflush(stdout); + } + if(finished) { + ERR("%s: Extra data after End Of Data Record (line %d)\n", devstr, i); + return 0; + } + if(hexline->d.content.header.tt == TT_EOF) { + DBG("End of data\n"); + finished = 1; + continue; + } + if((ret = handle_hexline(astribank, hexline)) < 0) { + ERR("%s: Failed hexfile sending in lineno %d (ret=%d)\n", devstr, i, ret);; + return ret; + } + } + if(verbose > LOG_INFO) { + putchar('\n'); + fflush(stdout); + } + if((ret = mpp_send_end(astribank)) < 0) { + ERR("%s: Failed hexfile send end: %d\n", devstr, ret); + return ret; + } +#if 0 + fclose(fp); +#endif + free_hexdata(hexdata); + DBG("hexfile loaded successfully\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + int opt_pic = 0; + int opt_echo = 0; + int opt_ecver = 0; +#if HAVE_OCTASIC + int opt_alaw = 0; + const char *span_spec = NULL; + char def_span_spec[sizeof(DEF_SPAN_SPEC_FORMAT)]; +#endif + int opt_dest = 0; + int opt_sum = 0; + enum dev_dest dest = DEST_NONE; + const char options[] = "vd:D:EFOopAS:"; + int iface_num; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'E': + if(dest != DEST_NONE) { + ERR("The -F and -E options are mutually exclusive.\n"); + usage(); + } + opt_dest++; + dest = DEST_EEPROM; + break; + case 'F': + if(dest != DEST_NONE) { + ERR("The -F and -E options are mutually exclusive.\n"); + usage(); + } + opt_dest++; + dest = DEST_FPGA; + break; +#if HAVE_OCTASIC + case 'O': + opt_echo = 1; + break; + case 'o': + opt_ecver = 1; + break; + case 'A': + opt_alaw = 1; + break; + case 'S': + span_spec = optarg; + break; +#endif + case 'p': + opt_pic = 1; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + opt_sum = opt_dest + opt_pic + opt_echo; + if(opt_sum > 1 || (opt_sum == 0 && opt_ecver == 0)) { + ERR("The -F, -E" +#if HAVE_OCTASIC + ", -O" +#endif + " and -p options are mutually exclusive, if neither is used then -o should present\n"); + usage(); + } + iface_num = (opt_dest) ? 1 : 0; + if(!opt_pic && !opt_ecver) { + if(optind != argc - 1) { + ERR("Got %d hexfile names (Need exactly one hexfile)\n", + argc - 1 - optind); + usage(); + } + } + if(!devpath) { + ERR("Missing device path.\n"); + usage(); + } +# ifdef HAVE_OCTASIC + if (!span_spec) { + snprintf(def_span_spec, sizeof(def_span_spec), + DEF_SPAN_SPEC_FORMAT, opt_alaw? 'E' : 'T'); + span_spec = def_span_spec; + } +#endif + if(opt_dest) { + /* + * MPP Interface + */ + struct astribank_device *astribank; + + if((astribank = mpp_init(devpath, iface_num)) == NULL) { + ERR("%s: Opening astribank failed\n", devpath); + return 1; + } + //show_astribank_info(astribank); + if(load_hexfile(astribank, argv[optind], dest) < 0) { + ERR("%s: Loading firmware to %s failed\n", devpath, dev_dest2str(dest)); + return 1; + } + astribank_close(astribank, 0); + } else if(opt_pic || opt_echo || opt_ecver) { + /* + * XPP Interface + */ + struct astribank_device *astribank; + + if((astribank = astribank_open(devpath, iface_num)) == NULL) { + ERR("%s: Opening astribank failed\n", devpath); + return 1; + } + //show_astribank_info(astribank); +#if HAVE_OCTASIC + if (opt_ecver) { + if((ret = echo_ver(astribank)) < 0) { + ERR("%s: Get Octasic version failed (Is Echo canceller card connected?)\n", devpath); + return 1; + } else + INFO("Octasic version: 0x%0X\n", ret); + } +#endif + if (opt_pic) { + if ((ret = load_pic(astribank, argc - optind, argv + optind)) < 0) { + ERR("%s: Loading PIC's failed\n", devpath); + return 1; + } +#if HAVE_OCTASIC + } else if (opt_echo) { + if((ret = load_echo(astribank, argv[optind], opt_alaw, span_spec)) < 0) { + ERR("%s: Loading ECHO's failed\n", devpath); + return 1; + } +#endif + } + astribank_close(astribank, 0); + } + return 0; +} diff --git a/xpp/astribank_hook b/xpp/astribank_hook new file mode 100755 index 0000000..fdfa82a --- /dev/null +++ b/xpp/astribank_hook @@ -0,0 +1,234 @@ +#! /bin/sh + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" + +set -e + +LOCK="/var/lock/twinstar_startup" + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +# For lab testing +liveconf="$dir/liveconf/dahdi" + +if [ -d "$liveconf" ]; then + dahdi_conf="$liveconf" +else + dahdi_conf="/etc/dahdi" +fi + +if [ "$XPP_HOTPLUG_DAHDI" != yes ]; then + exit 0 +fi + +export XPPORDER_CONF="$dahdi_conf/xpp_order" +export DAHDI_CFG_CMD="dahdi_cfg -c $dahdi_conf/system.conf" +export CALLED_FROM_ATRIBANK_HOOK=yes + +can_full_async() { + # Can we work aynchronously: + # - Need modern Asterisk that accept hotplug DAHDI devices. + # - Need DAHDI with "auto_assign_spans" == 0 + if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then + aas_param='/sys/module/dahdi/parameters/auto_assign_spans' + aas=`cat "$aas_param" 2>/dev/null` + if [ "$aas" = 0 ]; then + return 0 + else + $LOGGER "No async operation ($aas_param != 0)" + fi + else + $LOGGER "No async operation (ASTERISK_SUPPORTS_DAHDI_HOTPLUG!=yes)" + fi + return 1 +} + +check_xpporder_conf() { + if [ ! -r "$XPPORDER_CONF" ]; then + ( + echo "Skip($ACTION): No '$XPPORDER_CONF'" + echo "Removing uneeded startup semaphore" + astribank_is_starting -v -r 2>&1 + ) 2>&1 | $LOGGER + exit 0 + fi +} + +clean_lines() { + sed -e 's/#.*//' -e 'y/\t/ /' -e 's/^ *//' -e 's/ *$//' -e '$s/$/\n/' "$XPPORDER_CONF" +} + +matched_devices() { + ready=`grep -H READY /sys/bus/astribanks/devices/*/xbus_state | sed 's,/xbus_state.*,,'` + for dev in $ready + do + label=`cat "$dev/label"` + connector=`cat "$dev/connector"` + xbus=`echo "$dev" | sed 's,.*/,,'` + lineno=`clean_lines | egrep -n "^${label}$|^@${connector}$" | cut -d: -f1` + if [ "$lineno" != "" ]; then + #echo "$xbus: $XPPORDER_CONF:$lineno -- Match ${label} @${connector}" | $LOGGER + printf "${xbus}\t${label}\n" + else + echo "${xbus}: ${label} @${connector} not found in $XPPORDER_CONF: Ignore($ACTION)" | $LOGGER + fi + done +} + +# Wait until udev finished processing our requests +# so we know the device files were actually created +# before trying dahdi_cfg et-al. +wait_for_udev() { + UDEV_SETTLE_MAX_TIME=10 + + echo "Waiting for udev to settle down..." + if [ -x /sbin/udevsettle ]; then + # Old system, stand-alone udevsettle command + /sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME" + elif [ -x /sbin/udevadm ]; then + # Assume modern system, udevadm has settle parameter + if ! /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME" + then + echo "udevadm failed ($?)." + echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." + sleep "$UDEV_SETTLE_MAX_TIME" + fi + else + echo "No udevsettle/udevadm." + echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." + sleep "$UDEV_SETTLE_MAX_TIME" + fi + sleep 1 # Wait a bit more (races) +} + +start_dahdi() { + wait_for_udev + script=/etc/init.d/dahdi + echo "Starting $script." + "$script" start | logger -i -t "$script" + status=$? + echo "Status($script): $status" + if [ -x "$dir/twinstar_hook" ]; then + "$dir/twinstar_hook" + fi + # Finished astribanks + echo "Removing semaphore" + astribank_is_starting -v -r + rm -f "$LOCK" +} + +old_synchronous_start() { + NUM_GOOD=`matched_devices | wc -l` + NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` + echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER + if [ "$NUM_GOOD" -eq "$NUM_WANTED" ]; then + ( + # Delay the initialization of the Astribank until the filesystem + # is mounted read-write: + test_file="/var/lock/astribank_test_file" + for i in `seq 1 20`; do + if touch $test_file 2> /dev/null; then + rm -f $test_file + break + else + echo "$0: [$i] - Failed writing '$test_file'...waiting" | $LOGGER + sleep 1; + fi + done + + if ln -s "$XBUS_NAME" "$LOCK"; then + echo "START-DAHDI: Total $NUM_GOOD online." | $LOGGER + # Fork services + start_dahdi < /dev/null 2>&1 | $LOGGER + else + echo "$0: Was started: $(ls -l $LOCK)" | $LOGGER + fi + ) < /dev/null 2>&1 | $LOGGER & + fi +} + +old_synchronous_stop() { + NUM_GOOD=`matched_devices | wc -l` + NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` + echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER + if [ "$NUM_GOOD" -eq 0 ]; then + echo "All Astribanks offline" | $LOGGER + if [ -x "$dir/twinstar_hook" ]; then + "$dir/twinstar_hook" || : + fi + rm -f "$LOCK" + fi +} + +ab_list() { + find /sys/devices -name idVendor 2>/dev/null | \ + xargs grep -H 'e4e4' 2>/dev/null | \ + sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \ + sed 's,/[^/]*$,,' || : +} + +tws_watchdog_enable() { + devdir="/sys$DEVPATH" + label=`cat "$devdir/label"` + connector=`cat "$devdir/connector"` + xbus=`echo "$devdir" | sed 's,.*/,,'` + prefix="${xbus}: [${label}] @${connector}" + TWS_NOAUTOJUMPFILE="$TWS_DIR/twinstar_no_autojump" + if [ -e "$TWS_NOAUTOJUMPFILE" ]; then + $LOGGER "$prefix: ignore wd (found $TWS_NOAUTOJUMPFILE)" + else + # Re-arm Astribank watchdog + transportdir="$devdir/transport" + busnum=`cat "$transportdir/busnum" 2>/dev/null || :` + devnum=`cat "$transportdir/devnum" 2>/dev/null || :` + devaddr=`printf "%03d/%03d" "$busnum" "$devnum"` + $LOGGER "$prefix: enabling twinstar watchdog" + astribank_tool -D "$devaddr" -w 1 2>&1 | $LOGGER + fi +} + +#echo "$0: $ACTION($XBUS_NAME)" | $LOGGER +case "$ACTION" in +add) + ;; +remove) + ab=`ab_list | wc -l` + if [ "$ab" -eq 0 ]; then + $LOGGER "$prefix: No more Astribanks -- remove astribank_is_starting semaphore" + astribank_is_starting -v -r 2>&1 | $LOGGER + fi + ;; +online) + if can_full_async; then + tws_watchdog_enable + else + old_synchronous_start + fi + ;; +offline) + if can_full_async; then + : # Nothing to do + else + old_synchronous_stop + fi + ;; +*) + echo "$0: Unknown ACTION='$ACTION'" | $LOGGER + echo "$0: ARGS='$*'" | $LOGGER + echo "$0: ENV:" | $LOGGER + env | $LOGGER + exit 1 +esac + diff --git a/xpp/astribank_is_starting.8 b/xpp/astribank_is_starting.8 new file mode 100644 index 0000000..5ad0be1 --- /dev/null +++ b/xpp/astribank_is_starting.8 @@ -0,0 +1,100 @@ +.TH "ASTRIBANK_IS_STARTING" "8" "16 August 2009" "" "" + +.SH NAME +astribank_is_starting \- Mark / check is a Xorcom Astribank (xpp) is starting +.SH SYNOPSIS +.B astribank_is_starting [\-d] [\-v] [\-t \fItimeout\fB] <\-a|\-r|\-w> + +.B astribank_is_starting [\-d] [\-v] + +.B astribank_is_starting \-h + +.SH DESCRIPTION +.B astribank_is_starting +is an internal tool used by various xpp scripts to mark that there may +be an Astribank device currently initializing, and to check for that mark. + +Technically the mark is a SysV semaphore. + +.SH OPTIONS +.B \-a +.RS +.B Add. +Set the mark. Should return 0 unless there's an error. +.RE + +.B \-r +.RS +.B Remove. +Reset the mark. Should return 0 unless there's an error. +.RE + +.BI \-t timeout +.RS +.B Timeout. +Set the timeout value for the \fB\-w\fR option. Default is 60 seconds. +.RE + +.B \-w +.RS +.B Wait. +Wait for mark to be reset. Should return 0 unless there's an error. +.RE + +Without \-a or \-r: return 0 if the mark has been set, or a non-zero value +otherwise. + +.B \-d +.RS +Print debug information to stderr. +.RE + +.B \-v +.RS +Verbose execution. +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH FILES +.B /proc/sysvipc/sem +.RS +If set, the astribank should appear there with the ID 11211168 (0xAB11A0). +Naturally the ID (or rather, the usage of a semaphore in the first place) +is an implementation detail that may change. +.RE + +.SH NOTES +.B astribank_is_starting +is used to mark the fact that an Astribank may be currently reenumerating +(technically: distonnecting and connecting as a new USB device) after +loading the firmware. Thus the script that loads the firmware +(/usr/share/dahdi/xpp_fxloader) uses this utility to set the mark. + +The mark is reset by /usr/share/dahdi/waitfor_xpds , which is typically +run by the DAHDI init script and waits for all Astribanks to finish +loading. + +Q: Why do you use a semaphore? + +A: because, unlike the filesystem, it is writable at any given time. + +.SH BUGS +Option ordering matter. The \fB\-v\fR and \fB\-d\fR options should preceed +the actions (\fB\-a\fR, \fB\-r\fR and \fB\-w\fR). +The \fB\-t\fItimeout\fR option should preceed the \fB\-w\fR option. + +.SH SEE ALSO +semctl(3) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_is_starting.c b/xpp/astribank_is_starting.c new file mode 100644 index 0000000..da565c9 --- /dev/null +++ b/xpp/astribank_is_starting.c @@ -0,0 +1,196 @@ +#include "../autoconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *progname; +static const key_t key_astribanks = 0xAB11A0; +static int debug; +static int verbose; +static int timeout_seconds = 60; + +/* If libc provides no timeout variant: try to do without it: */ +#ifndef HAVE_SEMTIMEDOP +#define semtimedop(sem, ops, n, timeout) semop(sem, ops, n) +#endif + +static void usage(void) +{ + fprintf(stderr, "Usage: %s [-d] [-t ] [-a|-r|-w]\n", progname); + exit(1); +} + +static int absem_get(int createit) +{ + int flags = (createit) ? IPC_CREAT | 0644 : 0; + int absem; + + if((absem = semget(key_astribanks, 1, flags)) < 0) + absem = -errno; + return absem; +} + +static int absem_touch(void) +{ + int absem; + + if((absem = absem_get(1)) < 0) { + perror(__FUNCTION__); + return absem; + } + if(semctl(absem, 0, SETVAL, 0) < 0) { + perror("SETVAL"); + return -errno; + } + if(debug) + fprintf(stderr, "%s: touched absem\n", progname); + if(verbose) + printf("Astribanks initialization is starting\n"); + return 0; +} + +static int absem_remove(void) +{ + int absem; + + if((absem = absem_get(0)) < 0) { + if(absem == -ENOENT) { + if(debug) + fprintf(stderr, "%s: absem already removed\n", progname); + return 0; + } + perror(__FUNCTION__); + return absem; + } + if(semctl(absem, 0, IPC_RMID, 0) < 0) { + perror("RMID"); + return -errno; + } + if(debug) + fprintf(stderr, "%s: removed absem\n", progname); + if(verbose) + printf("Astribanks initialization is done\n"); + return 0; +} + +static int absem_wait(void) +{ + int absem; + struct sembuf sops; + long now; + long start_wait; + struct timespec timeout; + + if((absem = absem_get(0)) < 0) { + perror(__FUNCTION__); + return absem; + } + sops.sem_num = 0; + sops.sem_op = -1; + sops.sem_flg = 0; + start_wait = time(NULL); + timeout.tv_sec = timeout_seconds; + timeout.tv_nsec = 0; + if(semtimedop(absem, &sops, 1, &timeout) < 0) { + switch(errno) { + case EIDRM: /* Removed -- OK */ + break; + case EAGAIN: /* Timeout -- Report */ + fprintf(stderr, "Astribanks waiting timed out\n"); + return -errno; + default: /* Unexpected errors */ + perror("semop"); + return -errno; + } + /* fall-thgough */ + } + now = time(NULL); + if(debug) + fprintf(stderr, "%s: waited on absem %ld seconds\n", progname, now - start_wait); + if(verbose) + printf("Finished after %ld seconds\n", now - start_wait); + return 0; +} + +static int absem_detected(void) +{ + int absem; + + if((absem = absem_get(0)) < 0) { + if(debug) + fprintf(stderr, "%s: absem does not exist\n", progname); + if(verbose) + printf("No Astribanks are initializing\n"); + return absem; + } + if(debug) + fprintf(stderr, "%s: absem exists\n", progname); + if(verbose) + printf("Astribanks are initializing...\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + const char options[] = "dvarwt:h"; + int val; + + progname = argv[0]; + while (1) { + int c; + int t; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'd': + debug++; + break; + case 'v': + verbose++; + break; + case 't': + t = atoi(optarg); + if(t <= 0) { + fprintf(stderr, + "%s: -t expect a positive number of seconds: '%s'\n", + progname, optarg); + usage(); + } + timeout_seconds = t; + break; + case 'a': + if((val = absem_touch()) < 0) { + fprintf(stderr, "%s: Add failed: %d\n", progname, val); + return 1; + } + return 0; + case 'r': + if((val = absem_remove()) < 0) { + fprintf(stderr, "%s: Remove failed: %d\n", progname, val); + return 1; + } + return 0; + case 'w': + if((val = absem_wait()) < 0) { + fprintf(stderr, "%s: Wait failed: %d\n", progname, val); + return 1; + } + return 0; + case 'h': + default: + fprintf(stderr, "Unknown option '%c'\n", c); + usage(); + } + } + val = absem_detected(); + return (val == 0) ? 0 : 1; +} diff --git a/xpp/astribank_license.c b/xpp/astribank_license.c new file mode 100644 index 0000000..88d2af7 --- /dev/null +++ b/xpp/astribank_license.c @@ -0,0 +1,340 @@ +/* + * Written by Oron Peled + * Copyright (C) 2012, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include "astribank_license.h" + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +static const struct boundary { + const char *name; + const char *markers[2]; +} boundaries[] = { + [LICENSE_MARKER_NONE] = { /* Skip 0 */ + }, + [LICENSE_MARKER_XORCOM] = { + "Xorcom", + { + "-----BEGIN XORCOM LICENSE BLOCK-----", + "-----END XORCOM LICENSE BLOCK-----", + }, + }, + [LICENSE_MARKER_GENERIC] = { + "Generic", + { + "-----BEGIN TELEPHONY DEVICE LICENSE BLOCK-----", + "-----END TELEPHONY DEVICE LICENSE BLOCK-----", + } + }, +}; + +void license_markers_help(const char *prefix, FILE *fp) +{ + int i; + + fprintf(fp, "%sValid license markers:\n", prefix); + for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) { + const struct boundary *b = &boundaries[i]; + if (b->markers[0] != 0) + fprintf(fp, "%s\t%d - %s\n", prefix, i, b->name); + } +} + +int license_marker_valid(unsigned int which) +{ + if (which >= ARRAY_SIZE(boundaries)) + return 0; + if (boundaries[which].markers[0] == NULL) + return 0; + return 1; +} + +static const char *marker_string(unsigned int which, int end_marker) +{ + int selector = (end_marker) ? 1 : 0; + + if (license_marker_valid(which)) { + return boundaries[which].markers[selector]; + } + ERR("gen_marker: invalid marker %d\n", which); + return NULL; +} + +static int marker_find(const char *str, int end_marker) +{ + int selector = (end_marker) ? 1 : 0; + int i; + + for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) { + const struct boundary *b = &boundaries[i]; + const char *marker_str = b->markers[selector]; + +#if 0 + DBG("marker_find(%s,%d)[%d]: %s\n", + str, end_marker, i, marker_str); +#endif + if (!marker_str) + continue; + if (strcmp(str, marker_str) == 0) + return i; + } + return 0; +} + +static int bin_to_file(void *buf, int len, FILE *f) +{ + static int bytes_on_line; + unsigned char *p = buf; + if (buf == NULL) { + if (bytes_on_line != 0) { + if (fprintf(f, "\n") != 1) + return -1; + bytes_on_line = 0; + } + return 0; + } + int i; + for (i = 0; i < len; i++) { + if (fprintf(f, "%02x", *p++) != 2) + return -1; + bytes_on_line++; + if (bytes_on_line >= 16) { + if (fprintf(f, "\n") != 1) + return -1; + bytes_on_line = 0; + } + } + return 0; +} + +int write_to_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *key, + unsigned int marker, + FILE *f) +{ + fprintf(f, "%s\n", marker_string(marker, 0)); + fprintf(f, "Version: 1.0\n"); + fprintf(f, "Timestamp: %u\n", caps->timestamp); + fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label); + fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs); + fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo); + fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri); + fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri); + fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo); + fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps)); + fprintf(f, "Data:\n"); + bin_to_file(eeprom_table, sizeof(*eeprom_table), f); + bin_to_file(caps, sizeof(*caps), f); + bin_to_file(key, sizeof(*key), f); + bin_to_file(NULL, 0, f); + fprintf(f, "%s\n", marker_string(marker, 1)); + return 0; +} + +/* + * Removes whitespace on both sizes of the string. + * Returns a pointer to the first non-space char. The string + * is modified in place to trim trailing whitespace. + * If the whole string is whitespace, returns NULL. + */ +static char *trim(char *s) +{ + int len = strlen(s); + while (len > 0 && isspace(s[len-1])) { + len--; + } + if (len == 0) + return NULL; + s[len] = '\0'; + while (isspace(*s)) + s++; + /* *s is not a space, since in this case we'd return NULL above */ + return s; +} + +static int get_key_value(char *line, char **key, char **value) +{ + char *p = strchr(line, ':'); + if (p == NULL) + return -1; + *p = '\0'; + *key = trim(line); + *value = trim(p + 1); + return 0; +} + +static int hex_digit_to_int(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + return -1; +} + +static int str_to_bin(char *line, void *buf, int maxlen) +{ + static int offset; + unsigned char *p = buf; + if (strlen(line) % 2 != 0) + return -1; + while (offset < maxlen && *line) { + uint8_t value; + char c = hex_digit_to_int(*line++); + if (c < 0 || *line == '\0') + return -1; + value = c << 4; + c = hex_digit_to_int(*line++); + if (c < 0) + return -1; + value |= c; + p[offset++] = value; + } + if (offset == maxlen && *line) + return -1; + return offset; +} + +int read_from_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *capkey, + unsigned int *used_marker, + FILE *f) +{ + char buf[256]; + char *line, *key, *value; + int lineno = 0; + unsigned int license_marker_begin = 0; + unsigned int license_marker_end; + struct table { + struct eeprom_table eeprom_table; + struct capabilities capabilities; + struct capkey capkey; + } PACKED table; + enum PARSE_STATES { + STATE_BEFORE_LICENSE = 0, + STATE_EXPECT_VERSION = 1, + STATE_EXPECT_DATA = 2, + STATE_READ_DATA = 3, + STATE_AFTER_LICENSE = 4, + } state = STATE_BEFORE_LICENSE; + + memset(&table, 0, sizeof(struct table)); + /* + * states: + * 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1. + * 1: read Version, goto 2. if not version line then error. + * 2: after BEGIN line. split line into key:value. if line is Data:, goto 3. + * 3: read binary data. if line is END_LICENSE_BLOCK goto 4. + * 4: END_LICENSE_BLOCK - ignore lines. + */ + while (fgets(buf, 256, f) != NULL) { + lineno++; + int len = strlen(buf); + if (len > 0 && buf[len-1] != '\n') { + ERR("Line %d: Line too long\n", lineno); + return -1; + } + line = trim(buf); + if (line == NULL) { + if (state > STATE_BEFORE_LICENSE && state < STATE_AFTER_LICENSE) { + ERR("Line %d: Empty line\n", lineno); + return -1; + } + else + continue; + } + switch (state) { + case STATE_BEFORE_LICENSE: + license_marker_begin = marker_find(line, 0); + if (license_marker_begin) + state = STATE_EXPECT_VERSION; + else { + ERR("Line %d: Invalid license begin block\n", lineno); + return -1; + } + break; + case STATE_EXPECT_VERSION: + if (get_key_value(line, &key, &value) < 0) { + ERR("Line %d: Can't parse line\n", lineno); + return -1; + } + if (strcmp(key, "Version") == 0) { + if (strcmp(value, "1.0") == 0) { + state = STATE_EXPECT_DATA; + } else { + ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value); + return -1; + } + } else { + ERR("Line %d: No license file version\n", lineno); + return -1; + } + break; + case STATE_EXPECT_DATA: + if (get_key_value(line, &key, &value) < 0) { + ERR("Line %d: Can't parse line\n", lineno); + return -1; + } + if (strcmp(key, "Data") == 0) { + state = STATE_READ_DATA; + break; + } + break; + case STATE_READ_DATA: + license_marker_end = marker_find(line, 1); + if (license_marker_end) { + if (license_marker_end != license_marker_begin) { + ERR("Line %d: End marker != Begin marker\n", lineno); + return -1; + } + state = STATE_AFTER_LICENSE; + break; + } + if (str_to_bin(line, &table, sizeof(table)) < 0) { + ERR("Line %d: Error in data block\n", lineno); + return -1; + } + break; + case STATE_AFTER_LICENSE: + break; + + } + } + if (state != STATE_AFTER_LICENSE) { + ERR("Invalid license file\n"); + return -1; + } + memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table)); + memcpy(caps, &table.capabilities, sizeof(*caps)); + memcpy(capkey, &table.capkey, sizeof(*capkey)); + return 0; +} + diff --git a/xpp/astribank_license.h b/xpp/astribank_license.h new file mode 100644 index 0000000..74d6a31 --- /dev/null +++ b/xpp/astribank_license.h @@ -0,0 +1,29 @@ +#ifndef ASTRIBANK_ALLOW_H +#define ASTRIBANK_ALLOW_H + +#include "mpp.h" + +enum license_markers { + LICENSE_MARKER_NONE = 0, + LICENSE_MARKER_XORCOM = 1, + LICENSE_MARKER_GENERIC = 2, +}; + +int license_marker_valid(unsigned int which); +void license_markers_help(const char *prefix, FILE *fp); + +int write_to_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *key, + unsigned int marker, + FILE *f); + +int read_from_file( + struct eeprom_table *eeprom_table, + struct capabilities *caps, + struct capkey *capkey, + unsigned int *used_marker, + FILE *f); + +#endif /* ASTRIBANK_ALLOW_H */ diff --git a/xpp/astribank_tool.8 b/xpp/astribank_tool.8 new file mode 100644 index 0000000..31f9564 --- /dev/null +++ b/xpp/astribank_tool.8 @@ -0,0 +1,86 @@ +.TH "ASTRIBANK_TOOL" "8" "29 March 2009" "" "" + +.SH NAME +astribank_tool \- Xorcom Astribank (xpp) control tool +.SH SYNOPSIS +.B astribank_tool [ options ] [ operation... ] \-D \fIdevice-path\fR + +.B astribank_tool [\-h] + +.SH DESCRIPTION +.B astribank_tool +is a tool to control the USB-level functionality of an Astribank. +The tool operates on a single Astribank at a time (given as parameter +to the \-D command line option). + +.SH OPTIONS +.B \-D +.I device-path +.RS +Required. The device to read from/write to. This is +\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR +are the first two numbers in the output of lsusb(8) or dahdi_hardware(8). +On older versions of this tool you needed a complete path to the device, +which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or +/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR. +.RE + +.B \-p \fInum\fR +.RS +Set the TwinStar port number. Either 0 or 1. + +(TODO: explain). +.RE + +.B \-r \fItype\fR +.RS +Reset the Astribank and renumerate its USB connection to power on product ID. + +Tyep can be: \fBhalf\fR or \fBfull\fR. + +(TODO: explain those). +.RE + +.B \-w 0|1 +.RS +Enable (1) or disable (0) the TwinStar watchdog. When enabled, the +Astribank will jump to the second port if this system is "not working" +and the system on the second port is available. +.RE + +.B \-Q +.RS +Query astribank properties via MPP protocol. +.RE + +.B \-n +.RS +Renumerate the Astribank product number (e.g: from 1161 to 1162). +.RE + +.B \-v +.RS +Increase verbosity. May be used multiple times. +.RE + +.B \-d \fImask\fR +.RS +Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything". +.RE + +.B \-h +.RS +Displays usage message. +.RE + +.SH SEE ALSO +fxload(8), lsusb(8), astribank_hexload(8) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen . +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common\-licenses/GPL. diff --git a/xpp/astribank_tool.c b/xpp/astribank_tool.c new file mode 100644 index 0000000..f3ca976 --- /dev/null +++ b/xpp/astribank_tool.c @@ -0,0 +1,287 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "astribank_usb.h" +#include "mpptalk.h" +#include +#include + +#define DBG_MASK 0x80 +/* if enabled, adds support for resetting pre-MPP USB firmware - if we + * failed opening a device and we were asked to reset it, try also the + * old protocol. + */ +#define SUPPORT_OLD_RESET + +static char *progname; + +static void usage() +{ + fprintf(stderr, "Usage: %s [options] -D {/proc/bus/usb|/dev/bus/usb}// [operation...]\n", progname); + fprintf(stderr, "\tOptions:\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); + fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n"); + fprintf(stderr, "\tOperations:\n"); + fprintf(stderr, "\t\t[-n] # Renumerate device\n"); + fprintf(stderr, "\t\t[-r kind] # Reset: kind = {half|full}\n"); + fprintf(stderr, "\t\t[-p port] # TwinStar: USB port number [0, 1]\n"); + fprintf(stderr, "\t\t[-w (0|1)] # TwinStar: Watchdog off or on guard\n"); + fprintf(stderr, "\t\t[-Q] # Query device properties\n"); + exit(1); +} + +static int reset_kind(const char *arg) +{ + static const struct { + const char *name; + int type_code; + } reset_kinds[] = { + { "half", 0 }, + { "full", 1 }, + }; + int i; + + for(i = 0; i < sizeof(reset_kinds)/sizeof(reset_kinds[0]); i++) { + if(strcasecmp(reset_kinds[i].name, arg) == 0) + return reset_kinds[i].type_code; + } + ERR("Uknown reset kind '%s'\n", arg); + return -1; +} + + +static int show_hardware(struct astribank_device *astribank) +{ + int ret; + struct eeprom_table eeprom_table; + struct capabilities capabilities; + struct extrainfo extrainfo; + + ret = mpp_caps_get(astribank, &eeprom_table, &capabilities, NULL); + if(ret < 0) + return ret; + show_eeprom(&eeprom_table, stdout); + show_astribank_status(astribank, stdout); + if(astribank->eeprom_type == EEPROM_TYPE_LARGE) { + show_capabilities(&capabilities, stdout); + if(STATUS_FPGA_LOADED(astribank->status)) { + uint8_t unit; + uint8_t card_status; + uint8_t card_type; + uint8_t fpga_configuration; + uint8_t status; + + for(unit = 0; unit < 5; unit++) { + ret = mpps_card_info(astribank, unit, &card_type, &card_status); + if(ret < 0) + return ret; + printf("CARD %d: type=%x.%x %s\n", unit, + ((card_type >> 4) & 0xF), (card_type & 0xF), + ((card_status & 0x1) ? "PIC" : "NOPIC")); + } + ret = mpps_stat(astribank, unit, &fpga_configuration, &status); + if (ret < 0) + return ret; + printf("FPGA: %-17s: %d\n", "Configuration num", fpga_configuration); + printf("FPGA: %-17s: %s\n", "Watchdog Timer", + (SER_STAT_WATCHDOG_READY(status)) ? "ready" : "expired"); + printf("FPGA: %-17s: %s\n", "XPD Alive", + (SER_STAT_XPD_ALIVE(status)) ? "yes" : "no"); + } + ret = mpp_extrainfo_get(astribank, &extrainfo); + if(ret < 0) + return ret; + show_extrainfo(&extrainfo, stdout); + if(CAP_EXTRA_TWINSTAR(&capabilities)) { + twinstar_show(astribank, stdout); + } + } + return 0; +} + +#ifdef SUPPORT_OLD_RESET +/* Try to reset a device using USB_FW.hex, up to Xorcom rev. 6885 */ +int old_reset(const char* devpath) +{ + struct astribank_device *astribank; + int ret; + struct { + uint8_t op; + } PACKED header = {0x20}; /* PT_RESET */ + char *buf = (char*) &header; + + /* Note that the function re-opens the connection to the Astribank + * as any reference to the previous connection was lost when mpp_open + * returned NULL as the astribank reference. */ + astribank = astribank_open(devpath, 1); + if (!astribank) { + DBG("Failed re-opening astribank device for old_reset\n"); + return -ENODEV; + } + ret = xusb_send(astribank->xusb, buf, 1, 5000); + + /* If we just had a reenumeration, we may get -ENODEV */ + if(ret < 0 && ret != -ENODEV) + return ret; + /* We don't astribank_close(), as it has likely been + * reenumerated by now. */ + return 0; +} +#endif /* SUPPORT_OLD_RESET */ + +int main(int argc, char *argv[]) +{ + char *devpath = NULL; + struct astribank_device *astribank; + const char options[] = "vd:D:nr:p:w:Q"; + int opt_renumerate = 0; + char *opt_port = NULL; + char *opt_watchdog = NULL; + char *opt_reset = NULL; + int opt_query = 0; + int ret; + + progname = argv[0]; + while (1) { + int c; + + c = getopt (argc, argv, options); + if (c == -1) + break; + + switch (c) { + case 'D': + devpath = optarg; + break; + case 'n': + opt_renumerate++; + break; + case 'p': + opt_port = optarg; + break; + case 'w': + opt_watchdog = optarg; + break; + case 'r': + opt_reset = optarg; + /* + * Sanity check so we can reject bad + * arguments before device access. + */ + if(reset_kind(opt_reset) < 0) + usage(); + break; + case 'Q': + opt_query = 1; + break; + case 'v': + verbose++; + break; + case 'd': + debug_mask = strtoul(optarg, NULL, 0); + break; + case 'h': + default: + ERR("Unknown option '%c'\n", c); + usage(); + } + } + if(!devpath) { + ERR("Missing device path\n"); + usage(); + } + DBG("Startup %s\n", devpath); + if((astribank = mpp_init(devpath, 1)) == NULL) { + ERR("Failed initializing MPP\n"); +#ifdef SUPPORT_OLD_RESET + DBG("opt_reset = %s\n", opt_reset); + if (opt_reset) { + DBG("Trying old reset method\n"); + if ((ret = old_reset(devpath)) != 0) { + ERR("Old reset method failed as well: %d\n", ret); + } + } +#endif /* SUPPORT_OLD_RESET */ + + return 1; + } + /* + * First process reset options. We want to be able + * to reset minimal USB firmwares even if they don't + * implement the full MPP protocol (e.g: EEPROM_BURN) + */ + if(opt_reset) { + int full_reset; + + if((full_reset = reset_kind(opt_reset)) < 0) { + ERR("Bad reset kind '%s'\n", opt_reset); + return 1; + } + DBG("Reseting (%s)\n", opt_reset); + if((ret = mpp_reset(astribank, full_reset)) < 0) { + ERR("%s Reseting astribank failed: %d\n", + (full_reset) ? "Full" : "Half", ret); + } + goto out; + } + show_astribank_info(astribank); + if(opt_query) { + show_hardware(astribank); + } else if(opt_renumerate) { + DBG("Renumerate\n"); + if((ret = mpp_renumerate(astribank)) < 0) { + ERR("Renumerating astribank failed: %d\n", ret); + } + } else if(opt_watchdog) { + int watchdogstate = strtoul(opt_watchdog, NULL, 0); + + DBG("TWINSTAR: Setting watchdog %s-guard\n", + (watchdogstate) ? "on" : "off"); + if((ret = mpp_tws_setwatchdog(astribank, watchdogstate)) < 0) { + ERR("Failed to set watchdog to %d\n", watchdogstate); + return 1; + } + } else if(opt_port) { + int new_portnum = strtoul(opt_port, NULL, 0); + int tws_portnum = mpp_tws_portnum(astribank); + char *msg = (new_portnum == tws_portnum) + ? " Same same, never mind..." + : ""; + + DBG("TWINSTAR: Setting portnum to %d.%s\n", new_portnum, msg); + if((ret = mpp_tws_setportnum(astribank, new_portnum)) < 0) { + ERR("Failed to set USB portnum to %d\n", new_portnum); + return 1; + } + } +out: + mpp_exit(astribank); + return 0; +} diff --git a/xpp/astribank_upgrade b/xpp/astribank_upgrade new file mode 100755 index 0000000..71ae238 --- /dev/null +++ b/xpp/astribank_upgrade @@ -0,0 +1,150 @@ +#!/bin/bash + +# astribank_upgrade: force load Xorcom Astribank (XPP) USB firmware +# A reduced version of xpp_fxloader for manual upgrades. +# +# Written by Oron Peled +# Copyright (C) 2009 Xorcom +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +set -e + +# Make sure fxload is in the path: +PATH="$PATH:/usr/local/sbin:/sbin:/usr/sbin" +export PATH + +me=`basename $0` + +if [ -t 2 ]; then + LOGGER="logger -i -t '$me' -s" +else + LOGGER="logger -i -t '$me'" +fi + +USBFS_PREFIX=/proc/bus/usb +DEVUSB_PREFIX=/dev/bus/usb +USB_PREFIX= + +USB_FW="${USB_FW:-USB_FW.hex}" + +if [ "$USB_PREFIX" = '' ]; then + if [ -d "$DEVUSB_PREFIX" ]; then + USB_PREFIX=$DEVUSB_PREFIX + elif [ -r "$USBFS_PREFIX/devices" ]; then + USB_PREFIX=$USBFS_PREFIX + fi +fi + +# With Kernels older that 2.6.10 it seems to be possible +# to trigger a race condition by running fxload or fpga_load +# immediately after the detection of the device. +KERNEL_HAS_USB_RACE=0 +case "`uname -r`" in 2.6.[89]*) KERNEL_HAS_USB_RACE=1;; esac +sleep_if_race() { + if [ "$KERNEL_HAS_USB_RACE" = '1' ]; then + sleep 2 + fi +} + +find_dev() { + v_id=$1 + p_id=$2 + + lsusb | tr -d : | awk "/ ID $v_id$p_id/{printf \"$USB_PREFIX/%s/%s \",\$2,\$4}" +} + +run_fxload() { + sleep_if_race + fxload -t fx2 $* 2>&1 1>/dev/null | $LOGGER + status=$PIPESTATUS + if [ $status != 0 ]; then + $LOGGER "fxload failed with status $status" + exit 55 + fi +} + +load_usb_fw() { + v_id=$1 + p_id=$2 + fw=$3 + + devices=`find_dev $v_id $p_id` + for dev in $devices + do + ver=$(awk '/\$Id:/ { print $4 }' $FIRMWARE_DIR/$fw) + $LOGGER "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev" + run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1 + done +} + +numdevs() { + v_ids="$1" + p_ids="$2" + + for v in $v_ids + do + ( + for p in $p_ids + do + find_dev $v $p + done + ) + done | wc -w +} + +wait_renumeration() { + num="$1" + v_ids="$2" + p_ids="$3" + + while + n=`numdevs "$v_ids" "$p_ids"` + [ "$num" -gt "$n" ] + do + echo -n "." + sleep 1 + done + echo "Got all $num devices" +} + +if [ "$#" -ne 1 ]; then + echo >&2 "Usage: $0 " + exit 1 +fi +FIRMWARE_DIR="$1" +[ -f "$FIRMWARE_DIR/$USB_FW" ] || { + echo >&2 "$0: Could not find '$FIRMWARE_DIR/$USB_FW'" + exit 1 +} +numdevs=`numdevs e4e4 '11[3456][01]'` +$LOGGER -- "--------- LOADING NEW USB FIRMWARE: ($1) [$numdevs devices]" +load_usb_fw e4e4 1130 $USB_FW +load_usb_fw e4e4 1140 $USB_FW +load_usb_fw e4e4 1150 $USB_FW +load_usb_fw e4e4 1160 $USB_FW +load_usb_fw e4e4 1131 $USB_FW +load_usb_fw e4e4 1141 $USB_FW +load_usb_fw e4e4 1151 $USB_FW +load_usb_fw e4e4 1161 $USB_FW +load_usb_fw e4e4 1132 $USB_FW +load_usb_fw e4e4 1142 $USB_FW +load_usb_fw e4e4 1152 $USB_FW +load_usb_fw e4e4 1162 $USB_FW +wait_renumeration $numdevs e4e4 '11[3456]1' +$LOGGER -- "--------- NEW USB FIRMWARE IS LOADED" diff --git a/xpp/astribank_usb.c b/xpp/astribank_usb.c new file mode 100644 index 0000000..af7e6aa --- /dev/null +++ b/xpp/astribank_usb.c @@ -0,0 +1,276 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define _GNU_SOURCE /* for memrchr() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "astribank_usb.h" +#include + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x01 +#define TIMEOUT 500 + +#define TYPE_ENTRY(t,p,ni,n,ne,out,in,...) \ + { \ + .my_vendor_id = 0xe4e4, \ + .my_product_id = (p), \ + .name = #t, \ + .num_interfaces = (ni), \ + .my_interface_num = (n), \ + .num_endpoints = (ne), \ + .my_ep_in = (in), \ + .my_ep_out = (out), \ + } + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static const struct xusb_spec astribank_specs[] = { + /* OLD Firmwares */ + TYPE_ENTRY("USB-OLDFXS", 0x1131, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLDFXS", 0x1132, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-BRI", 0x1141, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-BRI", 0x1142, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-OLD", 0x1151, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLD", 0x1152, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + + TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("BURNED-MULTI", 0x1164, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-BURN", 0x1112, 2, 1, 2, MP_EP_OUT, MP_EP_IN), +}; + +static const struct xusb_spec astribank_pic_specs[] = { + TYPE_ENTRY("USB_PIC", 0x1161, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN), +}; +#undef TYPE_ENTRY + +//static int verbose = LOG_DEBUG; + +/* + * USB handling + */ +struct astribank_device *astribank_open(const char devpath[], int iface_num) +{ + struct astribank_device *astribank = NULL; + struct xusb *xusb; + + DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); + if((astribank = malloc(sizeof(struct astribank_device))) == NULL) { + ERR("Out of memory\n"); + goto fail; + } + memset(astribank, 0, sizeof(*astribank)); + if (iface_num) { + xusb = xusb_find_bypath(astribank_specs, ARRAY_SIZE(astribank_specs), devpath); + } else { + xusb = xusb_find_bypath(astribank_pic_specs, ARRAY_SIZE(astribank_pic_specs), devpath); + } + if (!xusb) { + ERR("%s: No device found\n", __func__); + goto fail; + } + astribank->xusb = xusb; + astribank->is_usb2 = (xusb_packet_size(xusb) == 512); + astribank->my_interface_num = iface_num; + if (xusb_claim_interface(astribank->xusb) < 0) { + ERR("xusb_claim_interface failed\n"); + goto fail; + } + astribank->tx_sequenceno = 1; + return astribank; +fail: + if (astribank) { + free(astribank); + astribank = NULL; + } + return NULL; +} + +/* + * MP device handling + */ +void show_astribank_info(const struct astribank_device *astribank) +{ + struct xusb *xusb; + + assert(astribank != NULL); + xusb = astribank->xusb; + assert(xusb != NULL); + if(verbose <= LOG_INFO) { + xusb_showinfo(xusb); + } else { + const struct xusb_spec *spec; + + spec = xusb_spec(xusb); + printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb)); + printf("USB Firmware Type: [%s]\n", spec->name); + printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb)); + printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb)); + printf("USB iProduct: [%s]\n", xusb_product(xusb)); + } +} + +void astribank_close(struct astribank_device *astribank, int disconnected) +{ + assert(astribank != NULL); + if (astribank->xusb) { + xusb_close(astribank->xusb); + astribank->xusb = NULL; + } + astribank->tx_sequenceno = 0; +} + +#if 0 +int flush_read(struct astribank_device *astribank) +{ + char tmpbuf[BUFSIZ]; + int ret; + + DBG("starting...\n"); + memset(tmpbuf, 0, BUFSIZ); + ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1); + if(ret < 0 && ret != -ETIMEDOUT) { + ERR("ret=%d\n", ret); + return ret; + } else if(ret > 0) { + DBG("Got %d bytes:\n", ret); + dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret); + } + return 0; +} +#endif + + +int release_isvalid(uint16_t release) +{ + uint8_t rmajor = (release >> 8) & 0xFF; + uint8_t rminor = release & 0xFF; + + return (rmajor > 0) && + (rmajor < 10) && + (rminor > 0) && + (rminor < 10); +} + +int label_isvalid(const char *label) +{ + int len; + int goodlen; + const char GOOD_CHARS[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_."; + + len = strlen(label); + goodlen = strspn(label, GOOD_CHARS); + if(len > LABEL_SIZE) { + ERR("Label too long (%d > %d)\n", len, LABEL_SIZE); + return 0; + } + if(goodlen != len) { + ERR("Bad character in label (pos=%d)\n", goodlen); + return 0; + } + return 1; +} + +int eeprom_fill(struct eeprom_table *eprm, + const char *vendor, + const char *product, + const char *release, + const char *label) +{ + uint16_t val; + + eprm->source = 0xC0; + eprm->config_byte = 0; + if(vendor) { + val = strtoul(vendor, NULL, 0); + if(!val) { + ERR("Invalid vendor '%s'\n", + vendor); + return -EINVAL; + } + eprm->vendor = val; + } + if(product) { + val = strtoul(product, NULL, 0); + if(!val) { + ERR("Invalid product '%s'\n", + product); + return -EINVAL; + } + eprm->product = val; + } + if(release) { + int release_major = 0; + int release_minor = 0; + uint16_t value; + + if(sscanf(release, "%d.%d", &release_major, &release_minor) != 2) { + ERR("Failed to parse release number '%s'\n", release); + return -EINVAL; + } + value = (release_major << 8) | release_minor; + DBG("Parsed release(%d): major=%d, minor=%d\n", + value, release_major, release_minor); + if(!release_isvalid(value)) { + ERR("Invalid release number 0x%X\n", value); + return -EINVAL; + } + eprm->release = value; + } + if(label) { + /* padding */ + if(!label_isvalid(label)) { + ERR("Invalid label '%s'\n", label); + return -EINVAL; + } + memset(eprm->label, 0, LABEL_SIZE); + memcpy(eprm->label, label, strlen(label)); + } + return 0; +} + +int astribank_has_twinstar(struct astribank_device *astribank) +{ + uint16_t product_series; + + assert(astribank != NULL); + product_series = xusb_product_id(astribank->xusb); + product_series &= 0xFFF0; + if(product_series == 0x1160) /* New boards */ + return 1; + return 0; +} + diff --git a/xpp/astribank_usb.h b/xpp/astribank_usb.h new file mode 100644 index 0000000..69778e6 --- /dev/null +++ b/xpp/astribank_usb.h @@ -0,0 +1,113 @@ +#ifndef ASTRIBANK_USB_H +#define ASTRIBANK_USB_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include "mpp.h" + +/* + * Astribank handling + */ + +#define PACKET_SIZE 512 + +/* USB Endpoints */ +#define MP_EP_OUT 0x04 /* Managment processor */ +#define MP_EP_IN 0x88 /* Managment processor */ + +#define XPP_EP_OUT 0x02 /* XPP */ +#define XPP_EP_IN 0x86 /* XPP */ + +/* USB firmware types */ +#define USB_11xx 0 +#define USB_FIRMWARE_II 1 +#define USB_PIC 2 + +struct interface_type { + int type_code; + int num_interfaces; + int my_interface_num; + int num_endpoints; + int my_ep_out; + int my_ep_in; + char *name; + int endpoints[4]; /* for matching */ +}; + +enum eeprom_burn_state { + BURN_STATE_NONE = 0, + BURN_STATE_STARTED = 1, + BURN_STATE_ENDED = 2, + BURN_STATE_FAILED = 3, +}; + +struct astribank_device { + struct xusb *xusb; + struct xtalk_device *xtalk_dev; + usb_dev_handle *handle; + int my_interface_num; + int my_ep_out; + int my_ep_in; + char iInterface[BUFSIZ]; + int is_usb2; + enum eeprom_type eeprom_type; + enum eeprom_burn_state burn_state; + uint8_t status; + uint8_t mpp_proto_version; + struct eeprom_table *eeprom; + struct firmware_versions fw_versions; + uint16_t tx_sequenceno; +}; + +/* + * Prototypes + */ +struct astribank_device *astribank_open(const char devpath[], int iface_num); +void astribank_close(struct astribank_device *astribank, int disconnected); +void show_astribank_info(const struct astribank_device *astribank); +int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout); +int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout); +int flush_read(struct astribank_device *astribank); +int eeprom_fill(struct eeprom_table *eprm, + const char *vendor, + const char *product, + const char *release, + const char *label); +int astribank_has_twinstar(struct astribank_device *astribank); +int label_isvalid(const char *label); + +#define AB_REPORT(report_type, astribank, fmt, ...) \ + report_type("%s [%s]: " fmt, \ + xusb_devpath((astribank)->xusb), \ + xusb_serial((astribank)->xusb), \ + ## __VA_ARGS__) + +#define AB_INFO(astribank, fmt, ...) \ + AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__) + +#define AB_ERR(astribank, fmt, ...) \ + AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__) + +#endif /* ASTRIBANK_USB_H */ diff --git a/xpp/dahdi.cgi b/xpp/dahdi.cgi new file mode 100755 index 0000000..5b0e591 --- /dev/null +++ b/xpp/dahdi.cgi @@ -0,0 +1,265 @@ +#! /usr/bin/perl -wT + +# Written by Tzafrir Cohen +# Copyright (C) 2008, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. + +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use CGI::Pretty qw/:standard start_ul start_li start_div start_pre/; +use Dahdi; +use Dahdi::Xpp; +use Dahdi::Hardware; + +$ENV{'PATH'} = '/bin:/usr/bin'; + +my $DEF_TOK = ''; + +my $style=< +END + +my @Toc = (); + +sub header_line($$) { + my ($text, $anchor) = @_; + print a({-name=>$anchor},h2($text)); + push(@Toc, [$text, $anchor] ); +} + +print header, + start_html( + -title=>"DAHDI Information", + -style=>{-code=>$style}), + h1("DAHDI Information"); + +print start_div({-id=>'content'}); + +sub dahdi_spans() { + my %ChansStat = (num=>0, configured=>0, inuse=>0); + + header_line("DAHDI Spans", 'spans'); + + print p('Here we list the ', + dfn({-title=> 'A span is a logical unit of dahdi + channels. e.g.: all the channels that come from + a specific port, or all the analog channels from + a certain PCI card'}, + 'spans'), + ' that DAHDI devices registered + with DAHDI. For each span we list all of its channels.' + ), + p('A channel that appears in ', + span({-class=>'status-noconf'},'red text'),' ', + 'is one that has not been configured at all. Either not + listed in system.conf, or dahdi_cfg was not run.' + ), + p('A channel that appears in ', + span({-class=>'status-notused'},'pink text'),' ', + 'is one that has been configured but is not used by any + application. This usually means that either Asterisk is + not running or Asterisk is not configured to use this + channel' + ), + p('If a port is disconnected it will have a "RED" alarm. + For a FXO port this will only be on the specific port. + For a BRI, E1 or T1 port it will be an alarm on the apn + and all of the channels.'), + ; + + + + foreach my $span (Dahdi::spans()) { + my $spanno = $span->num; + my $index = 0; + + print h3(a({-name=>"zap_span_$spanno"}, "Span $spanno: ", + $span->name, " ", $span->description)), + start_ul; + foreach my $chan ($span->chans()) { + my $batt = ''; + $batt = "(battery)" if $chan->battery; + my $type = $chan->type; + my $sig = $chan->signalling; + my $info = $chan->info; + my $chan_stat = 'ok'; + $ChansStat{num}++; + if (!$sig) { + $chan_stat = 'noconf'; + } else { + $ChansStat{configured}++; + if ($info =~ /\(In use\)/) { + $ChansStat{inuse}++; + } else { + $chan_stat = 'notused'; + } + } + # TODO: color differently if no signalling and + # if not in-use and in alarm. + print li({-class=>"status-$chan_stat"}, + $chan->num, " $type, $sig $info $batt"); + } + print end_ul; + } +} + +sub dahdi_hardware() { + header_line("DAHDI Hardware", 'zap_hard'); + + print p('Here we list all the DAHDI hardware devices on your + system. If a device is not currently handled by a + driver, it will appear as ', + span({-class=>'status-noconf'},'red text'),'.'); + + my $hardware = Dahdi::Hardware->scan; + + print start_ul; + foreach my $device ($hardware->device_list) { + my $driver = $device->driver || ""; + my $status = 'ok'; + + if (! $device->loaded) { + $status = 'noconf'; + } + + print li({-class=>"status-$status"}, + $device->hardware_name, ": ", $driver, + " [".$device->vendor,"/". $device->product. "] ", + $device->description); + } + print end_ul; +} + +sub astribanks() { + header_line("Astribanks", 'astribanks'); + + print p('Here we list all the Astribank devices (That are + handled by the drivers). For each Astribank we list + its XPDs. A ', + dfn({-title=> + 'a logical unit of the Astribank. It will '. + 'be registered in DAHDI as a single span. This '. + 'can be either an analog (FXS or FXO) module or '. + 'a single port in case of a BRI and PRI modules.' + }, + 'XPD'),'. ', + ' that is registered will have a link to the + information about the span below. One that is not + registered will appear as ', + span({-class=>'status-noconf'},'red text'),'.'); + + print start_ul; + + foreach my $xbus (Dahdi::Xpp::xbuses()) { + print start_li, + $xbus->name." (".$xbus->label .", ".$xbus->connector .")", + start_ul; + foreach my $xpd ($xbus->xpds) { + my $chan_stat = 'ok'; + my $span_str = 'UNREGISTERED'; + if ($xpd->spanno) { + my $spanno = $xpd->spanno; + $span_str = + a({-href=>"#zap_span_$spanno"}, + "Span $spanno"); + } else { + $chan_stat = 'noconf'; + } + print li({-class=>"status-$chan_stat"}, + '[', $xpd->type, '] ', $span_str, $xpd->fqn + ); + } + print end_ul, end_li; + } + print end_ul; +} + + +dahdi_hardware(); + +astribanks(); + +dahdi_spans(); + +print end_div(); # content + +print div({-id=>'toc'}, + p( a{-href=>'/'},'[Homepage]' ), + ( map {p( a({-href=> '#'.$_->[1]},$_->[0] ) )} @Toc ), +); diff --git a/xpp/dahdi_drivers b/xpp/dahdi_drivers new file mode 100755 index 0000000..863d7b1 --- /dev/null +++ b/xpp/dahdi_drivers @@ -0,0 +1,23 @@ +#! /usr/bin/perl -w +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi::Hardware; + +my @drivers = Dahdi::Hardware->drivers; +print join("\n", @drivers),"\n"; +__END__ + +=head1 NAME + +dahdi_drivers - Show drivers required for installed dahdi devices. + +=head1 SYNOPSIS + +dahdi_drivers + +=head1 DESCRIPTION + +This script shows by default the list of drivers required for currently +installed dahdi devices. diff --git a/xpp/dahdi_genconf b/xpp/dahdi_genconf new file mode 100755 index 0000000..842084d --- /dev/null +++ b/xpp/dahdi_genconf @@ -0,0 +1,241 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Getopt::Long; +use Dahdi; +use Dahdi::Xpp; +use Dahdi::Config::Gen; +use Dahdi::Config::Params; + +Getopt::Long::Configure ("bundling"); + +my $version = '1'; # Functionality version (integer) +my $revision = '$Revision$'; + +my %opts; + +sub usage { + warn "Usage: $0 [options] \n"; + warn " Options:\n"; + warn " --line-mode= - Also generate span-types.conf with default line mode\n"; + warn " -F|--freepbx - Modify configuration for Freepbx (skip FXS channels)\n"; + warn " -v|--verbose - Be versbose, show generated files\n"; + warn " -V|--version - Show version and exit\n"; + warn " -h|--help - Show this message\n"; + exit 1; +} + +sub set_defaults { + my $default_file = $ENV{GENCONF_PARAMETERS} || "/etc/dahdi/genconf_parameters"; + my $params = Dahdi::Config::Params->new($default_file); + #$params->dump; + if($opts{v}) { + print "Default parameters from ", $params->{GENCONF_FILE}, "\n"; + } + my $gconfig = Dahdi::Config::Gen->new($params); + #$gconfig->dump; + return $gconfig; +} + +sub spans_prep($@) { + my $gconfig = shift || die; + my @spans = @_; + foreach my $span (@spans) { + if($span->is_pri || $span->is_bri) { + $span->pri_set_fromconfig($gconfig); + } + } +} + +sub munge_spantypes { + if ($opts{'line-mode'}) { + print "Will generate span-types.conf with line-mode=$opts{'line-mode'}\n" + if $opts{'verbose'}; + return "spantypes=line-mode=$opts{'line-mode'}"; + } else { + print "Will generate span-types.conf\n" if $opts{'verbose'}; + return "spantypes"; + } +} + +sub generator_list($) { + my $gconfig = shift || die; + my @genlist; + + if (@ARGV) { + for my $gen (@ARGV) { + $gen = munge_spantypes() if $gen eq 'spantypes'; + push @genlist, $gen; + } + } else { + # No files given. Use the defaults. + @genlist = ('assignedspans', 'system', 'chandahdi'); + if($gconfig->{'pri_connection_type'} eq 'R2') { + push @genlist, 'unicall'; + } + push(@genlist, munge_spantypes()) if $opts{'line-mode'}; + } + return @genlist; +} + +sub parse_genopts($) { + my $optstr = shift; + my %genopts; + + $optstr = '' unless defined $optstr; + foreach my $o (split(/,/, $optstr)) { + my ($k, $v) = split(/=/, $o, 2); + $v = 1 unless defined $v and $v; + $genopts{$k} = $v; + } + return %genopts; +} + +sub generate_files($@) { + my $gconfig = shift || die; + my @spans = @_; + my @generators = generator_list($gconfig); + + for my $gen (@generators) { + my ($name, $optstr) = split(/=/, $gen, 2); + die "Illegal name '$name'\n" unless $name =~ /^\w+$/; + $name =~ s/(.)(.*)/\u$1\L$2/; + my %genopts = parse_genopts($optstr); + $genopts{'freepbx'} = 'yes' if $opts{'F'}; + if(defined $opts{'v'}) { + $genopts{'verbose'} = $opts{v}; + } + $gconfig->run_generator($name, \%genopts, @spans); + } +} + +GetOptions(\%opts, + "line-mode=s", + "h|help", + "v|verbose", + "V|version", + "F|freepbx", + ) or usage; + +usage if $opts{h}; + +if($opts{'V'}) { + my $revstr = $revision; + $revstr =~ s/[^$]*\$[^:]+:\s*//; + $revstr =~ s/\s*\$.*//; + print "$0: version=$version revision=$revstr\n"; + exit 0; +} + +my $gconfig = set_defaults; +my @spans = Dahdi::spans(); +spans_prep($gconfig, @spans); +generate_files($gconfig, @spans); + +__END__ + +=head1 NAME + +dahdi_genconf - Generate configuration for Dahdi channels. + +=head1 SYNOPSIS + +dahdi_genconf [options] [generator...] + +=head1 DESCRIPTION + +This script generate configuration files for Dahdi hardware. +It uses two information sources: + +=over 4 + +=item Hardware + + The actual Dahdi hardware is automatically detected on the host. + +=item /etc/dahdi/genconf_parameters + +A configuration file that supplements the hardware information. +Its location may be overridden via the C environment +variable. + +=back + +The dahdi_genconf script can generate various kinds of configuration files +as specified by the generator arguments. Each generator is a perl class +in Dahdi::Config::Gen namespace. The generator names on the command line +are the class names in lowercase. + +The following generators are currently implemented: system, modules, spantypes, +assignedspans, chandahdi, unicall, users. + +For further documentation on each, please user perldoc on the relevant +class. E.g: C + +Each generator on the command line may be passed custom options by assigning +a comma separated list of options to the generator name. E.g: + + dahdi_genconf system chandahdi=verbose unicall + +=head2 Global options: + +=over 4 + +=item -V --version + +Version -- print version string and exit. + +=item -v --verbose + +Verbose -- sets the C<'verbose'> option for all generators. + +=item -F --freepbx + +Freepbx -- sets the C<'freepbx'> option for all generators. +Currently, chandahdi is affected. + +=item --line-mode=I + +I may be E1, J1 or T1. + +Enables the generator B and the option B to it. +(Equivalent to the option C<--line-mode> to C). This +will generate a C file with a single wildcard line +setting the line mode to I. + +=back + +=head2 Implementation notes: + +=over 4 + +=item * + +F parsing is done via C. +An object representing the parsed data is instantiated by: +Cnew()>. +The C method of this object contains all the hard coded +defaults of the configuration directives. + +=item * + +A configuration object is instantiated by Cnew($params)>. +The mapping of configuration directives into semantic configuration is +done in the constructor. + +=item * + +A single generator is run via the the C method of the +configuration object. + +=back diff --git a/xpp/dahdi_hardware b/xpp/dahdi_hardware new file mode 100755 index 0000000..032b9e3 --- /dev/null +++ b/xpp/dahdi_hardware @@ -0,0 +1,196 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; + +sub usage { + die "Usage: $0 [-v][-x][-t]\n"; +} + +my %opts; +getopts('vxt', \%opts) || usage; +@ARGV == 0 or usage; + +my @spans = Dahdi::spans; + +sub show_xbus($) { + my $xbus = shift or die; + my @xpds = $xbus->xpds; + my $label = '[' . $xbus->label() . ']'; + my $connector = ($xbus->status eq 'CONNECTED') ? $xbus->connector : "MISSING"; + printf " LABEL=%-20s CONNECTOR=%-20s\n", $label, $connector; + foreach my $xpd (@xpds) { + my $reg = $xpd->dahdi_registration; + my $channels = '(' . $xpd->channels . ')'; + my $span; + my $spanstr; + if($reg && @spans) { + ($span) = grep { $_->name eq $xpd->fqn } @spans; + $spanstr = ($span) ? ("Span " . $span->num) : ""; + } else { + $spanstr = "Unregistered"; + } + my $master = ''; + #$master = "XPP-SYNC" if $xpd->is_sync_master; + $master .= " DAHDI-SYNC" if defined($span) && $span->is_dahdi_sync_master; + printf "\t%-10s: %-8s %-5s %s %s\n", $xpd->fqn, $xpd->type, $channels, $spanstr, $master; + } +} + +my %seen; +my $format = "%-20s %-12s %4s:%4s %s\n"; + +sub show_disconnected(%) { + my %seen = @_; + + my $notified_lost = 0; + foreach my $xbus (Dahdi::Xpp::xbuses) { + if(!$seen{$xbus->name}) { + print "----------- XPP Spans with disconnected hardware -----------\n" + unless $notified_lost++; + printf($format, $xbus->name, '', '', '', "NO HARDWARE"); + show_xbus($xbus) if $opts{'v'}; + } + } +} + +# FIXME: For verbose display we also need to see the XPP devices. +# If no spans are registered, this won't happen. A brute-force +# method for making it happen: +Dahdi::Xpp::xbuses if ($opts{'v'}); + +my @devices = Dahdi::Hardware->device_list; +foreach my $dev (@devices) { + my $driver = $dev->driver || ""; + my $xbus; + my $loaded; + my $tws_port; + my $tws_power; + my $tws_watchdog; + my $mppinfo; + if($dev->is_astribank) { + $xbus = $dev->xbus; + if($opts{'v'} || $opts{'t'}) { + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + $mppinfo = $dev->mppinfo; + if(defined $mppinfo) { + $tws_port = $mppinfo->{TWINSTAR_PORT}; + $tws_power = $mppinfo->{TWINSTAR_POWER}; + $tws_watchdog = $mppinfo->{TWINSTAR_WATCHDOG}; + } + } + } + $loaded = $dev->loaded; + warn "driver should be '$driver' but is actually '$loaded'\n" + if defined($loaded) && $driver ne $loaded; + $driver = "$driver" . (($loaded) ? "+" : "-"); + if(defined $tws_power && defined $tws_watchdog) { + my $tws_active = $tws_watchdog && $tws_power->[0] && $tws_power->[1]; + $driver .= "[T]" if $tws_active; + } + my $description = $dev->description || ""; + printf $format, $dev->hardware_name, $driver, $dev->vendor, $dev->product, $description; + if($opts{'v'} && defined $mppinfo && exists $mppinfo->{MPP_TALK}) { + printf " MPP: TWINSTAR_PORT=$tws_port\n" if defined $tws_port; + printf " MPP: TWINSTAR_WATCHDOG=$tws_watchdog\n" if defined $tws_watchdog; + for(my $i = 0; $i < 2; $i++) { + printf " MPP: TWINSTAR_POWER[%d]=%d\n", + $i, $tws_power->[$i] if defined $tws_power; + } + } + if(!defined $xbus || !$xbus) { + next; + } + $seen{$xbus->name} = 1; + show_xbus($xbus) if $opts{'v'}; +} + +show_disconnected(%seen) if $opts{'x'}; + +__END__ + +=head1 NAME + +dahdi_hardware - Shows Dahdi hardware devices. + +=head1 SYNOPSIS + +dahdi_hardware [-v][-x] + +=head1 OPTIONS + +=over + +=item -v + +Verbose output - show spans used by each device etc. Currently only +implemented for the Xorcom Astribank. + +=item -x + +Show disconnected Astribank unit, if any. + +=back + +=head1 DESCRIPTION + +Show all Dahdi hardware devices. Devices are recognized according to +lists of PCI and USB IDs in Dahdi::Hardware::PCI.pm and +Dahdi::Hardware::USB.pm . For PCI it is possible to detect by +sub-vendor and sub-product ID as well. + +The first output column is the connector: a bus specific field that +shows where this device is. + +The second field shows which driver should handle the device. a "-" sign +marks that the device is not yet handled by this driver. A "+" sign +means that the device is handled by the driver. + +For the Xorcom Astribank (and in the future: for other Dahdi devices) +some further information is provided from the driver. Those extra lines +always begin with spaces. + +Example output: + +Without drivers loaded: + + usb:001/002 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + usb:001/003 xpp_usb- e4e4:1152 Astribank-multi FPGA-firmware + pci:0000:01:0b.0 wctdm- e159:0001 Wildcard TDM400P REV H + +With drivers loaded, without -v: + usb:001/002 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + usb:001/003 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + pci:0000:01:0b.0 wctdm+ e159:0001 Wildcard TDM400P REV E/F + +With drivers loaded, with -v: + usb:001/002 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:123] CONNECTOR=usb-0000:00:1d.7-1 + XBUS-00/XPD-00: FXS Span 2 + XBUS-00/XPD-10: FXS Span 3 + XBUS-00/XPD-20: FXS Span 4 + XBUS-00/XPD-30: FXS Span 5 + usb:001/003 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware + LABEL=[usb:4567] CONNECTOR=usb-0000:00:1d.7-4 + XBUS-01/XPD-00: FXS Span 6 XPP-SYNC + XBUS-01/XPD-10: FXO Span 7 + XBUS-01/XPD-20: FXO Span 8 + XBUS-01/XPD-30: FXO Span 9 + pci:0000:01:0b.0 wctdm+ e159:0001 Wildcard TDM400P REV E/F + diff --git a/xpp/dahdi_registration b/xpp/dahdi_registration new file mode 100755 index 0000000..2772e00 --- /dev/null +++ b/xpp/dahdi_registration @@ -0,0 +1,248 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Xpd; +use Getopt::Std; + +sub usage { + die "Usage: $0 [-v] [-R] [-s sort_order] [on|off|1|0]\n"; +} + +sub check_param { + my $param = shift || die; + open(F, $param) || return ''; + my $val = ; + close F; + chomp $val; + return $val; +} + +my %opts; +getopts('vRs:', \%opts) || usage; + +my $dahdi_autoreg = check_param('/sys/module/xpp/parameters/dahdi_autoreg') eq 'Y'; +my $auto_assign_spans = check_param('/sys/module/dahdi/parameters/auto_assign_spans') ne '0'; +my $assigned_spans_config = $ENV{'ASSIGNED_SPANS_CONF_FILE'} || '/etc/dahdi/assigned-spans.conf'; +my $span_types_config = $ENV{'SPAN_TYPES_CONF_FILE'} || '/etc/dahdi/span-types.conf'; +my $have_assigned_spans_config = -f $assigned_spans_config || 0; +my $have_span_types_config = -f $span_types_config || 0; + +# Spans will be auto-assigned by default if either: +# - Driver $auto_assign_spans them or +# - Udev script see that we $have_span_types_config and it "add" them +my $default_auto_assign = $auto_assign_spans || $have_assigned_spans_config; + +my $sorter; +my $sort_order = $opts{'s'}; +if(defined $sort_order) { + my $sorter = Dahdi::Xpp::sorters($sort_order); + + if(!defined $sorter) { + my @sorter_names = Dahdi::Xpp::sorters; + print STDERR "Unknown sort order $sort_order. Select from:\n\t"; + print STDERR join("\n\t", @sorter_names); + print STDERR "\n"; + exit 1; + } +} + +@ARGV == 0 or @ARGV == 1 or usage; +my $on = shift; +my $verbose = $opts{'v'}; +my $should_output = 1; + +#print "dahdi_autoreg=$dahdi_autoreg auto_assign_spans=$auto_assign_spans have_assigned_spans_config='$have_assigned_spans_config' have_span_types_config='$have_span_types_config'\n"; + +if(defined($on)) { # Translate to booleans + $on = uc($on); + $on =~ /^(ON|OFF|1|0)$/ or usage; + $on = ($on eq 'ON') ? 1 : 0; + $should_output = 0 unless $verbose; +} + +sub state2str($) { + return (shift)?"on":"off"; +} + +sub myprintf { + printf @_ if $should_output; +} + +foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) { + my $prev = $xbus->dahdi_registration($on); + if(!defined($prev)) { # Failure + printf STDERR "%s: Failed %s\n", $xbus->name, $!; + next; + } + my $reg_str; + if (defined $on) { + $reg_str = ($on) ? "registering" : "unregistering"; + } else { + $reg_str = ($prev) ? "registered" : "unregistered"; + } + myprintf "%-10s\t%3s-%s\t%s (%s)\n", + $xbus->name, $xbus->xpporder, $xbus->label, $xbus->connector, + $reg_str; + next unless $xbus->status eq 'CONNECTED'; + # Only assign if no default assignment, or forced by '-R' option + if (defined($on) && $on) { + if ($opts{'R'} || ! $default_auto_assign) { + # Emulate /etc/dahdi/assigned-spans.conf: + # - We iterate over $xbus according to /etc/dahdi/xpp_order + # - We "auto" assign all spans of current $xbus + my $devpath = sprintf "/sys/bus/dahdi_devices/devices/astribanks:xbus-%02d", $xbus->num; + my @cmd = ('dahdi_span_assignments', 'auto', $devpath); + system @cmd; + warn "Failed '@cmd' (status=$?)\n" if $?; + } + # wait for UDEV to do its stuff + system "dahdi_waitfor_span_assignments assigned"; + } + foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) { + my $spanno = $xpd->xpd_getattr('span'); + myprintf "\t%-10s: ", $xpd->fqn; + my $spanstr = ($spanno) ? ("Span " . $spanno) : "unassigned"; + myprintf "%s\n", $spanstr ; + } +} +myprintf "# Sorted: $sort_order\n" if defined $sort_order; + +__END__ + +=head1 NAME + +dahdi_registration - Handle registration of Xorcom XPD modules in dahdi. + +=head1 SYNOPSIS + +dahdi_registration [-v] [-s sortorder] [-R] [on|off] + +=head1 DESCRIPTION + +Without parameters, show all connected XPDs sorted by physical connector order. +Each one is show to be unregistered (off), or registered to a specific dahdi +span (the span number is shown). + +All registerations/deregisterations are sorted by physical connector string. + +Span registration should generally always succeed. Span unregistration may +fail if channels from the span are in use by e.g. asterisk. In such a case +you'll also see those channels as '(In use)' in the output of lsdahdi(8). + +dahdi_registration is intended to be used when the kernel module parameter +B is false (and implicitly: when the module parameter +B is true). See also the NOTES section regarding +C. + +If dahdi_autoreg is true, the program will normally do nothing. + +=head2 Parameters + +off -- deregisters all XPD's from dahdi. + +on -- registers all XPD's to dahdi. + +=head2 Options + +=over + +=item -v + +verbose output. + +=item -R + +Force operations (on/off) even if the module parameter B +for xpp is enabled (which makes this program unneeded). + +=item -s I + +The sort order to use. + +=back + +If the option is not used, the sort order is taken from the environment +variable XBUS_SORT and failing that: the hard-coded default of +SORT_XPPORDER. + +The available sorting orders are documented in Dahdi::Xpp manual. + + + +=head2 Sample Output + +An example of the output of dahdi_registration for some registered +Astribanks: + + $ dahdi_registration -s type + XBUS-01 usb:0000153 usb-0000:00:10.4-2 + XBUS-01/XPD-00: on Span 1 + XBUS-01/XPD-01: on Span 2 + XBUS-00 usb:0000157 usb-0000:00:10.4-4 + XBUS-00/XPD-00: on Span 3 + XBUS-00/XPD-01: on Span 4 + XBUS-00/XPD-02: on Span 5 + XBUS-00/XPD-03: on Span 6 + XBUS-00/XPD-04: on Span 7 + XBUS-00/XPD-05: on Span 8 + XBUS-00/XPD-06: on Span 9 + XBUS-00/XPD-07: on Span 10 + XBUS-02 usb-0000:00:10.4-1 + XBUS-02/XPD-00: on Span 11 + XBUS-02/XPD-10: on Span 12 + # Sorted: type + +=head1 FILES + +=over + +=item /proc/xpp/XBUS-nn/XPD-mm/dahdi_registration + +Reading from this file shows if if the if the specific XPD is +registered. Writing to it 0 or 1 registers / unregisters the device. + +This should allow you to register / unregister a specific XPD rather +than all of them. + +=back + +=head1 NOTES + +dahdi_registration is intended to be used when the kernel module +parameter B is false (and implicitly: when the module +parameter B is true), that is, Astribank devices +as detected by XPP (xbus / xpd) do not register automatically with the +DAHDI core. This tool is used to register tem in an explicit order. It +works well, but only if you can arange for all of the Astribanks of the +system to be available (and not already registered) at a specific point +in time. + +Newer versions of DAHDI added support for registering a span to a +specific span/channelss numbers specification. This allows registering +them out of order. To use this capability, the module parameter +B should be unset (set to 0) and thus spans of +detected DAHDI devices could be registered using C +(which may also be run automatically from a udev hook). + +In this case there is no point in delaying XPP device registration with +dahdi and the parameter B should be set. +dahdi_registration will simply become a no-op. + +=head1 SEE ALSO + +B(8), B(8). + diff --git a/xpp/echo_loader.c b/xpp/echo_loader.c new file mode 100644 index 0000000..ca92883 --- /dev/null +++ b/xpp/echo_loader.c @@ -0,0 +1,876 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "echo_loader.h" +#include "debug.h" +#include +#include "parse_span_specs.h" + +#define DBG_MASK 0x03 +#define TIMEOUT 1000 +#define ECHO_MAX_CHANS 128 +#define ECHO_RIN_STREAM 0 +#define ECHO_ROUT_STREAM 1 +#define ECHO_SIN_STREAM 2 +#define ECHO_SOUT_STREAM 3 + +#define ECHO_RIN_STREAM2 4 +#define ECHO_SIN_STREAM2 6 +#define ECHO_ROUT_STREAM2 5 +#define ECHO_SOUT_STREAM2 7 + +#define EC_VER_TEST 0xABCD +#define EC_VER_INVALID 0xFFFF +static float oct_fw_load_timeout = 2.0; + +struct echo_mod { + tPOCT6100_INSTANCE_API pApiInstance; + UINT32 ulEchoChanHndl[256]; + struct astribank_device *astribank; + int maxchans; +}; + +enum xpp_packet_types { + SPI_SND_XOP = 0x0F, + SPI_RCV_XOP = 0x10, + TST_SND_XOP = 0x35, + TST_RCV_XOP = 0x36, +}; + +struct xpp_packet_header { + struct { + uint16_t len; + uint8_t op; + uint8_t unit; + } PACKED header; + union { + struct { + uint8_t header; + uint8_t flags; + uint8_t addr_l; + uint8_t addr_h; + uint8_t data_l; + uint8_t data_h; + } PACKED spi_pack; + struct { + uint8_t tid; + uint8_t tsid; + } PACKED tst_pack; + } alt; +} PACKED; + +static struct usb_buffer { + char data[PACKET_SIZE]; + int max_len; + int curr; + /* statistics */ + int min_send; + int max_send; + int num_sends; + long total_bytes; + struct timeval start; + struct timeval end; +} usb_buffer; + + +static void usb_buffer_init(struct astribank_device *astribank, struct usb_buffer *ub) +{ + ub->max_len = xusb_packet_size(astribank->xusb); + ub->curr = 0; + ub->min_send = INT_MAX; + ub->max_send = 0; + ub->num_sends = 0; + ub->total_bytes = 0; + gettimeofday(&ub->start, NULL); +} + +static long usb_buffer_usec(struct usb_buffer *ub) +{ + struct timeval now; + + gettimeofday(&now, NULL); + return (now.tv_sec - ub->start.tv_sec) * 1000000 + + (now.tv_usec - ub->start.tv_usec); +} + +static void usb_buffer_showstatistics(struct astribank_device *astribank, struct usb_buffer *ub) +{ + long usec; + + usec = usb_buffer_usec(ub); + AB_INFO(astribank, "Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%ld\n", + ub->min_send, + ub->total_bytes / ub->num_sends, + ub->max_send, + ub->num_sends, ub->total_bytes, + usec / 1000, usec / ub->num_sends); +} + +static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffer *ub) +{ + int ret; + long t; + long sec; + static int last_sec; + + if (ub->curr == 0) + return 0; + ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT); + if (ret < 0) { + AB_ERR(astribank, "xusb_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + if (ret > ub->max_send) + ub->max_send = ret; + if (ret < ub->min_send) + ub->min_send = ret; + ub->total_bytes += ret; + ub->num_sends++; + ub->curr = 0; + + sec = usb_buffer_usec(ub) / (1000 * 1000); + if (sec > last_sec) { + DBG("bytes/sec=%ld average len=%ld\n", + ub->total_bytes / sec, + ub->total_bytes / ub->num_sends); + last_sec = sec; + } + + /* + * Best result with high frequency firmware: 21 seconds + * Octasic statistics: packet_size=[10, 239, 510] packets=26806, bytes=6419640 usec=21127883 usec/packet=788 + * t = 0.3 * ret - 150; + */ + t = oct_fw_load_timeout * ret - 150; + if (t > 0) + usleep(t); + return ret; +} + +static int usb_buffer_append(struct astribank_device *astribank, struct usb_buffer *ub, + char *buf, int len) +{ + if (ub->curr + len >= ub->max_len) { + AB_ERR(astribank, "%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n", + __func__, ub->curr, len, ub->max_len); + return -ENOMEM; + } + memcpy(ub->data + ub->curr, buf, len); + ub->curr += len; + return len; +} + +static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer *ub, + char *buf, int len, int timeout, int recv_answer) +{ + int ret = 0; + + if (ub->curr + len >= ub->max_len) { + ret = usb_buffer_flush(astribank, ub); + if (ret < 0) + return ret; + } + + if ((ret = usb_buffer_append(astribank, ub, buf, len)) < 0) { + return ret; + } + DBG("%s: %d bytes %s\n", __func__, len, (recv_answer) ? "recv" : "send"); + if (recv_answer) { + struct xpp_packet_header *phead; + + ret = usb_buffer_flush(astribank, ub); + if (ret < 0) + return ret; + ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT); + if (ret <= 0) { + AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret)); + return -EINVAL; + } + DBG("%s: %d bytes recv\n", __func__, ret); + phead = (struct xpp_packet_header *)buf; + if (phead->header.op != SPI_RCV_XOP && + phead->header.op != TST_RCV_XOP) { + AB_ERR(astribank, "Got unexpected reply OP=0x%02X\n", + phead->header.op); + dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", + buf, ret); + return -EINVAL; + } + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[R]", (char *)phead, phead->header.len); + switch(phead->header.op) { + case SPI_RCV_XOP: + ret = (phead->alt.spi_pack.data_h << 8) | phead->alt.spi_pack.data_l; + break; + case TST_RCV_XOP: + ret = (phead->alt.tst_pack.tid << 8) | phead->alt.tst_pack.tsid; + break; + default: + ret = -EINVAL; + } + } + return ret; +} + +int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver) +{ + int ret; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + int spi_flags; + + assert(astribank != NULL); + spi_flags = 0x30 | (recv_answer ? 0x40 : 0x00) | (ver ? 0x01 : 0x00); + pack_len = sizeof(phead->header) + sizeof(phead->alt.spi_pack); + phead->header.len = pack_len; + phead->header.op = SPI_SND_XOP; + phead->header.unit = 0x40; /* EC has always this unit num */ + phead->alt.spi_pack.header = 0x05; + phead->alt.spi_pack.flags = spi_flags; + phead->alt.spi_pack.addr_l = (addr >> 0) & 0xFF; + phead->alt.spi_pack.addr_h = (addr >> 8) & 0xFF; + phead->alt.spi_pack.data_l = (data >> 0) & 0xFF; + phead->alt.spi_pack.data_h = (data >> 8) & 0xFF; + + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[W]", (char *)phead, pack_len); + + + ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, recv_answer); + if (ret < 0) { + AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + return ret; +} + +int test_send(struct astribank_device *astribank) +{ + int ret; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + + assert(astribank != NULL); + pack_len = sizeof(phead->header) + sizeof(phead->alt.tst_pack); + phead->header.len = 6; + phead->header.op = 0x35; + phead->header.unit = 0x00; + phead->alt.tst_pack.tid = 0x28; /* EC TestId */ + phead->alt.tst_pack.tsid = 0x00; /* EC SubId */ + + dump_packet(LOG_DEBUG, DBG_MASK, "dump:echoline[W]", + (char *)phead, pack_len); + + ret = usb_buffer_send(astribank, + &usb_buffer, buf, pack_len, TIMEOUT, 1); + if (ret < 0) { + AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret); + return ret; + } + DBG("%s: Written %d bytes\n", __func__, ret); + return ret; +} + +int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data) +{ + int ret; +/* DBG("SEND: %04X -> [%04X]\n", data, addr); + DBG("\t\t[%04X] <- %04X\n", 0x0008, (addr >> 20)); + DBG("\t\t[%04X] <- %04X\n", 0x000A, (addr >> 4) & ((1 << 16) - 1)); + DBG("\t\t[%04X] <- %04X\n", 0x0004, data); + DBG("\t\t[%04X] <- %04X\n", 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1); + */ + + DBG("SND:\n"); + ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0004, data , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) | + (1 << 8) | (3 << 12) | 1 , 0, 0); + if (ret < 0) + goto failed; + return cOCT6100_ERR_OK; +failed: + AB_ERR(astribank, "echo_send_data: spi_send failed (ret = %d)\n", ret); + return ret; +} + +int echo_recv_data(struct astribank_device *astribank, const unsigned int addr) +{ + unsigned int data = 0x00; + int ret; + + DBG("RCV:\n"); + ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) | + (1 << 8) | 1 , 0, 0); + if (ret < 0) + goto failed; + ret = spi_send(astribank, 0x0004, data , 1, 0); + if (ret < 0) + goto failed; + return ret; +failed: + AB_ERR(astribank, "echo_recv_data: spi_send failed (ret = %d)\n", ret); + return ret; +} + +int load_file(char *filename, unsigned char **ppBuf, UINT32 *pLen) +{ + unsigned char *pbyFileData = NULL; + FILE *pFile; + + DBG("Loading %s file...\n", filename); + pFile = fopen(filename, "rb"); + if (pFile == NULL) { + ERR("fopen: %s\n", strerror(errno)); + return -ENODEV; + } + + fseek(pFile, 0L, SEEK_END); + *pLen = ftell(pFile); + fseek(pFile, 0L, SEEK_SET); + + pbyFileData = (unsigned char *)malloc(*pLen); + if (pbyFileData == NULL) { + fclose(pFile); + ERR("malloc\n"); + return -ENODEV; + } else { + DBG("allocated mem for pbyFileData\n"); + } + if (fread(pbyFileData, 1, *pLen, pFile) != *pLen) { + fclose(pFile); + ERR("fread: %s\n", strerror(errno)); + return -ENODEV; + } + fclose(pFile); + DBG("Successful loading %s file into memory " + "(size = %d, DUMP: first = %02X %02X, last = %02X %02X)\n", + filename, *pLen, + pbyFileData[0], pbyFileData[1], + pbyFileData[(*pLen)-2], pbyFileData[(*pLen)-1]); + *ppBuf = pbyFileData; + return 0; +} + +UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime) +{ + ///* Why couldn't they just take a timeval like everyone else? */ + struct timeval tv; + unsigned long long total_usecs; + unsigned int mask = ~0; + + gettimeofday(&tv, 0); + total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) + + (((unsigned long long)(tv.tv_usec))); + f_pTime->aulWallTimeUs[0] = (total_usecs & mask); + f_pTime->aulWallTimeUs[1] = (total_usecs >> 32); + //printf("Inside of Oct6100UserGetTime\n"); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength) +{ + memset(f_pAddress, f_ulPattern, f_ulLength); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength) +{ + memcpy(f_pDestination, f_pSource, f_ulLength); + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate) +{ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy) +{ +#ifdef OCTASIC_DEBUG + ERR("I should never be called! (destroy serialize object)\n"); +#endif + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize) +{ + /* Not needed */ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease) +{ + /* Not needed */ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams) +{ + const unsigned int addr = f_pWriteParams->ulWriteAddress; + const unsigned int data = f_pWriteParams->usWriteData; + const struct echo_mod *echo_mod = (struct echo_mod *)(f_pWriteParams->pProcessContext); + struct astribank_device *astribank = echo_mod->astribank; + int ret; + + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams) +{ + unsigned int addr; + unsigned int data; + unsigned int len; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + unsigned int i; + + len = f_pSmearParams->ulWriteLength; + echo_mod = (struct echo_mod *)f_pSmearParams->pProcessContext; + astribank = echo_mod->astribank; + for (i = 0; i < len; i++) { + int ret; + + addr = f_pSmearParams->ulWriteAddress + (i << 1); + data = f_pSmearParams->usWriteData; + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams) +{ + unsigned int addr; + unsigned int data; + unsigned int len = f_pBurstParams->ulWriteLength; + const struct echo_mod *echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext; + struct astribank_device *astribank = echo_mod->astribank; + unsigned int i; + + for (i = 0; i < len; i++) { + int ret; + + addr = f_pBurstParams->ulWriteAddress + (i << 1); + data = f_pBurstParams->pusWriteData[i]; + ret = echo_send_data(astribank, addr, data); + if (ret < 0) { + ERR("echo_send_data failed (ret = %d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_WRITE_API; + } + } + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams) +{ + const unsigned int addr = f_pReadParams->ulReadAddress; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + int ret; + + echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext; + astribank = echo_mod->astribank; + ret = echo_recv_data(astribank, addr); + if (ret < 0) { + ERR("echo_recv_data failed (%d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_READ_API; + } + *f_pReadParams->pusReadData = ret; + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams) +{ + unsigned int addr; + unsigned int len; + const struct echo_mod *echo_mod; + struct astribank_device *astribank; + unsigned int i; + + len = f_pBurstParams->ulReadLength; + echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext; + astribank = echo_mod->astribank; + for (i = 0;i < len; i++) { + unsigned int ret; + + addr = f_pBurstParams->ulReadAddress + (i << 1); + ret = echo_recv_data(astribank, addr); + if (ret < 0) { + ERR("echo_recv_data failed (%d)\n", ret); + return cOCT6100_ERR_FATAL_DRIVER_READ_API; + } + f_pBurstParams->pusReadData[i] = ret; + } + return cOCT6100_ERR_OK; +} + +inline int get_ver(struct astribank_device *astribank) +{ + return spi_send(astribank, 0, 0, 1, 1); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct span_specs *span_specs) +{ + int cpld_ver; + struct echo_mod *echo_mod; + UINT32 nChan; + UINT32 nSlot; + UINT32 pcmLaw; + UINT32 ulResult; + + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + tPOCT6100_INSTANCE_API pApiInstance; + tOCT6100_CHIP_OPEN OpenChip; + + UINT32 ulImageByteSize; + PUINT8 pbyImageData = NULL; + + /*=========================================================================*/ + /* Channel resources.*/ + tOCT6100_CHANNEL_OPEN ChannelOpen; + UINT32 ulChanHndl; + enum tdm_codec tdm_codec; + int spanno; + + if (test_send(astribank) < 0) + return cOCT6100_ERR_FATAL; + cpld_ver = get_ver(astribank); + AB_INFO(astribank, "Check EC_CPLD version: %d\n", cpld_ver); + if (cpld_ver < 0) + return cOCT6100_ERR_FATAL; + else if (cpld_ver == EC_VER_TEST) { + AB_INFO(astribank, "+---------------------------------------------------------+\n"); + AB_INFO(astribank, "| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n"); + AB_INFO(astribank, "+---------------------------------------------------------+\n"); + return cOCT6100_ERR_OK; + } + + + /**************************************************************************/ + /**************************************************************************/ + /* 1) Configure and Open the OCT6100. */ + /**************************************************************************/ + /**************************************************************************/ + + memset(&InstanceSize, 0, sizeof(tOCT6100_GET_INSTANCE_SIZE)); + memset(&OpenChip, 0, sizeof(tOCT6100_CHIP_OPEN)); + + echo_mod = malloc(sizeof(struct echo_mod)); + if (!echo_mod) { + AB_ERR(astribank, "cannot allocate memory for echo_mod\n"); + return cOCT6100_ERR_FATAL; + } + DBG("allocated mem for echo_mod\n"); + + memset(echo_mod, 0, sizeof(struct echo_mod)); + + /* Fill the OCT6100 Chip Open configuration structure with default values */ + + ulResult = Oct6100ChipOpenDef(&OpenChip); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100ChipOpenDef failed: result=%X\n", + ulResult); + return ulResult; + } + + OpenChip.pProcessContext = echo_mod; + /* Configure clocks */ + + /* upclk oscillator is at 33.33 Mhz */ + OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; + + /* mclk will be generated by internal PLL at 133 Mhz */ + OpenChip.fEnableMemClkOut = TRUE; + OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; + + /* General parameters */ + OpenChip.fEnableChannelRecording = TRUE; + + /* Chip ID.*/ + OpenChip.ulUserChipId = 1; + + /* Set the max number of accesses to 1024 to speed things up */ + /* OpenChip.ulMaxRwAccesses = 1024; */ + + /* Set the maximums that the chip needs to support for this test */ + OpenChip.ulMaxChannels = 256; + OpenChip.ulMaxPlayoutBuffers = 2; + + OpenChip.ulMaxBiDirChannels = 0; + OpenChip.ulMaxConfBridges = 0; + OpenChip.ulMaxPhasingTssts = 0; + OpenChip.ulMaxTdmStreams = 8; + OpenChip.ulMaxTsiCncts = 0; + + /* External Memory Settings: Use DDR memory*/ + OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; + + OpenChip.ulNumMemoryChips = 1; + OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB; + + + /* Load the image file */ + ulResult = load_file( filename, + &pbyImageData, + &ulImageByteSize); + + if (ulResult != 0) { + AB_ERR(astribank, "Failed load_file %s (%08X)\n", filename, ulResult); + return ulResult; + } + if (pbyImageData == NULL || ulImageByteSize == 0){ + AB_ERR(astribank, "Bad pbyImageData or ulImageByteSize\n"); + return cOCT6100_ERR_FATAL; + } + + /* Assign the image file.*/ + OpenChip.pbyImageFile = pbyImageData; + OpenChip.ulImageSize = ulImageByteSize; + + /* + * Inserting default values into tOCT6100_GET_INSTANCE_SIZE + * structure parameters. + */ + Oct6100GetInstanceSizeDef(&InstanceSize); + + /* Get the size of the OCT6100 instance structure. */ + ulResult = Oct6100GetInstanceSize(&OpenChip, &InstanceSize); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100GetInstanceSize failed (%08X)\n", + ulResult); + return ulResult; + } + + pApiInstance = malloc(InstanceSize.ulApiInstanceSize); + echo_mod->pApiInstance = pApiInstance; + echo_mod->astribank = astribank; + + if (!pApiInstance) { + AB_ERR(astribank, "Out of memory (can't allocate %d bytes)!\n", + InstanceSize.ulApiInstanceSize); + return cOCT6100_ERR_FATAL; + } + + /* Perform actual open of chip */ + ulResult = Oct6100ChipOpen(pApiInstance, &OpenChip); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Oct6100ChipOpen failed: result=%X\n", + ulResult); + return ulResult; + } + DBG("%s: OCT6100 is open\n", __func__); + + /* Free the image file data */ + free(pbyImageData); + + /**************************************************************************/ + /**************************************************************************/ + /* 2) Open channels in echo cancellation mode. */ + /**************************************************************************/ + /**************************************************************************/ + + for (nChan = 0; nChan < ECHO_MAX_CHANS; nChan++) { + nSlot = nChan; + /* open a channel.*/ + Oct6100ChannelOpenDef(&ChannelOpen); + + /* Assign the handle memory.*/ + ChannelOpen.pulChannelHndl = &ulChanHndl; + + /* Set the channel to work at the echo cancellation mode.*/ + ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + spanno = nChan % 4; + assert(spanno >= 0 && spanno < MAX_SPANNO); + tdm_codec = span_specs->span_is_alaw[spanno]; + if (tdm_codec == TDM_CODEC_UNKNOWN) { + AB_ERR(astribank, "Calculated bad alaw/ulaw on channel %d\n", nChan); + return cOCT6100_ERR_FATAL; + } + if (nChan < 4) + AB_INFO(astribank, "ECHO PRI port %d = %s\n", spanno+1, (tdm_codec == TDM_CODEC_ALAW) ? "alaw" : "ulaw"); + + pcmLaw = ((tdm_codec == TDM_CODEC_ALAW) ? cOCT6100_PCM_A_LAW: cOCT6100_PCM_U_LAW); + + /* Configure the TDM interface.*/ + ChannelOpen.TdmConfig.ulRinPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulRinStream = ECHO_RIN_STREAM; + ChannelOpen.TdmConfig.ulRinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSinPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulSinStream = ECHO_SIN_STREAM; + ChannelOpen.TdmConfig.ulSinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulRoutPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulRoutStream = ECHO_ROUT_STREAM; + ChannelOpen.TdmConfig.ulRoutTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSoutPcmLaw = pcmLaw; + ChannelOpen.TdmConfig.ulSoutStream = ECHO_SOUT_STREAM; + ChannelOpen.TdmConfig.ulSoutTimeslot = nSlot; + + /* Set the desired VQE features.*/ + ChannelOpen.VqeConfig.fEnableNlp = TRUE; + ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; + + ChannelOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + cOCT6100_COMFORT_NOISE_EXTENDED, + cOCT6100_COMFORT_NOISE_OFF, + cOCT6100_COMFORT_NOISE_FAST_LATCH + */ + ulResult = Oct6100ChannelOpen( pApiInstance, + &ChannelOpen); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Found error on chan %d\n", nChan); + return ulResult; + } + } + + /**************************************************************************/ + /**************************************************************************/ + /* *) Open channels in echo cancellation mode for second bus. */ + /**************************************************************************/ + /**************************************************************************/ + + for (nChan = 8; nChan < 32; nChan++) { + nSlot = (nChan >> 3) * 32 + (nChan & 0x07); + /* open a channel.*/ + Oct6100ChannelOpenDef(&ChannelOpen); + + /* Assign the handle memory.*/ + ChannelOpen.pulChannelHndl = &ulChanHndl; + + /* Set the channel to work at the echo cancellation mode.*/ + ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + /* Configure the TDM interface.*/ + ChannelOpen.TdmConfig.ulRinStream = ECHO_RIN_STREAM2;; + ChannelOpen.TdmConfig.ulRinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSinStream = ECHO_SIN_STREAM2; + ChannelOpen.TdmConfig.ulSinTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulRoutStream = ECHO_ROUT_STREAM2; + ChannelOpen.TdmConfig.ulRoutTimeslot = nSlot; + + ChannelOpen.TdmConfig.ulSoutStream = ECHO_SOUT_STREAM2; + ChannelOpen.TdmConfig.ulSoutTimeslot = nSlot; + + /* Set the desired VQE features.*/ + ChannelOpen.VqeConfig.fEnableNlp = TRUE; + ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; + + ChannelOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + cOCT6100_COMFORT_NOISE_EXTENDED, + cOCT6100_COMFORT_NOISE_OFF, + cOCT6100_COMFORT_NOISE_FAST_LATCH + */ + ulResult = Oct6100ChannelOpen( pApiInstance, + &ChannelOpen); + if (ulResult != cOCT6100_ERR_OK) { + AB_ERR(astribank, "Found error on chan %d\n", nChan); + return ulResult; + } + } + + + DBG("%s: Finishing\n", __func__); + free(pApiInstance); + free(echo_mod); + return cOCT6100_ERR_OK; + +} +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int load_echo(struct astribank_device *astribank, char *filename, int default_is_alaw, const char *span_spec) +{ + int ret; + UINT32 octasic_status; + struct span_specs *span_specs; + + span_specs = parse_span_specifications(span_spec, default_is_alaw); + if (!span_specs) { + AB_ERR(astribank, "ECHO parsing span specs failed\n"); + return -EFAULT; + } + AB_INFO(astribank, "Loading ECHOCAN Firmware: %s (default %s)\n", + filename, (default_is_alaw) ? "alaw" : "ulaw"); + usb_buffer_init(astribank, &usb_buffer); + octasic_status = init_octasic(filename, astribank, span_specs); + free_span_specifications(span_specs); + if (octasic_status != cOCT6100_ERR_OK) { + AB_ERR(astribank, "ECHO %s burning failed (%08X)\n", + filename, octasic_status); + return -ENODEV; + } + ret = usb_buffer_flush(astribank, &usb_buffer); + if (ret < 0) { + AB_ERR(astribank, "ECHO %s buffer flush failed (%d)\n", filename, ret); + return -ENODEV; + } + usb_buffer_showstatistics(astribank, &usb_buffer); + return 0; +} + +int echo_ver(struct astribank_device *astribank) +{ + usb_buffer_init(astribank, &usb_buffer); + return get_ver(astribank); +} + diff --git a/xpp/echo_loader.h b/xpp/echo_loader.h new file mode 100644 index 0000000..2bffda2 --- /dev/null +++ b/xpp/echo_loader.h @@ -0,0 +1,32 @@ +#ifndef ECHO_LOADER_H +#define ECHO_LOADER_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include "astribank_usb.h" + +int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver); +int load_echo(struct astribank_device *astribank, char *filename, int is_alaw, const char *span_spec); +int echo_ver(struct astribank_device *astribank); + +#endif /* ECHO_LOADER_H */ diff --git a/xpp/genconf_parameters b/xpp/genconf_parameters new file mode 100644 index 0000000..c27f960 --- /dev/null +++ b/xpp/genconf_parameters @@ -0,0 +1,169 @@ +# +# /etc/dahdi/genconf_parameters +# +# This file contains parameters that affect the +# dahdi_genconf configuration generator. +# +# Syntax: +# * A comment from '#' to end of line +# * Blank lines ignored +# * Whitespace at end of line trimmed +# * Single valued items: +# key value +# * List valued items: +# key +# value1 +# value2 +# ... +# + +# When generating extensions for chan_dahdi.conf or users.conf etc: the +# extension number will be channel_number+base_exten . The default is: +#base_exten 4000 +# +# Make FXS (analog phones) extensions answer immediately (sets +# 'immediate = yes' for them in chan_dahdi.conf). Don't enable this before +# you're read documentation about this option. +#fxs_immediate yes +# +# For FXS (analog phones) - use KS or LS? ks is the only method for +# Asterisk to provide disconnect supervision and thus it would normally +# be preferred and is the default. +#fxs_default_start ls +# +# For FXO (analog lines) - use KS or LS? KS is the default and is +# normally the better choice as it allows detecting hang-ups on many +# lines. +#fxo_default_start ls + +# Set tone zone values. This is used for playing tones (busy, dial-tone +# and such). The default is 'us'. This sets the value for both loadzone +# and defaultzone in system.conf . +#lc_country il + +# The dialplan context into which to send trunks in chan_dahdi.conf or +# users.conf. The default value is: +#context_lines from-pstn +# +# The dialplan context into which to send extensions in chan_dahdi.conf or +# users.conf. The default value is: +#context_phones from-internal +# +# Two extra contexts for the input ports and output ports of an +# Astribank. Default values are: +#context_input astbank-input +#context_output astbank-output + +# A group to put all analog phones in. By default 0, so you can dial to +# the 'first phone available' using Dahdi/g5 . +#group_phones 5 +# +# A group in which to put all the channels belonging to some trunk. +# Thus you can dial through "some trunk" using Dahdi/G0/NUMBER +#group_lines 0 + +# Channels of digital trunk of span N are also added to group 10+N (that +# is: 14 for channels of span 4). + +# Do we want to use PtP ('bri') or PtMP ('bri_ptmp') for BRI? PtMP +# allows connecting several CPE devices on the same network device +# (several BRI phones on the same line, kind of like several analog +# phones on the same analog line). However it is generally brings +# unnecessary complexity for a pbx-pbx connection. It is still the +# default as this is normally what you get for a BRI PSTN connection. +#bri_sig_style bri +# +# If this option is set (that is: not remmed-out), BRI NT ports will +# also be set as overlap. This is useful if you want to connect ISDN +# phones. +#brint_overlap + +# The echo canceler to use. If you have a hardware echo canceler, just +# leave it be, as this one won't be used anyway. +# +# The default is mg2, but it may change in the future. E.g: a packager +# that bundles a better echo canceler may set it as the default, or +# dahdi_genconf will scan for the "best" echo canceler. +# +#echo_can hpec +#echo_can oslec +#echo_can none # to avoid echo canceler altogether + +# bri_hardhdlc: +# 'yes' - forces BRI cards to use 'hardhdlc' signalling. +# 'no' - forces BRI cards to use 'dchan' (an alias for 'fcshdlc'). +# It is usefull only for dahdi with the bristuff patch. +# +# If it is left out or set to 'auto': +# * Information supplied by the driver is used to decide: +# - Currently implemented for Astribanks. +# - Taken from /sys/bus/xpds/drivers/bri/dchan_hardhdlc. +# * Without this info, falls back to 'hardhdlc'. +#bri_hardhdlc auto + +# For MFC/R2 Support: 'R2' will make E1 spans CAS and with the +# 'r2_idle_bits' bit in system.conf . It will also make dahdi_genconf default +# to generating the channels of this card in unicall.conf rather than in +# chan_dahdi.conf . The meaning of this may be extended somehow to support +# R2 through openr2/chan_dahdi later on. +#pri_connection_type R2 +#pri_connection_type CAS +# +# Explicitly set the idle bits for E1 CAS (Sample value is the default): +#r2_idle_bits 1101 +# +# Set T1 framing type to d4 instead of esf: +#tdm_framing d4 +# +# Use E&M on CAS (default is FXS/FXO). If set, E1 spans will be used as +# E&M-E1 and T1 will use the requested type: +#em_signalling em +#em_signalling em_w +#em_signalling featd +#em_signalling featdtmf +#em_signalling featdtmf_ta +#em_signalling featb +#em_signalling fgccama +#em_signalling fgccamamf +# +# pri_termtype contains a list of settings: +# Currently the only setting is for TE or NT (the default is TE). This +# sets two different but normally related configuration items: +# +# A TE span will have *_cpe signalling in Asterisk and will also get +# timing from the remote party. +# +# A NT span will have *_new signalling in Asterisk and will provide +# timing to the remote party. +# +# pri_termtype is a list if span specs and configuration (TE/NT) for +# them. The first spec that matches is used. The matching is of perl +# regular expressions, but with '*' and '?' have their meaning from +# basic regular expressions. +#pri_termtype +# SPAN/2 NT +# SPAN/4 NT +# +#pri_termtype +# SPAN/* NT +# +# Astribanks can be matched by span and also by their: +# LABEL + XPD number: +# this is burned into the Astribank and won't change +# if it's connected via different USB port/hub +# CONNECTOR + XPD number: +# The USB path to which the Astribank is connected. +# Replacing an Astribank and connecting to the same USB port/hub +# would not change this property. However, any change in USB +# wiring (e.g: adding another hub) may alter this. +# NUM (XBUS number) + XPD number: +# The XBUS number. This is not stable and may even change +# between boots. +# +#pri_termtype +# LABEL/usb:INT01216/XPD-0[123] NT +# LABEL/usb:INT00375/XPD-0[123] NT +# CONNECTOR/@usb-0000:00:1d.7-1/XPD-0[123] NT +# CONNECTOR/@usb-0000:00:1d.7-2/XPD-0[123] NT +# NUM/XBUS-01/XPD-0[123] NT +# NUM/XBUS-03/XPD-0[123] NT diff --git a/xpp/hexfile.c b/xpp/hexfile.c new file mode 100644 index 0000000..1227b26 --- /dev/null +++ b/xpp/hexfile.c @@ -0,0 +1,568 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include "hexfile.h" + +static const char rcsid[] = "$Id$"; + +static parse_hexfile_report_func_t report_func = NULL; + +parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf) +{ + parse_hexfile_report_func_t old_rf = report_func; + report_func = rf; + return old_rf; +} + +static void chomp(char buf[]) +{ + size_t last = strlen(buf) - 1; + while(last >= 0 && isspace(buf[last])) + buf[last--] = '\0'; +} + +static int hexline_checksum(struct hexline *hexline) +{ + unsigned int i; + unsigned int chksm = 0; + int ll = hexline->d.content.header.ll; + + for(i = 0; i <= sizeof(hexline->d.content.header) + ll; i++) { + chksm += hexline->d.raw[i]; + } + return chksm & 0xFF; +} + +int dump_hexline(int recordno, struct hexline *line, FILE *fp) +{ + uint8_t ll; + uint16_t offset; + uint8_t tt; + uint8_t old_chksum; + uint8_t new_chksum; + uint8_t *data; + unsigned int i; + + ll = line->d.content.header.ll; + offset = line->d.content.header.offset; + tt = line->d.content.header.tt; + fprintf(fp, ":%02X%04X%02X", ll, offset, tt); + data = line->d.content.tt_data.data; + for(i = 0; i < ll; i++) { + fprintf(fp, "%02X", data[i]); + } + old_chksum = data[ll]; + data[ll] = 0; + new_chksum = 0xFF - hexline_checksum(line) + 1; + data[ll] = old_chksum; + fprintf(fp, "%02X\n", new_chksum); + if(new_chksum != old_chksum) { + if(report_func) + report_func(LOG_ERR, "record #%d: new_chksum(%02X) != old_chksum(%02X)\n", + recordno, new_chksum, old_chksum); + return 0; + } + return 1; +} + +struct hexline *new_hexline(uint8_t datalen, uint16_t offset, uint8_t tt) +{ + struct hexline *hexline; + size_t allocsize; + + allocsize = sizeof(struct hexline) + datalen + 1; /* checksum byte */ + if((hexline = malloc(allocsize)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return NULL; + } + memset(hexline, 0, allocsize); + hexline->d.content.header.ll = datalen; + hexline->d.content.header.offset = offset; + hexline->d.content.header.tt = tt; + return hexline; +} + +static int append_hexline(struct hexdata *hexdata, char *buf) +{ + int ret; + unsigned int ll, offset, tt; + char *p; + struct hexline *hexline; + unsigned int i; + + if(hexdata->got_eof) { + if(report_func) + report_func(LOG_ERR, "Extranous data after EOF record\n"); + return -EINVAL; + } + if(hexdata->last_line >= hexdata->maxlines) { + if(report_func) + report_func(LOG_ERR, "Hexfile too large (maxline %d)\n", hexdata->maxlines); + return -ENOMEM; + } + ret = sscanf(buf, "%02X%04X%02X", &ll, &offset, &tt); + if(ret != 3) { + if(report_func) + report_func(LOG_ERR, "Bad line header (only %d items out of 3 parsed)\n", ret); + return -EINVAL; + } + switch(tt) { + case TT_DATA: + break; + case TT_EOF: + if(ll != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + hexdata->got_eof = 1; + break; + case TT_EXT_SEG: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_START_SEG: + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_EXT_LIN: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; + case TT_START_LIN: /* Unimplemented */ + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; + default: + if(report_func) + report_func(LOG_ERR, "%d: Unimplemented record type %d: %s\n", + hexdata->last_line, tt, buf); + return -EINVAL; + } + buf += 8; /* Skip header */ + if((hexline = new_hexline(ll, offset, tt)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory for hexfile lines\n"); + return -EINVAL; + } + p = buf; + for(i = 0; i < ll + 1; i++) { /* include checksum */ + unsigned int val; + + if((*p == '\0') || (*(p+1) == '\0')) { + if(report_func) + report_func(LOG_ERR, "Short data string '%s'\n", buf); + return -EINVAL; + } + ret = sscanf(p, "%02X", &val); + if(ret != 1) { + if(report_func) + report_func(LOG_ERR, "Bad data byte #%d\n", i); + return -EINVAL; + } + hexline->d.content.tt_data.data[i] = val; + p += 2; + } + if(hexline_checksum(hexline) != 0) { + if(report_func) { + report_func(LOG_ERR, "Bad checksum (%d instead of 0)\n", + hexline_checksum(hexline)); + dump_hexline(hexdata->last_line, hexline, stderr); + } + return -EINVAL; + } + hexdata->lines[hexdata->last_line] = hexline; + if(hexdata->got_eof) + return 0; + hexdata->last_line++; + return 1; +} + +void free_hexdata(struct hexdata *hexdata) +{ + if(hexdata) { + unsigned int i; + + for(i = 0; i < hexdata->maxlines; i++) + if(hexdata->lines[i] != NULL) + free(hexdata->lines[i]); + free(hexdata); + } +} + +int dump_hexfile(struct hexdata *hexdata, const char *outfile) +{ + FILE *fp; + unsigned int i; + + if(report_func) + report_func(LOG_INFO, "Dumping hex data into '%s'\n", outfile); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + for(i = 0; i <= hexdata->last_line; i++) { + struct hexline *line = hexdata->lines[i]; + if(!line) { + if(report_func) + report_func(LOG_ERR, "Missing line at #%d\n", i); + return -EINVAL; + } + if(!dump_hexline(i, line, fp)) + return -EINVAL; + } + return 0; +} + +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth) +{ + FILE *fp; + uint8_t tt; + unsigned int i; + struct hexline *line; + + if(report_func) + report_func(LOG_INFO, + "Dumping hex data into '%s' (maxwidth=%d)\n", + outfile, maxwidth); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + if(maxwidth == 0) + maxwidth = UINT8_MAX; + for(i = 0; i <= hexdata->last_line; i++) { + int bytesleft = 0; + int extra_offset = 0; + int base_offset; + uint8_t *base_data; + + line = hexdata->lines[i]; + if(!line) { + if(report_func) + report_func(LOG_ERR, "Missing line at #%d\n", i); + return -EINVAL; + } + bytesleft = line->d.content.header.ll; + /* split the line into several lines */ + tt = line->d.content.header.tt; + base_offset = line->d.content.header.offset; + base_data = line->d.content.tt_data.data; + while (bytesleft > 0) { + struct hexline *extraline; + uint8_t new_chksum; + unsigned int curr_bytes = (bytesleft >= maxwidth) ? maxwidth : bytesleft; + + /* generate the new line */ + if((extraline = new_hexline(curr_bytes, base_offset + extra_offset, tt)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory for hexfile lines\n"); + return -EINVAL; + } + memcpy(extraline->d.content.tt_data.data, base_data + extra_offset, curr_bytes); + new_chksum = 0xFF - hexline_checksum(extraline) + 1; + extraline->d.content.tt_data.data[curr_bytes] = new_chksum; + /* print it */ + dump_hexline(i, extraline, fp); + /* cleanups */ + free(extraline); + extra_offset += curr_bytes; + bytesleft -= curr_bytes; + } + } + if(tt != TT_EOF) { + if(report_func) + report_func(LOG_ERR, "Missing EOF record\n"); + return -EINVAL; + } + dump_hexline(i, line, fp); + return 0; +} + +void process_comment(struct hexdata *hexdata, char buf[]) +{ + char *dollar_start; + char *dollar_end; + const char id_prefix[] = "Id: "; + char tmp[BUFSIZ]; + char *p; + int len; + + if(report_func) + report_func(LOG_INFO, "Comment: %s\n", buf + 1); + /* Search for RCS keywords */ + if((dollar_start = strchr(buf, '$')) == NULL) + return; + if((dollar_end = strchr(dollar_start + 1, '$')) == NULL) + return; + /* Crop the '$' signs */ + len = dollar_end - dollar_start; + len -= 2; + memcpy(tmp, dollar_start + 1, len); + tmp[len] = '\0'; + p = tmp; + if(strstr(tmp, id_prefix) == NULL) + return; + p += strlen(id_prefix); + if((p = strchr(p, ' ')) == NULL) + return; + p++; + snprintf(hexdata->version_info, BUFSIZ, "%s", p); + if((p = strchr(hexdata->version_info, ' ')) != NULL) + *p = '\0'; +} + +struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines) +{ + FILE *fp; + struct hexdata *hexdata = NULL; + int datasize; + char buf[BUFSIZ]; + int line; + int dos_eof = 0; + int ret; + + assert(fname != NULL); + if(report_func) + report_func(LOG_INFO, "Parsing %s\n", fname); + datasize = sizeof(struct hexdata) + maxlines * sizeof(char *); + hexdata = (struct hexdata *)malloc(datasize); + if(!hexdata) { + if(report_func) + report_func(LOG_ERR, "Failed to allocate %d bytes for hexfile contents\n", datasize); + goto err; + } + memset(hexdata, 0, datasize); + hexdata->maxlines = maxlines; + if((fp = fopen(fname, "r")) == NULL) { + if(report_func) + report_func(LOG_ERR, "Failed to open hexfile '%s'\n", fname); + goto err; + } + snprintf(hexdata->fname, PATH_MAX, "%s", fname); + for(line = 1; fgets(buf, BUFSIZ, fp); line++) { + if(dos_eof) { + if(report_func) + report_func(LOG_ERR, "%s:%d - Got DOS EOF character before true EOF\n", fname, line); + goto err; + } + if(buf[0] == 0x1A && buf[1] == '\0') { /* DOS EOF char */ + dos_eof = 1; + continue; + } + chomp(buf); + if(buf[0] == '\0') { + if(report_func) + report_func(LOG_ERR, "%s:%d - Short line\n", fname, line); + goto err; + } + if(buf[0] == '#') { + process_comment(hexdata, buf); + continue; + } + if(buf[0] != ':') { + if(report_func) + report_func(LOG_ERR, "%s:%d - Line begins with 0x%X\n", fname, line, buf[0]); + goto err; + } + if((ret = append_hexline(hexdata, buf + 1)) < 0) { + if(report_func) + report_func(LOG_ERR, "%s:%d - Failed parsing.\n", fname, line); + goto err; + } + } + fclose(fp); + if(report_func) + report_func(LOG_INFO, "%s parsed OK\n", fname); + return hexdata; +err: + free_hexdata(hexdata); + return NULL; +} + +void dump_binary(struct hexdata *hexdata, const char *outfile) +{ + FILE *fp; + unsigned int i; + size_t len; + + if(report_func) + report_func(LOG_INFO, "Dumping binary data into '%s'\n", outfile); + if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + + if(!hexline) + break; + switch(hexline->d.content.header.tt) { + case TT_EOF: + if(report_func) + report_func(LOG_INFO, "\ndump: good EOF record"); + break; + case TT_DATA: + if(report_func) + report_func(LOG_INFO, "dump: %6d\r", i); + len = hexline->d.content.header.ll; + if(fwrite(hexline->d.content.tt_data.data, 1, len, fp) != len) { + perror("write"); + exit(1); + } + break; + case TT_EXT_SEG: + case TT_START_SEG: + case TT_EXT_LIN: + case TT_START_LIN: + if(report_func) + report_func(LOG_INFO, + "\ndump(%d): ignored record type %d", + i, hexline->d.content.header.tt); + break; + default: + if(report_func) + report_func(LOG_ERR, "dump: Unknown record type %d\n", + hexline->d.content.header.tt); + exit(1); + } + } + if(report_func) + report_func(LOG_INFO, "\nDump finished\n"); + fclose(fp); +} + +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output) +{ + struct hexline *hexline; + + if(!data) { + fprintf(output, ":%02X%04X%02XFF\n", 0, 0, TT_EOF); + return; + } + if((hexline = new_hexline(len, addr, (!data) ? TT_EOF : TT_DATA)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return; + } + if(data) + memcpy(&hexline->d.content.tt_data, data, len); + dump_hexline(0, hexline, output); + free(hexline); +} + +/* + * Algorithm lifted of sum(1) implementation from coreutils. + * We chose the default algorithm (BSD style). + */ +int bsd_checksum(struct hexdata *hexdata) +{ + unsigned int i; + size_t len; + int ck = 0; + + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline = hexdata->lines[i]; + unsigned char *p; + + if(!hexline) + break; + if(hexline->d.content.header.tt == TT_EOF) + continue; + len = hexline->d.content.header.ll; + p = hexline->d.content.tt_data.data; + for(; len; p++, len--) { + ck = (ck >> 1) + ((ck & 1) << 15); + ck += *p; + ck &= 0xffff; /* Keep it within bounds. */ + } + } + return ck; +} diff --git a/xpp/hexfile.h b/xpp/hexfile.h new file mode 100644 index 0000000..27c71e7 --- /dev/null +++ b/xpp/hexfile.h @@ -0,0 +1,87 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef PARSE_HEXFILE_H +#define PARSE_HEXFILE_H + +#include +#include +#include +#include +#include +#define PACKED __attribute__((packed)) +#define ZERO_SIZE 0 + +/* Record types in hexfile */ +enum { + TT_DATA = 0, + TT_EOF = 1, + TT_EXT_SEG = 2, + TT_START_SEG = 3, + TT_EXT_LIN = 4, + TT_START_LIN = 5, + TT_NO_SUCH_TT +}; + +#pragma pack(1) +struct hexline { + union { + uint8_t raw[ZERO_SIZE]; + struct content { + struct header { + uint8_t ll; /* len */ + uint16_t offset; /* offset */ + uint8_t tt; /* type */ + } PACKED header; + struct tt_data { + uint8_t data[ZERO_SIZE]; + } tt_data; + } PACKED content; + } d; +} PACKED; +#pragma pack() + +struct hexdata { + unsigned int maxlines; + unsigned int last_line; + int got_eof; + char fname[PATH_MAX]; + char version_info[BUFSIZ]; + struct hexline *lines[ZERO_SIZE]; +}; + + +__BEGIN_DECLS + +typedef void (*parse_hexfile_report_func_t)(int level, const char *msg, ...); + +parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf); +void free_hexdata(struct hexdata *hexdata); +struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines); +int dump_hexfile(struct hexdata *hexdata, const char *outfile); +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth); +void dump_binary(struct hexdata *hexdata, const char *outfile); +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output); +int bsd_checksum(struct hexdata *hexdata); +__END_DECLS + +#endif diff --git a/xpp/lsdahdi b/xpp/lsdahdi new file mode 100755 index 0000000..2e68d44 --- /dev/null +++ b/xpp/lsdahdi @@ -0,0 +1,110 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Xpd; + +my @xbuses = Dahdi::Xpp::xbuses; +my @xpds = map { $_->xpds } @xbuses; + +foreach my $span (Dahdi::spans()) { + my $spanno = $span->num; + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my @lines; + my $index = 0; + + @lines = @{$xpd->lines} if defined $xpd; + printf "### Span %2d: %s %s\n", $span->num, $span->name, $span->description; + foreach my $chan ($span->chans()) { + my %type_map = ( + OUT => 'Output', + IN => 'Input' + ); + my ($type) = map { $type_map{$_} or $_ } $chan->type || ("unknown"); + my $batt = ""; + $batt = "(battery)" if $chan->battery; + my @alarms = $chan->alarms; + my $alarm_str = join(" ", @alarms); + printf "%3d %-10s %-10s %s %s %s\n", + $chan->num, $type, $chan->signalling, $chan->info, $batt, $alarm_str; + $index++; + } +} + +__END__ + +=head1 NAME + +lsdahdi - List all Dahdi channels with their types and spans. + +=head1 SYNOPSIS + +lsdahdi + +=head1 DESCRIPTION + +Example output: + + ### Span 1: WCTDM/0 "Wildcard TDM400P REV E/F Board 1" + 1 FXO FXOLS (In use) + 2 FXS FXSKS + 3 FXS FXSKS + 4 FXS FXSKS + ### Span 2: XBUS-00/XPD-00 "Xorcom XPD #00/00: FXO" + 5 FXO FXSKS (In use) + 6 FXO FXSKS (In use) (no pcm) + 7 FXO FXSKS (In use) (no pcm) + 8 FXO FXSKS (In use) (no pcm) + 9 FXO FXSKS (In use) (no pcm) + 10 FXO FXSKS (In use) (no pcm) + 11 FXO FXSKS (In use) (no pcm) + 12 FXO FXSKS (In use) (no pcm) + ### Span 3: XBUS-00/XPD-10 "Xorcom XPD #00/10: FXO" + 13 FXO FXSKS (In use) (no pcm) + 14 FXO FXSKS (In use) (no pcm) + 15 FXO FXSKS (In use) (no pcm) + 16 FXO FXSKS (In use) (no pcm) + 17 FXO FXSKS (In use) (no pcm) + 18 FXO FXSKS (In use) (no pcm) + 19 FXO FXSKS (In use) (no pcm) + 20 FXO FXSKS (In use) (no pcm) + + ... + + ### Span 6: XBUS-01/XPD-00 "Xorcom XPD #01/00: FXS" + 37 FXS FXOLS (In use) + 38 FXS FXOLS (In use) (no pcm) + 39 FXS FXOLS (In use) (no pcm) + 40 FXS FXOLS (In use) (no pcm) + 41 FXS FXOLS (In use) (no pcm) + 42 FXS FXOLS (In use) (no pcm) + 43 FXS FXOLS (In use) (no pcm) + 44 FXS FXOLS (In use) (no pcm) + 45 Output FXOLS (In use) (no pcm) + 46 Output FXOLS (In use) (no pcm) + 47 Input FXOLS (In use) (no pcm) + 48 Input FXOLS (In use) (no pcm) + 49 Input FXOLS (In use) (no pcm) + 50 Input FXOLS (In use) (no pcm) + +The first column is the type of the channel (port, for an analog device) +and the second one is the signalling (if set). + +=head1 FILES + +lsdahdi is a somewhat glorified 'cat /proc/dahdi/*' . Unlike that +command, it sorts the spans with the proper order. It also formats the +output slightly differently. diff --git a/xpp/mpp.h b/xpp/mpp.h new file mode 100644 index 0000000..53ea81e --- /dev/null +++ b/xpp/mpp.h @@ -0,0 +1,202 @@ +#ifndef MPP_H +#define MPP_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * MPP - Managment Processor Protocol definitions + */ + +#include +#include +#include + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#error "We do not know how your compiler packs structures" +#endif + +#define MK_PROTO_VERSION(major, minor) (((major) << 4) | (0x0F & (minor))) + +#define MPP_PROTOCOL_VERSION MK_PROTO_VERSION(1,4) +#define MPP_SUPPORTED_VERSION(x) ((x) == MK_PROTO_VERSION(1,3) || (x) == MK_PROTO_VERSION(1,4)) + +/* + * The eeprom_table is common to all eeprom types. + */ +#define LABEL_SIZE 8 +struct eeprom_table { + uint8_t source; /* C0 - small eeprom, C2 - large eeprom */ + uint16_t vendor; + uint16_t product; + uint16_t release; /* BCD encoded release */ + uint8_t config_byte; /* Must be 0 */ + uint8_t label[LABEL_SIZE]; +} PACKED; + +#define VERSION_LEN 6 +struct firmware_versions { + char usb[VERSION_LEN]; + char fpga[VERSION_LEN]; + char eeprom[VERSION_LEN]; +} PACKED; + +struct capabilities { + uint8_t ports_fxs; + uint8_t ports_fxo; + uint8_t ports_bri; + uint8_t ports_pri; + uint8_t extra_features; /* BIT(0) - TwinStar */ + uint8_t ports_echo; + uint8_t reserved[2]; + uint32_t timestamp; +} PACKED; + +#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01) +#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0) +#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0) + +#define KEYSIZE 16 + +struct capkey { + uint8_t k[KEYSIZE]; +} PACKED; + +struct extrainfo { + char text[EXTRAINFO_SIZE]; +} PACKED; + +struct mpp_header { + uint16_t len; + uint16_t seq; + uint8_t op; /* MSB: 0 - to device, 1 - from device */ +} PACKED; + +enum mpp_ser_op { + SER_CARD_INFO_GET = 0x1, + SER_STAT_GET = 0x3, +/* Status bits */ +#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01) +#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02) +}; + +/* Individual commands structure */ + +CMD_DEF(MPP, STATUS_GET); + + +CMD_DEF(MPP, STATUS_GET_REPLY, + uint8_t i2cs_data; + +#define STATUS_FPGA_LOADED(x) ((x) & 0x01) + uint8_t status; /* BIT(0) - FPGA is loaded */ + struct firmware_versions fw_versions; + ); + +CMD_DEF(MPP, EEPROM_SET, + struct eeprom_table data; + ); + +CMD_DEF(MPP, CAPS_GET); + +CMD_DEF(MPP, CAPS_GET_REPLY, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, CAPS_SET, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, EXTRAINFO_GET); + +CMD_DEF(MPP, EXTRAINFO_GET_REPLY, + struct extrainfo info; + ); + +CMD_DEF(MPP, EXTRAINFO_SET, + struct extrainfo info; + ); + +CMD_DEF(MPP, RENUM); + +CMD_DEF(MPP, EEPROM_BLK_RD, + uint16_t offset; + uint16_t len; + ); + +CMD_DEF(MPP, EEPROM_BLK_RD_REPLY, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, DEV_SEND_START, + uint8_t dest; + char ihex_version[VERSION_LEN]; + ); + +CMD_DEF(MPP, DEV_SEND_END); + +CMD_DEF(MPP, DEV_SEND_SEG, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, RESET); +CMD_DEF(MPP, HALF_RESET); + +CMD_DEF(MPP, SER_SEND, + uint8_t data[0]; + ); + +CMD_DEF(MPP, SER_RECV, + uint8_t data[0]; + ); + +CMD_DEF(MPP, TWS_WD_MODE_SET, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_WD_MODE_GET); +CMD_DEF(MPP, TWS_WD_MODE_GET_REPLY, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_PORT_SET, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PORT_GET); +CMD_DEF(MPP, TWS_PORT_GET_REPLY, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PWR_GET); +CMD_DEF(MPP, TWS_PWR_GET_REPLY, + uint8_t power; + ); + +#endif /* MPP_H */ diff --git a/xpp/mpptalk.c b/xpp/mpptalk.c new file mode 100644 index 0000000..e49c3cd --- /dev/null +++ b/xpp/mpptalk.c @@ -0,0 +1,956 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "astribank_usb.h" +#include "mpp.h" +#include "mpptalk.h" +#include +#include +#include + +static const char rcsid[] = "$Id$"; + +#define DBG_MASK 0x02 + +const char *ack_status_msg(uint8_t status) +{ + const static char *msgs[] = { + [STAT_OK] = "Acknowledges previous command", + [STAT_FAIL] = "Last command failed", + [STAT_RESET_FAIL] = "Reset failed", + [STAT_NODEST] = "No destination is selected", + [STAT_MISMATCH] = "Data mismatch", + [STAT_NOACCESS] = "No access", + [STAT_BAD_CMD] = "Bad command", + [STAT_TOO_SHORT] = "Packet is too short", + [STAT_ERROFFS] = "Offset error", + [STAT_NOCODE] = "Source was not burned before", + [STAT_NO_LEEPROM] = "Large EEPROM was not found", + [STAT_NO_EEPROM] = "No EEPROM was found", + [STAT_WRITE_FAIL] = "Writing to device failed", + [STAT_FPGA_ERR] = "FPGA error", + [STAT_KEY_ERR] = "Bad Capabilities Key", + [STAT_NOCAPS_ERR] = "No matching capability", + [STAT_NOPWR_ERR] = "No power on USB connector", + [STAT_CAPS_FPGA_ERR] = "Setting of the capabilities while FPGA is loaded", + }; + if(status > sizeof(msgs)/sizeof(msgs[0])) + return "ERROR CODE TOO LARGE"; + if(!msgs[status]) + return "MISSING ERROR CODE"; + return msgs[status]; +} + +const char *eeprom_type2str(int et) +{ + const static char *msgs[] = { + [EEPROM_TYPE_NONE] = "NONE", + [EEPROM_TYPE_SMALL] = "SMALL", + [EEPROM_TYPE_LARGE] = "LARGE", + [EEPROM_TYPE_UNUSED] = "UNUSED", + }; + if(et > sizeof(msgs)/sizeof(msgs[0])) + return NULL; + return msgs[et]; +}; + +const char *dev_dest2str(int dest) +{ + const static char *msgs[] = { + [DEST_NONE] = "NONE", + [DEST_FPGA] = "FPGA", + [DEST_EEPROM] = "EEPROM", + }; + if(dest > sizeof(msgs)/sizeof(msgs[0])) + return NULL; + return msgs[dest]; +}; + +union XTALK_PDATA(MPP) { + MEMBER(MPP, STATUS_GET); + MEMBER(MPP, STATUS_GET_REPLY); + MEMBER(MPP, EEPROM_SET); + MEMBER(MPP, CAPS_GET); + MEMBER(MPP, CAPS_GET_REPLY); + MEMBER(MPP, CAPS_SET); + MEMBER(MPP, EXTRAINFO_GET); + MEMBER(MPP, EXTRAINFO_GET_REPLY); + MEMBER(MPP, EXTRAINFO_SET); + MEMBER(MPP, RENUM); + MEMBER(MPP, EEPROM_BLK_RD); + MEMBER(MPP, EEPROM_BLK_RD_REPLY); + MEMBER(MPP, DEV_SEND_SEG); + MEMBER(MPP, DEV_SEND_START); + MEMBER(MPP, DEV_SEND_END); + MEMBER(MPP, RESET); + MEMBER(MPP, HALF_RESET); + MEMBER(MPP, SER_SEND); + MEMBER(MPP, SER_RECV); + /* Twinstar */ + MEMBER(MPP, TWS_WD_MODE_SET); + MEMBER(MPP, TWS_WD_MODE_GET); + MEMBER(MPP, TWS_WD_MODE_GET_REPLY); + MEMBER(MPP, TWS_PORT_SET); + MEMBER(MPP, TWS_PORT_GET); + MEMBER(MPP, TWS_PORT_GET_REPLY); + MEMBER(MPP, TWS_PWR_GET); + MEMBER(MPP, TWS_PWR_GET_REPLY); +} PACKED members; + +struct xtalk_protocol astribank_proto = { + .name = "ABNK", + .proto_version = 0x14, + .commands = { + CMD_SEND(MPP, STATUS_GET), + CMD_RECV(MPP, STATUS_GET_REPLY, NULL), + CMD_SEND(MPP, EEPROM_SET), + CMD_SEND(MPP, CAPS_GET), + CMD_RECV(MPP, CAPS_GET_REPLY, NULL), + CMD_SEND(MPP, CAPS_SET), + CMD_SEND(MPP, EXTRAINFO_GET), + CMD_RECV(MPP, EXTRAINFO_GET_REPLY, NULL), + CMD_SEND(MPP, EXTRAINFO_SET), + CMD_SEND(MPP, RENUM), + CMD_SEND(MPP, EEPROM_BLK_RD), + CMD_RECV(MPP, EEPROM_BLK_RD_REPLY, NULL), + CMD_SEND(MPP, DEV_SEND_SEG), + CMD_SEND(MPP, DEV_SEND_START), + CMD_SEND(MPP, DEV_SEND_END), + CMD_SEND(MPP, RESET), + CMD_SEND(MPP, HALF_RESET), + CMD_SEND(MPP, SER_SEND), + CMD_SEND(MPP, SER_RECV), + /* Twinstar */ + CMD_SEND(MPP, TWS_WD_MODE_SET), + CMD_SEND(MPP, TWS_WD_MODE_GET), + CMD_RECV(MPP, TWS_WD_MODE_GET_REPLY, NULL), + CMD_SEND(MPP, TWS_PORT_SET), + CMD_SEND(MPP, TWS_PORT_GET), + CMD_RECV(MPP, TWS_PORT_GET_REPLY, NULL), + CMD_SEND(MPP, TWS_PWR_GET), + CMD_RECV(MPP, TWS_PWR_GET_REPLY, NULL), + }, + .ack_statuses = { + } +}; + +struct cmd_queue { + struct cmd_queue *next; + struct cmd_queue *prev; + struct xtalk_command *cmd; +}; + +static struct cmd_queue output_queue = { + .next = &output_queue, + .prev = &output_queue, + .cmd = NULL + }; + +void dump_command(struct xtalk_command *cmd) +{ + uint16_t len; + int i; + + len = cmd->header.len; + if(len < sizeof(struct mpp_header)) { + ERR("Command too short (%d)\n", len); + return; + } + INFO("DUMP: OP=0x%X len=%d seq=%d\n", + cmd->header.op, cmd->header.len, cmd->header.seq); + for(i = 0; i < len - sizeof(struct mpp_header); i++) { + INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); + } +} + + +static int set_ihex_version(char *dst, const char *src) +{ + memcpy(dst, src, VERSION_LEN); + return 0; +} + +/* + * Protocol Commands + */ + +int mpp_status_query(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_STATUS_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + astribank->eeprom_type = 0x3 & (CMD_FIELD(reply, MPP, STATUS_GET_REPLY, i2cs_data) >> 3); + astribank->status = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, status); + astribank->fw_versions = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, fw_versions); + DBG("EEPROM TYPE: %02x\n", astribank->eeprom_type); + DBG("FPGA Firmware: %s\n", (astribank->status & 0x1) ? "Loaded" : "Empty"); + DBG("Firmware Versions: USB='%s' FPGA='%s' EEPROM='%s'\n", + astribank->fw_versions.usb, + astribank->fw_versions.fpga, + astribank->fw_versions.eeprom); + free_command(reply); + return ret; +} + +int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EEPROM_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, EEPROM_SET, data), et, sizeof(*et)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_renumerate(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_RENUM, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +int mpp_caps_get(struct astribank_device *astribank, + struct eeprom_table *eeprom_table, + struct capabilities *capabilities, + struct capkey *key) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_CAPS_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_CAPS_GET_REPLY); + if(eeprom_table) { + memcpy(eeprom_table, (void *)&CMD_FIELD(reply, MPP, CAPS_GET_REPLY, data), sizeof(*eeprom_table)); + } + if(capabilities) { + const struct capabilities *cap = &CMD_FIELD(reply, MPP, CAPS_GET_REPLY, capabilities); + + memcpy(capabilities, cap, sizeof(*capabilities)); + } + if(key) { + const struct capkey *k = &CMD_FIELD(reply, MPP, CAPS_GET_REPLY, key); + + memcpy(key, k, sizeof(*key)); + } + free_command(reply); + return 0; +} + +int mpp_caps_set(struct astribank_device *astribank, + const struct eeprom_table *eeprom_table, + const struct capabilities *capabilities, + const struct capkey *key) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_CAPS_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, data), eeprom_table, sizeof(*eeprom_table)); + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, capabilities), capabilities, sizeof(*capabilities)); + memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, key), key, sizeof(*key)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY); + if(info) { + int i; + + memcpy(info, (void *)&CMD_FIELD(reply, MPP, EXTRAINFO_GET_REPLY, info), sizeof(*info)); + /* + * clean non-printing characters + */ + for (i = sizeof(*info) - 1; i >= 0; i--) { + if (info->text[i] != (char)0xFF) + break; + info->text[i] = '\0'; + } + } + free_command(reply); + return 0; +} + +int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + memcpy(&CMD_FIELD(cmd, MPP, EXTRAINFO_SET, info), info, sizeof(*info)); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + int size; + + DBG("len = %d, offset = %d\n", len, offset); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_EEPROM_BLK_RD, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, len) = len; + CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, offset) = offset; + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + size = ret; + goto out; + } + size = reply->header.len - sizeof(struct mpp_header) - sizeof(XTALK_STRUCT(MPP, EEPROM_BLK_RD_REPLY)); + INFO("size=%d offset=0x%X\n", size, CMD_FIELD(reply, MPP, EEPROM_BLK_RD_REPLY, offset)); + dump_packet(LOG_DEBUG, DBG_MASK, "BLK_RD", (char *)reply, ret); + if(size > len) { + ERR("Truncating reply (was %d, now %d)\n", size, len); + size = len; + } + memcpy(buf, CMD_FIELD(reply, MPP, EEPROM_BLK_RD_REPLY, data), size); +out: + free_command(reply); + return size; +} + +int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply = NULL; + struct xtalk_device *xtalk_dev; + int ret = 0; + + DBG("dest = %s ihex_version = '%s'\n", dev_dest2str(dest), ihex_version); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_START, 0)) == NULL) { + ERR("new_command failed\n"); + ret = -ENOMEM; + goto out; + } + CMD_FIELD(cmd, MPP, DEV_SEND_START, dest) = dest; + set_ihex_version(CMD_FIELD(cmd, MPP, DEV_SEND_START, ihex_version), ihex_version); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } +out: + if(reply) + free_command(reply); + astribank->burn_state = (ret == 0) + ? BURN_STATE_STARTED + : BURN_STATE_FAILED; + return ret; +} + +int mpp_send_end(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply = NULL; + struct xtalk_device *xtalk_dev; + int ret = 0; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_END, 0)) == NULL) { + ERR("new_command failed\n"); + ret = -ENOMEM; + goto out; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } +out: + if(reply) + free_command(reply); + astribank->burn_state = (ret == 0) + ? BURN_STATE_ENDED + : BURN_STATE_FAILED; + return ret; +} + +int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if(!astribank->burn_state == BURN_STATE_STARTED) { + ERR("Tried to send a segment while burn_state=%d\n", + astribank->burn_state); + return -EINVAL; + } + DBG("len = %d, offset = %d (0x%02X, 0x%02X)\n", len, offset, *data, *(data + 1)); + if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_SEG, len)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, DEV_SEND_SEG, offset) = offset; + memcpy(CMD_FIELD(cmd, MPP, DEV_SEND_SEG, data), data, len); +#if 0 + { + FILE *fp; + if((fp = fopen("seg_data.bin", "a")) == NULL) { + perror("seg_data.bin"); + exit(1); + } + if(fwrite(CMD_FIELD(cmd, MPP, DEV_SEND_SEG, data), len, 1, fp) != 1) { + perror("fwrite"); + exit(1); + } + fclose(fp); + } +#endif + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_reset(struct astribank_device *astribank, int full_reset) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + int op = (full_reset) ? MPP_RESET: MPP_HALF_RESET; + + DBG("full = %s\n", (full_reset) ? "YES" : "NO"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, op, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + uint8_t *data; + + DBG("len=%d\n", len); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_SER_SEND, len)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + data = CMD_FIELD(cmd, MPP, SER_SEND, data); + memcpy(data, in, len); + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + assert(reply->header.op == MPP_SER_RECV); + data = CMD_FIELD(reply, MPP, SER_RECV, data); + memcpy(out, data, len); + free_command(reply); + return 0; +} + +int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status) +{ + /* + * Serial commands must have equal send/receive size + */ + struct card_info_command { + uint8_t ser_op; + uint8_t addr; + uint8_t card_full_type; /* (type << 4 | subtype) */ + uint8_t card_status; /* BIT(0) - PIC burned */ + } PACKED; + struct card_info_command ci_send; + struct card_info_command ci_recv; + int ret; + + memset(&ci_send, 0, sizeof(ci_send)); + memset(&ci_recv, 0, sizeof(ci_recv)); + ci_send.ser_op = SER_CARD_INFO_GET; + ci_send.addr = (unit << 4); /* low nibble is subunit */ + ret = mpp_serial_cmd(astribank, + (uint8_t *)&ci_send, + (uint8_t *)&ci_recv, + sizeof(struct card_info_command)); + if (ret < 0) + return ret; + *card_type = ci_recv.card_full_type; + *card_status = ci_recv.card_status; + return 0; +} + +int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *fpga_configuration, uint8_t *status) +{ + /* + * Serial commands must have equal send/receive size + */ + struct fpga_stat_command { + uint8_t ser_op; + uint8_t fpga_configuration; + uint8_t status; /* BIT(0) - Watchdog timer status */ + } PACKED; + struct fpga_stat_command fs_send; + struct fpga_stat_command fs_recv; + int ret; + + memset(&fs_send, 0, sizeof(fs_send)); + memset(&fs_recv, 0, sizeof(fs_recv)); + fs_send.ser_op = SER_STAT_GET; + ret = mpp_serial_cmd(astribank, + (uint8_t *)&fs_send, + (uint8_t *)&fs_recv, + sizeof(struct fpga_stat_command)); + if(ret < 0) + return ret; + *fpga_configuration = fs_recv.fpga_configuration; + *status = fs_recv.status; + return 0; +} + +int mpp_tws_watchdog(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_WD_MODE_GET_REPLY, wd_active); + DBG("wd_active=0x%X\n", ret); + free_command(reply); + return ret == 1; +} + +int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("%s\n", (yes) ? "YES" : "NO"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, TWS_WD_MODE_SET, wd_active) = (yes) ? 1 : 0; + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + free_command(reply); + return 0; +} + +int mpp_tws_powerstate(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_PWR_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_PWR_GET_REPLY, power); + DBG("power=0x%X\n", ret); + free_command(reply); + return ret; +} + +int mpp_tws_portnum(struct astribank_device *astribank) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_GET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + ret = process_command(xtalk_dev, cmd, &reply); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + ret = CMD_FIELD(reply, MPP, TWS_PORT_GET_REPLY, portnum); + DBG("portnum=0x%X\n", ret); + free_command(reply); + return ret; +} + +int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum) +{ + struct xtalk_command *cmd; + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(astribank != NULL); + xtalk_dev = astribank->xtalk_dev; + if(portnum >= 2) { + ERR("Invalid portnum (%d)\n", portnum); + return -EINVAL; + } + if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_SET, 0)) == NULL) { + ERR("new_command failed\n"); + return -ENOMEM; + } + CMD_FIELD(cmd, MPP, TWS_PORT_SET, portnum) = portnum; + ret = process_command(xtalk_dev, cmd, NULL); + if(ret < 0) { + ERR("process_command failed: %d\n", ret); + return ret; + } + return 0; +} + +/* Adapters for xusb ops */ +static inline int xusb_close_func(void *priv) +{ + return xusb_close((struct xusb *)priv); +} + +static inline int xusb_send_func(void *priv, void *data, size_t len, int timeout) +{ + return xusb_send((struct xusb *)priv, data, len, timeout); +} + +static inline int xusb_recv_func(void *priv, void *data, size_t maxlen, int timeout) +{ + return xusb_recv((struct xusb *)priv, data, maxlen, timeout); +} + + +static struct xtalk_ops xusb_ops = { + .send_func = xusb_send_func, + .recv_func = xusb_recv_func, + .close_func = xusb_close_func, +}; + +/* + * Wrappers + */ + +struct astribank_device *mpp_init(const char devpath[], int iface_num) +{ + struct astribank_device *astribank = NULL; + struct xtalk_device *xtalk_dev = NULL; + struct xusb *xusb = NULL; + int packet_size; + int ret; + + DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); + if((astribank = astribank_open(devpath, iface_num)) == NULL) { + ERR("Opening astribank failed\n"); + goto err; + } + xusb = astribank->xusb; + packet_size = xusb_packet_size(xusb); + if((xtalk_dev = xtalk_new(&xusb_ops, packet_size, xusb)) == NULL) { + ERR("Allocating new XTALK device failed\n"); + goto err; + } + astribank->xtalk_dev = xtalk_dev; + ret = xtalk_set_protocol(xtalk_dev, &astribank_proto); + if(ret < 0) { + ERR("MPP Protocol registration failed: %d\n", ret); + goto err; + } + ret = xtalk_proto_query(xtalk_dev); + if(ret < 0) { + ERR("Protocol handshake failed: %d\n", ret); + goto err; + } + ret = mpp_status_query(astribank); + if(ret < 0) { + ERR("Status query failed: %d\n", ret); + goto err; + } + return astribank; + +err: + if (astribank) { + astribank_close(astribank, 0); + astribank = NULL; + } + if(xtalk_dev) { + xtalk_delete(xtalk_dev); + xtalk_dev = NULL; + } + return NULL; +} + +void mpp_exit(struct astribank_device *astribank) +{ + DBG("\n"); + astribank_close(astribank, 0); +} + +/* + * data structures + */ + +void show_eeprom(const struct eeprom_table *eprm, FILE *fp) +{ + int rmajor = (eprm->release >> 8) & 0xFF; + int rminor = eprm->release & 0xFF;; + char buf[BUFSIZ]; + + memset(buf, 0, LABEL_SIZE + 1); + memcpy(buf, eprm->label, LABEL_SIZE); + fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Source", eprm->source); + fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Vendor", eprm->vendor); + fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Product", eprm->product); + fprintf(fp, "EEPROM: %-15s: %d.%d\n", "Release", rmajor, rminor); + fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Config", eprm->config_byte); + fprintf(fp, "EEPROM: %-15s: '%s'\n", "Label", buf); +} + +void show_capabilities(const struct capabilities *capabilities, FILE *fp) +{ + fprintf(fp, "Capabilities: FXS ports: %2d\n", capabilities->ports_fxs); + fprintf(fp, "Capabilities: FXO ports: %2d\n", capabilities->ports_fxo); + fprintf(fp, "Capabilities: BRI ports: %2d\n", capabilities->ports_bri); + fprintf(fp, "Capabilities: PRI ports: %2d\n", capabilities->ports_pri); + fprintf(fp, "Capabilities: ECHO ports: %2d\n", capabilities->ports_echo); + fprintf(fp, "Capabilities: TwinStar : %s\n", + (CAP_EXTRA_TWINSTAR(capabilities)) ? "Yes" : "No"); +} + +void show_astribank_status(struct astribank_device *astribank, FILE *fp) +{ + char version_buf[BUFSIZ]; + int is_loaded = STATUS_FPGA_LOADED(astribank->status); + + fprintf(fp, "Astribank: EEPROM : %s\n", + eeprom_type2str(astribank->eeprom_type)); + fprintf(fp, "Astribank: FPGA status : %s\n", + is_loaded ? "Loaded" : "Empty"); + if(is_loaded) { + memset(version_buf, 0, sizeof(version_buf)); + memcpy(version_buf, astribank->fw_versions.fpga, VERSION_LEN); + fprintf(fp, "Astribank: FPGA version: %s\n", + version_buf); + } +} + +void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp) +{ + char buf[EXTRAINFO_SIZE + 1]; + + memcpy(buf, extrainfo->text, EXTRAINFO_SIZE); + buf[EXTRAINFO_SIZE] = '\0'; /* assure null termination */ + fprintf(fp, "Extrainfo: : '%s'\n", buf); +} + +int twinstar_show(struct astribank_device *astribank, FILE *fp) +{ + int watchdog; + int powerstate; + int portnum; + int i; + + if(!astribank_has_twinstar(astribank)) { + fprintf(fp, "TwinStar: NO\n"); + return 0; + } + if((watchdog = mpp_tws_watchdog(astribank)) < 0) { + ERR("Failed getting TwinStar information\n"); + return watchdog; + } + if((powerstate = mpp_tws_powerstate(astribank)) < 0) { + ERR("Failed getting TwinStar powerstate\n"); + return powerstate; + } + if((portnum = mpp_tws_portnum(astribank)) < 0) { + ERR("Failed getting TwinStar portnum\n"); + return portnum; + } + fprintf(fp, "TwinStar: Connected to : USB-%1d\n", portnum); + fprintf(fp, "TwinStar: Watchdog : %s\n", + (watchdog) ? "on-guard" : "off-guard"); + for(i = 0; i < 2; i++) { + int pw = (1 << i) & powerstate; + + fprintf(fp, "TwinStar: USB-%1d POWER : %s\n", + i, (pw) ? "ON" : "OFF"); + } + return 0; +} diff --git a/xpp/mpptalk.h b/xpp/mpptalk.h new file mode 100644 index 0000000..49db037 --- /dev/null +++ b/xpp/mpptalk.h @@ -0,0 +1,85 @@ +#ifndef MPP_FUNCS_H +#define MPP_FUNCS_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include + +#include "mpp.h" +#include "astribank_usb.h" + +struct astribank_device; +struct eeprom_table; +struct extrainfo; +struct capabilities; +struct capkey; + +#define TIMEOUT 6000 + +/* high-level */ +struct astribank_device *mpp_init(const char devpath[], int iface_num); +void mpp_exit(struct astribank_device *astribank); +int mpp_proto_query(struct astribank_device *astribank); +int mpp_status_query(struct astribank_device *astribank); +int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et); +int mpp_renumerate(struct astribank_device *astribank); +int mpp_caps_get(struct astribank_device *astribank, + struct eeprom_table *et, + struct capabilities *cap, + struct capkey *key); +int mpp_caps_set(struct astribank_device *astribank, + const struct eeprom_table *eeprom_table, + const struct capabilities *capabilities, + const struct capkey *key); +int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info); +int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info); +int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len); +int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version); +int mpp_send_end(struct astribank_device *astribank); +int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len); +int mpp_reset(struct astribank_device *astribank, int full_reset); +int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len); +void show_eeprom(const struct eeprom_table *eprm, FILE *fp); +void show_capabilities(const struct capabilities *capabilities, FILE *fp); +void show_astribank_status(struct astribank_device *astribank, FILE *fp); +void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp); +int twinstar_show(struct astribank_device *astribank, FILE *fp); + +/* + * Serial commands to FPGA + */ +int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status); +int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *maincard_version, uint8_t *status); + +/* + * Twinstar + */ +int mpp_tws_watchdog(struct astribank_device *astribank); +int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes); +int mpp_tws_powerstate(struct astribank_device *astribank); +int mpp_tws_portnum(struct astribank_device *astribank); +int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum); + +const char *dev_dest2str(int dest); + +#endif /* MPP_FUNCS_H */ diff --git a/xpp/mpptalk_defs.h b/xpp/mpptalk_defs.h new file mode 100644 index 0000000..bc0b83b --- /dev/null +++ b/xpp/mpptalk_defs.h @@ -0,0 +1,113 @@ +#ifndef MPPTALK_DEFS_H +#define MPPTALK_DEFS_H +/* + * Written by Oron Peled + * Copyright (C) 2008,2009,2010 Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +/* + * MPP - Managment Processor Protocol definitions + */ + +/* + * OP Codes: + * MSB of op signifies a reply from device + */ +#define MPP_RENUM 0x0B /* Trigger USB renumeration */ +#define MPP_EEPROM_SET 0x0D + +/* AB capabilities */ +#define MPP_CAPS_GET 0x0E +#define MPP_CAPS_GET_REPLY 0x8E +#define MPP_CAPS_SET 0x0F + +#define MPP_DEV_SEND_START 0x05 +#define MPP_DEV_SEND_SEG 0x07 +#define MPP_DEV_SEND_END 0x09 + +/* Astribank Status */ +#define MPP_STATUS_GET 0x11 +#define MPP_STATUS_GET_REPLY 0x91 +#define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */ + +/* Get extra vendor information */ +#define MPP_EXTRAINFO_GET 0x13 +#define MPP_EXTRAINFO_GET_REPLY 0x93 +#define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */ + +#define MPP_EEPROM_BLK_RD 0x27 +#define MPP_EEPROM_BLK_RD_REPLY 0xA7 + +#define MPP_SER_SEND 0x37 +#define MPP_SER_RECV 0xB7 + +#define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */ +#define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */ + +/* Twinstar */ +#define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */ +#define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */ +#define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */ +#define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */ +#define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */ +#define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */ + +/* + * Statuses + */ +#define STAT_OK 0x00 /* acknowledges previous command */ +#define STAT_FAIL 0x01 /* Last command failed */ +#define STAT_RESET_FAIL 0x02 /* reset failed */ +#define STAT_NODEST 0x03 /* No destination is selected */ +#define STAT_MISMATCH 0x04 /* Data mismatch */ +#define STAT_NOACCESS 0x05 /* No access */ +#define STAT_BAD_CMD 0x06 /* Bad command */ +#define STAT_TOO_SHORT 0x07 /* Packet is too short */ +#define STAT_ERROFFS 0x08 /* Offset error */ +#define STAT_NOCODE 0x09 /* Source was not burned before */ +#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ +#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ +#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ +#define STAT_FPGA_ERR 0x0D /* FPGA error */ +#define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */ +#define STAT_NOCAPS_ERR 0x0F /* No matching capability */ +#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ +#define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */ + +/* EEPROM_QUERY: i2cs(ID1, ID0) */ +enum eeprom_type { + EEPROM_TYPE_NONE = 0, + EEPROM_TYPE_SMALL = 1, + EEPROM_TYPE_LARGE = 2, + EEPROM_TYPE_UNUSED = 3, +}; + +enum dev_dest { + DEST_NONE = 0x00, + DEST_FPGA = 0x01, + DEST_EEPROM = 0x02, +}; + +#define EXTRAINFO_SIZE 24 + +#endif /* MPPTALK_DEFS_H */ diff --git a/xpp/oct612x/Makefile b/xpp/oct612x/Makefile new file mode 100644 index 0000000..e3e32e5 --- /dev/null +++ b/xpp/oct612x/Makefile @@ -0,0 +1,38 @@ +CFLAGS=-V3.4 -ffunction-sections -I/lib/modules/$(shell uname -r)/build/include -Iinclude -Ioctdeviceapi -Ioctdeviceapi/oct6100api -DGFP_ATOMIC=0 -Dkmalloc=calloc -Dkfree=free +LDFLAGS=-V3.4 -Wl,-Map -Wl,test.map -Wl,--gc-sections + +APIDIR=octdeviceapi/oct6100api/oct6100_api + +OCTASIC_OBJS=$(APIDIR)/oct6100_adpcm_chan.o \ + $(APIDIR)/oct6100_channel.o \ + $(APIDIR)/oct6100_chip_open.o \ + $(APIDIR)/oct6100_chip_stats.o \ + $(APIDIR)/oct6100_conf_bridge.o \ + $(APIDIR)/oct6100_debug.o \ + $(APIDIR)/oct6100_events.o \ + $(APIDIR)/oct6100_interrupts.o \ + $(APIDIR)/oct6100_memory.o \ + $(APIDIR)/oct6100_miscellaneous.o \ + $(APIDIR)/oct6100_mixer.o \ + $(APIDIR)/oct6100_phasing_tsst.o \ + $(APIDIR)/oct6100_playout_buf.o \ + $(APIDIR)/oct6100_remote_debug.o \ + $(APIDIR)/oct6100_tlv.o \ + $(APIDIR)/oct6100_tone_detection.o \ + $(APIDIR)/oct6100_tsi_cnct.o \ + $(APIDIR)/oct6100_tsst.o \ + $(APIDIR)/oct6100_user.o \ + apilib/bt/octapi_bt0.o \ + apilib/largmath/octapi_largmath.o \ + apilib/llman/octapi_llman.o + + +all: test + +test.o: test.c + +test: test.o $(OCTASIC_OBJS) + +clean: + rm -rf test test.o + rm -rf $(OCTASIC_OBJS) diff --git a/xpp/oct612x/apilib/bt/octapi_bt0.c b/xpp/oct612x/apilib/bt/octapi_bt0.c new file mode 100644 index 0000000..f9af44a --- /dev/null +++ b/xpp/oct612x/apilib/bt/octapi_bt0.c @@ -0,0 +1,1217 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_bt0.h" +#include "octapi_bt0_private.h" + + + +#if !SKIP_OctApiBt0GetSize +UINT32 OctApiBt0GetSize(UINT32 number_of_items,UINT32 key_size, UINT32 data_size, UINT32 * b_size) +{ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + *b_size = 0; + *b_size += sizeof(OCTAPI_BT0); + *b_size += sizeof(OCTAPI_BT0_NODE) * number_of_items; + *b_size += key_size * number_of_items; + *b_size += data_size * number_of_items; + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0Init +UINT32 OctApiBt0Init(void ** b,UINT32 number_of_items,UINT32 key_size, UINT32 data_size) +{ + UINT32 i; + OCTAPI_BT0 * bb; + + /* Check input parameters.*/ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + /* If b is not already allocated.*/ + if (*b == NULL) return(OCTAPI_BT0_MALLOC_FAILED); + + bb = (OCTAPI_BT0 *)(*b); + + /* Initialize the tree to an empty one!*/ + bb->root_link.node_number = 0xFFFFFFFF; + bb->root_link.depth = 0; + + /* Initialize tree parameters.*/ + bb->number_of_items = number_of_items; + bb->key_size = key_size / 4; + bb->data_size = data_size / 4; + + /* Initialize the next free node pointer.*/ + if (number_of_items != 0) + bb->next_free_node = 0; + else + bb->next_free_node = 0xFFFFFFFF; + + /* Setup the arrays.*/ + OctApiBt0CorrectPointers(bb); + + /* Initialize the Nodes to unused!*/ + for(i=0;inode[i].next_free_node = i + 1; + } + + /* Last empty node points to invalid node.*/ + bb->node[number_of_items-1].next_free_node = 0xFFFFFFFF; + + bb->invalid_value = 0xFFFFFFFF; + bb->no_smaller_key = OCTAPI_BT0_NO_SMALLER_KEY; + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0CorrectPointers +void OctApiBt0CorrectPointers(OCTAPI_BT0 * bb) +{ + bb->node = (OCTAPI_BT0_NODE *)(((BYTE *)bb) + sizeof(OCTAPI_BT0)); + bb->key = (UINT32 *)(((BYTE *)bb->node) + (sizeof(OCTAPI_BT0_NODE) * bb->number_of_items)); + bb->data = (UINT32 *)(((BYTE *)bb->key) + (sizeof(UINT32) * bb->number_of_items * bb->key_size)); +} +#endif + + +#if !SKIP_OctApiBt0AddNode +UINT32 OctApiBt0AddNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode2(bb,&(bb->root_link), lkey, new_node_number); + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0AddNode2 +UINT32 OctApiBt0AddNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[0].depth = 0; + bb->node[new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[0]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[1]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + + +#if !SKIP_OctApiBt0AddNode3 +UINT32 OctApiBt0AddNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + if ( *p_new_node_number == 0xFFFFFFFF ) + return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[0]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[1]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +/* state +0 -> first call to the function. +1 -> recursive call.*/ +#if !SKIP_OctApiBt0AddNode4 +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + if ( state == 0 ) + *p_prev_node_number = 0xFFFFFFFF; + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + if ( state == 0 ) + *p_prev_node_number = OCTAPI_BT0_NO_SMALLER_KEY; + + if ( *p_prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY ) + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[0]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + if ( state == 0 ) + *p_prev_node_number = link->node_number; + else + { + if ( *p_prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *p_prev_node_number = link->node_number; + else + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[1]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +#if !SKIP_OctApiBt0KeyCompare +UINT32 OctApiBt0KeyCompare(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey) +{ + UINT32 * nkey; + UINT32 i; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * link->node_number]); + + for(i=0;ikey_size;i++) + { + if (lkey[i] < nkey[i]) + return(OCTAPI_BT0_LKEY_SMALLER); + else if (lkey[i] > nkey[i]) + return(OCTAPI_BT0_LKEY_LARGER); + } + + return(OCTAPI_BT0_LKEY_EQUAL); +} +#endif + + +#if !SKIP_OctApiBt0UpdateLinkDepth +void OctApiBt0UpdateLinkDepth(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link) +{ + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (this_node->l[0].depth > this_node->l[1].depth) + link->depth = this_node->l[0].depth + 1; + else + link->depth = this_node->l[1].depth + 1; +} +#endif + +#if !SKIP_OctApiBt0Rebalance +void OctApiBt0Rebalance(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[0].depth > (bb->node[root_link->node_number].l[1].depth + 1)) /* Heavy to the left.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[0]); + + if (bb->node[heavy_link->node_number].l[1].depth > bb->node[heavy_link->node_number].l[0].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[1]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } + else if (bb->node[root_link->node_number].l[1].depth > (bb->node[root_link->node_number].l[0].depth + 1)) /* Heavy to the right.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[1]); + + if (bb->node[heavy_link->node_number].l[0].depth > bb->node[heavy_link->node_number].l[1].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[0]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } +} +#endif + +/* This function does a rotation towards the outside of the tree*/ +/* in order to keep the heavy branches towards the outside.*/ +#if !SKIP_OctApiBt0ExternalHeavy +void OctApiBt0ExternalHeavy(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[1].depth > bb->node[root_link->node_number].l[0].depth) /* Exterior of tree is towards the left.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[0]; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + else if (bb->node[root_link->node_number].l[0].depth > bb->node[root_link->node_number].l[1].depth) /* Exterior of tree is towards the right.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[1]; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode2 +UINT32 OctApiBt0RemoveNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link) +{ + UINT32 result; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode3 +UINT32 OctApiBt0RemoveNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link, UINT32 *p_prev_node_number ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0RemoveNode +UINT32 OctApiBt0RemoveNode(void * b,void * key) +{ + OCTAPI_BT0 * bb; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Attempt to remove the node. Only a "no hit" will cause an error.*/ + result = OctApiBt0RemoveNode2(bb,&(bb->root_link), lkey, NULL, 0, NULL); + if (result != GENERIC_OK) return(result); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0QueryNode2 +UINT32 OctApiBt0QueryNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 * node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[0]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[1]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else + { + /* A match!*/ + *node_number = link->node_number; + } + } + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0QueryNode +UINT32 OctApiBt0QueryNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + UINT32 node_number; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Get the node number.*/ + result = OctApiBt0QueryNode2(bb,&(bb->root_link),lkey,&node_number); + if (result != GENERIC_OK) return(result); + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0GetFirstNode +UINT32 OctApiBt0GetFirstNode(void * b,void ** key, void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * node; + UINT32 node_number; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check if there are any keys present in the tree. */ + if (bb->root_link.node_number == 0xFFFFFFFF) return OCTAPI_BT0_NO_NODES_AVAILABLE; + + node_number = bb->root_link.node_number; + node = &bb->node[node_number]; + + /* Make our way down to the left-most node. */ + while (node->l[0].node_number != 0xFFFFFFFF) + { + node_number = node->l[0].node_number; + node = &bb->node[node_number]; + } + + /* Return the address of the data to the user.*/ + if ( bb->key_size > 0 ) + *key = (void *)(&(bb->key[bb->key_size * node_number])); + + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0FindOrAddNode +UINT32 OctApiBt0FindOrAddNode(void * b,void * key,void ** data, UINT32 *fnct_result) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number = 0; + UINT32 result; + UINT32 tree_already_full = FALSE; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node != 0xFFFFFFFF) + { + + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + } + else + tree_already_full = TRUE; /* Signal that the tree was already full when the function was called.*/ + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode3(bb,&(bb->root_link), lkey, &new_node_number); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0AddNodeReportPrevNodeData +UINT32 OctApiBt0AddNodeReportPrevNodeData(void * b,void * key,void ** data, void ** prev_data, PUINT32 fnct_result ) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number; + UINT32 prev_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Set the previous node value */ + prev_node_number = 0xFFFFFFFF; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode4(bb,&(bb->root_link), lkey, &new_node_number, &prev_node_number, 0); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + if ( bb->data_size > 0 ) + { + if ( (prev_node_number != 0xFFFFFFFF) && + (prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY) && + (*fnct_result == OCTAPI0_BT0_NODE_ADDDED)) + *prev_data = ( void* )(&(bb->data[bb->data_size * prev_node_number])); + else if ( prev_node_number == 0xFFFFFFFF ) + *prev_data = ( void* )(&bb->invalid_value); + else if ( prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *prev_data = ( void* )(&bb->no_smaller_key); + } + + return(GENERIC_OK); +} +#endif + diff --git a/xpp/oct612x/apilib/bt/octapi_bt0_private.h b/xpp/oct612x/apilib/bt/octapi_bt0_private.h new file mode 100644 index 0000000..8c68c3e --- /dev/null +++ b/xpp/oct612x/apilib/bt/octapi_bt0_private.h @@ -0,0 +1,93 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_PRIVATE_H__ +#define __OCTAPI_BT0_PRIVATE_H__ + + + +#include "octdef.h" + +#define OCTAPI_BT0_LKEY_LARGER 0x0 +#define OCTAPI_BT0_LKEY_SMALLER 0x1 +#define OCTAPI_BT0_LKEY_EQUAL 0x2 + +typedef struct __OCTAPI_BT0_LINK__ +{ + UINT32 node_number; + UINT32 depth; +} OCTAPI_BT0_LINK; + +typedef struct __OCTAPI_BT0_NODE__ +{ + UINT32 next_free_node; /* Number of the next node in the free node link-list.*/ + OCTAPI_BT0_LINK l[2]; /* 0 = left link; 1 = right link.*/ +} OCTAPI_BT0_NODE; + + +typedef struct __OCTAPI_BT0__ +{ + UINT32 number_of_items; /* Number of items on total that can be allocated in the tree.*/ + UINT32 key_size; /* Size is in UINT32s*/ + UINT32 data_size; /* Size is in UINT32s*/ + + /* Empty node linked-list:*/ + UINT32 next_free_node; /* 0xFFFFFFFF means that no nodes are free.*/ + + /* Tree as such:*/ + OCTAPI_BT0_NODE * node; /* Array of nodes (number_of_items in size).*/ + + /* Tree root:*/ + OCTAPI_BT0_LINK root_link; + + /* Associated key structure*/ + UINT32 * key; /* Array of keys associated to NODEs.*/ + + /* Associated data structure.*/ + UINT32 * data; /* Array of data associated to NODEs.*/ + + UINT32 invalid_value; + UINT32 no_smaller_key; + +} OCTAPI_BT0; + +void OctApiBt0CorrectPointers( OCTAPI_BT0 * bb ); +UINT32 OctApiBt0AddNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 new_node_number ); +UINT32 OctApiBt0AddNode3( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 *p_new_node_number ); +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ); +UINT32 OctApiBt0KeyCompare( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey ); +void OctApiBt0UpdateLinkDepth( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link ); +void OctApiBt0Rebalance( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +void OctApiBt0ExternalHeavy( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +UINT32 OctApiBt0RemoveNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link ); + + + +#endif /*__OCTAPI_BT0_PRIVATE_H__*/ diff --git a/xpp/oct612x/apilib/largmath/octapi_largmath.c b/xpp/oct612x/apilib/largmath/octapi_largmath.c new file mode 100644 index 0000000..75153b8 --- /dev/null +++ b/xpp/oct612x/apilib/largmath/octapi_largmath.c @@ -0,0 +1,628 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmAdd. +| +| Description: This function adds 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The +| result is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmAdd +UINT32 OctApiLmAdd(UINT32 * a,USHORT alen,UINT32 * b,USHORT blen,UINT32 * z, USHORT zlen) +{ + USHORT i; + UINT32 temp; + UINT32 carry=0; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = *(b+i); else bprim = 0; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow.*/ + if (carry == 1) return(OCTAPI_LM_OVERFLOW); + + /* All is well.*/ + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function subtracts 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *bneg UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| *neg USHORT Indicates if the result is negative +| (TRUE/FALSE). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmSubtract +UINT32 OctApiLmSubtract(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,UINT32 * z,USHORT zlen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + /* Number is not of right neg. Invert and add one to correct neg.*/ + for(i=0;i<=zlen;i++) + *(z+i) = ~(*(z+i)); + + temp = 1; + OctApiLmAdd(&temp,0,z,zlen,z,zlen); + + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmCompare. +| +| Description: This function compares two numbers (arrays) of equal lengths. +| Number a is (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *neg USHORT Result of compare. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmCompare +UINT32 OctApiLmCompare(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + UINT32 zlen; + + /* Set zlen to alen or blen (which ever is longer)*/ + if (alen < blen) + zlen = blen; + else + zlen = alen; + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function multiplies 2 numbers, a and b. Number a and +| b are both (ablen + 1) * 32 bits long. The result is twice as +| long. If the functions succeeds if returns GENERIC_OK, +| else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmMultiply +UINT32 OctApiLmMultiply(UINT32 * a,UINT32 * b,USHORT ablen,UINT32 * z) +{ + USHORT i,j,k; + USHORT nos; + UINT32 lownum; + UINT32 highnum; + USHORT longnumi; + USHORT longnumj; + USHORT indentw,indentl; + + + /* Caculate number of shorts in a and b.*/ + nos = (USHORT)((ablen+1) * 2); + + /* Clear answer word.*/ + for(i=0;i OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizea = FALSE; + if(*b > OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizeb = FALSE; + + if(optimizea == TRUE) + { + for(l = 0; l < *a; l++) + OctApiLmAdd(z, (USHORT)(nos-1), b, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + + if(optimizeb == TRUE) + { + for(l = 0; l < *b; l++) + OctApiLmAdd(z, (USHORT)(nos-1), a, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + } + + for(i=0;i>16; /* Odd word. Upper part of long.*/ + + for(j=0;j>16; /* Odd word. Upper part of long.*/ + + /* Find the word indent of the answer. 0 = no indent. 1 = one word indent.*/ + indentw = (USHORT)( j+i ); + indentl = (USHORT)( indentw / 2 ); + + /* Multiply both numbers.*/ + product = highnum * lownum; + + /* After multiplying both numbers, add result to end result.*/ + if ((indentw % 2) == 0) /* Even word boundary, addition in one shot!*/ + { + UINT32 carry=0; + UINT32 temp; + UINT32 addme; + + for(k=indentl;k>16; + else addme = 0; + + temp = *(z+k) + addme + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < addme) carry = 1; else carry = 0; + else + if (temp <= addme) carry = 1; else carry = 0; + + /* Set value.*/ + *(z+k) = temp; + } + + /* Carry should always be 0.*/ + if (carry == 1) return(GENERIC_ERROR); + } + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmDivide. +| +| Description: This function divides the number n by the number d. The +| quotient is placed in q and the remainder in r. The arrays +| n, d, q and r are all of the same length, namely (ndqrlen + 1). +| If the functions succeeds if returns GENERIC_OK, else +| GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmDivide +UINT32 OctApiLmDivide(UINT32 * n,UINT32 * d,UINT32 * q,UINT32 * r,USHORT ndqrlen) +{ + /* Proceedure for division:*/ + /* r = n*/ + /* q = 0*/ + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + /* d <<= shift;*/ + /* Start loop:*/ + /* compare r and d*/ + /* if r > d then*/ + /* r -= d;*/ + /* write a '1' to bit "shift" of array q.*/ + /* end if;*/ + /* if shift == 0 then*/ + /* return;*/ + /* else*/ + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + /* end if;*/ + + UINT32 i; + UINT32 result; + USHORT shift,n_msb,d_msb; + USHORT neg; + USHORT ConditionFlag = TRUE; + + /* r = n*/ + for(i=0;i<=ndqrlen;i++) + *(r+i) = *(n+i); + + /* q = 0*/ + for(i=0;i<=ndqrlen;i++) + *(q+i) = 0; + + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + result = OctApiLmGetMsb(d,ndqrlen,&d_msb); + if (result != GENERIC_OK) return(result); + + result = OctApiLmGetMsb(n,ndqrlen,&n_msb); + if (result != GENERIC_OK) return(result); + + if (d_msb == 0xFFFF) /* Division by 0.*/ + return(OCTAPI_LM_DIVISION_BY_ZERO); + + if (n_msb == 0xFFFF) /* 0/n, returns 0 R 0.*/ + return(GENERIC_OK); + + if (n_msb < d_msb) /* x/y, where x is smaller than y, returns 0 R x.*/ + return(GENERIC_OK); + + shift = (USHORT)( n_msb - d_msb ); + + /* Shift d to match n highest bit position.*/ + result = OctApiLmShiftn(d,ndqrlen,TRUE,shift); + if (result != GENERIC_OK) return(result); + + /* Start loop:*/ + while( ConditionFlag == TRUE ) + { + /* compare r and d*/ + result = OctApiLmCompare(r,ndqrlen,d,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + if (neg == FALSE) /* Subtraction can be done(do it).*/ + { + /* r -= d;*/ + result = OctApiLmSubtract(r,ndqrlen,d,ndqrlen,r,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + /* write a '1' to bit "shift" of array q.*/ + *(q+(shift/32)) |= (UINT32)0x1 << (shift%32); + } + + /* if shift == 0 then*/ + /* return;*/ + if (shift == 0) return(GENERIC_OK); + + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + shift--; + OctApiLmShiftRight1(d,ndqrlen); + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: octapi_lm_shifright1. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftRight1 +UINT32 OctApiLmShiftRight1(UINT32 * a,USHORT alen) +{ + UINT32 i; + + /* Start with lower long and move up by one long each time,*/ + /* shifting each long to the right by one bit. The upper bit*/ + /* of the next long will have to be concatenated each time a*/ + /* loop is executed. For the last long, leave the highest bit*/ + /* intact.*/ + for(i=0;i>=1; /* Shift long by one to the right.*/ + *(a+i)|=*(a+i+1)<<31; + } + *(a+alen)>>=1; /* Shift last long, leaving it's highest bit at 0.*/ + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmShiftn. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftn +UINT32 OctApiLmShiftn(UINT32 * a,USHORT alen,USHORT shiftleft,USHORT shiftn) +{ + UINT32 i; + USHORT long_offset; + USHORT bit_offset; + + long_offset = (USHORT)( shiftn / 32 ); + bit_offset = (USHORT)( shiftn % 32 ); + + if (shiftleft == TRUE) /* Shift left.*/ + { + for(i=alen;i<=alen;i--) + { + /* Fill upper bits of long.*/ + if (i >= long_offset) + *(a+i) = *(a+i-long_offset) << bit_offset; + else + *(a+i) = 0; + + /* Fill lower bits of long.*/ + if (i > long_offset && bit_offset != 0) + *(a+i) |= *(a+i-long_offset-1) >> (32-bit_offset); + } + } + else /* Shift right.*/ + { + for(i=0;i<=alen;i++) + { + /* Fill lower bits of long.*/ + if ((alen-i) >= long_offset) + *(a+i) = *(a+i+long_offset) >> bit_offset; + else + *(a+i) = 0; + + /* Fill upper bits of long.*/ + if ((alen-i) > long_offset && bit_offset != 0) + *(a+i) |= *(a+i+long_offset+1) << (32-bit_offset); + + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmGetMsb. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmGetMsb +UINT32 OctApiLmGetMsb(UINT32 * a,USHORT alen,USHORT * msb_pos) +{ + UINT32 i,j; + UINT32 x; + + for(i=alen;i<=alen;i--) + { + if (*(a+i) == 0) continue; + + x = *(a+i); + for(j=31;j<=31;j--) + { + /* Test for bit being '1'.*/ + if ((x & 0x80000000) != 0) + { + *msb_pos=(USHORT)(j+(32*i)); + return(GENERIC_OK); + } + + /* Shift bit one bit position, and try again.*/ + x<<=1; + } + } + + /* MSB not found.*/ + *msb_pos = 0xFFFF; + + return(GENERIC_OK); +} +#endif diff --git a/xpp/oct612x/apilib/llman/octapi_llman.c b/xpp/oct612x/apilib/llman/octapi_llman.c new file mode 100644 index 0000000..9926d20 --- /dev/null +++ b/xpp/oct612x/apilib/llman/octapi_llman.c @@ -0,0 +1,2787 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "octapi_llman_private.h" +#include "apilib/octapi_llman.h" +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocGetSize +UINT32 OctapiLlmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(LLM_ALLOC)) + (number_of_items * sizeof(UINT32)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInit. +| +| Description: This function intializes the LLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInit +UINT32 OctapiLlmAllocInit(void ** l,UINT32 number_of_items) +{ + LLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet:*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)(*l); + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i] = i+1; + } + + ls->linked_list[number_of_items - 1] = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the LLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInfo +UINT32 OctapiLlmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + LLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocAlloc +UINT32 OctapiLlmAllocAlloc(void * l,UINT32 * blocknum) +{ + LLM_ALLOC* ls; + UINT32 allocated_block; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = *node; + + /* Tag as used the current block number.*/ + *node = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocDealloc +UINT32 OctapiLlmAllocDealloc(void * l,UINT32 blocknum) +{ + LLM_ALLOC* ls; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (*node != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to list.*/ + *node = ls->next_avail_num; + + /* Point to returned block.*/ + ls->next_avail_num = blocknum; + + /* Update block usage number.*/ + ls->allocated_items--; + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| This version is a time manage version of llman. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocGetSize +UINT32 OctApiTllmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(TLLM_ALLOC)) + (number_of_items * sizeof(TLLM_ALLOC_NODE)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInit. +| +| Description: This function intializes the TLLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInit +UINT32 OctApiTllmAllocInit(void ** l,UINT32 number_of_items) +{ + TLLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet.*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)(*l); + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i].value = i+1; + } + + ls->linked_list[number_of_items - 1].value = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + /* Set the number of timeout entry.*/ + ls->number_of_timeout = 0; + + /* Next timeout is 0.*/ + ls->next_timeout_num = 0xFFFFFFFF; + ls->last_timeout_num = 0xFFFFFFFF; + + /* Set the known time to 0.*/ + ls->last_known_time[ 0 ] = 0; + ls->last_known_time[ 1 ] = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the TLLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInfo +UINT32 OctApiTllmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + TLLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocAlloc. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| *current_time UINT32 +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocAlloc +UINT32 OctApiTllmAllocAlloc(void * l,UINT32 * blocknum, UINT32 *current_time) +{ + TLLM_ALLOC* ls; + UINT32 allocated_block; + TLLM_ALLOC_NODE* node; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + if ( ls->allocated_items == ls->number_of_items && + ls->next_timeout_num != 0xFFFFFFFF ) + { + UINT32 l_ulResult; + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = node->value; + + /* Tag as used the current block number.*/ + node->value = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocDealloc +UINT32 OctApiTllmAllocDealloc(void * l,UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2]) +{ + TLLM_ALLOC* ls; + TLLM_ALLOC_NODE* node; + UINT32 l_ulResult; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if ( ls->next_timeout_num != 0xFFFFFFFF ) + { + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (node->value != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to timeout list.*/ + if ( ls->last_timeout_num != 0xFFFFFFFF ) + { + TLLM_ALLOC_NODE* last_node; + + /* insert the node at the end of the list.*/ + node->value = 0xFFFFFFFF; + last_node = &ls->linked_list[ ls->last_timeout_num ]; + last_node->value = blocknum; + } + else + { + /* The node is alone in the list.*/ + node->value = 0xFFFFFFFF; + ls->next_timeout_num = blocknum; + } + + ls->last_timeout_num = blocknum; + ls->number_of_timeout++; + + /* Set the timeout time of the node.*/ + l_ulResult = OctApiLmAdd( current_time, 1, &timeout_value, 0, node->timeout, 1 ); + if (l_ulResult != GENERIC_OK) + return(l_ulResult); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmCheckTimeoutList. +| +| Description: This function will verify if the timeout time +| of all the node present in the timeout list are bigger +| then the current time. If so the node will be returned +| ot the free node list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *ls TLLM_ALLOC The memory used by the TLLM_ALLOC structure. +| current_time UINT32[2] The current time in msec. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmCheckTimeoutList +UINT32 OctApiTllmCheckTimeoutList(TLLM_ALLOC *ls, UINT32 current_time[2]) +{ + UINT32 result; + UINT32 fConditionFlag = TRUE; + + /* Free-up any pending memory before trying the allocation:*/ + if ((ls->last_known_time[0] != current_time[0] || + ls->last_known_time[1] != current_time[1]) && + (current_time[1] != 0 || current_time[0] != 0)) /* Time has changed.*/ + { + TLLM_ALLOC_NODE *pcurrent_node; + UINT32 current_num; + USHORT neg; + + /* Remember time for next time!*/ + ls->last_known_time[0] = current_time[0]; + ls->last_known_time[1] = current_time[1]; + + + while ( fConditionFlag == TRUE ) + { + /* Get a node from the timeout list.*/ + pcurrent_node = &ls->linked_list[ ls->next_timeout_num ]; + current_num = ls->next_timeout_num; + + /* Check if first node has timeout.*/ + result = OctApiLmCompare(current_time,1,pcurrent_node->timeout ,1,&neg); + if (result != GENERIC_OK) return(result); + + /* if the timeout tiem was exceeded, set the block as free.*/ + if ( neg == FALSE ) + { + /* set the next node pointer.*/ + ls->next_timeout_num = pcurrent_node->value; + ls->number_of_timeout--; + + /* reset the last pointer of the timeout list.*/ + if ( ls->number_of_timeout == 0 ) + ls->last_timeout_num = 0xFFFFFFFF; + + /* return the node the free list.*/ + pcurrent_node->value = ls->next_avail_num; + ls->next_avail_num = current_num; + ls->allocated_items--; + } + else /* node not in timeout */ + { + fConditionFlag = FALSE; + break; + } + + if ( ls->next_timeout_num == 0xFFFFFFFF ) + { + fConditionFlag = FALSE; + break; /* end of timeout list.*/ + } + } + } + + return(GENERIC_OK); +} +#endif +/**************************************** llm_alloc section **********************************************/ + + + + + + + +/**************************************** llm_list section **********************************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListGetSize +UINT32 OctApiLlmListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM_LIST) + (number_of_lists * sizeof(LLM_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlmListGetItemPointer +LLM_LIST_ITEM * OctApiLlmListGetItemPointer(LLM_LIST * ls, UINT32 item_number) +{ + return (LLM_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInit. +| +| Description: This function intializes the LLM_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInit +UINT32 OctApiLlmListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInfo. +| +| Description: This function returns the status of the LLM_LIST structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *allocated_lists UINT32 The number of linked_lists allocated. +| *free_lists UINT32 The number of linked_lists still free. +| *allocated_items UINT32 The number of items allocated to lists. +| *free_items UINT32 The number of items still free. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInfo +UINT32 OctApiLlmListInfo(void * l,UINT32 * allocated_lists,UINT32 * allocated_items, + UINT32 * free_lists,UINT32 * free_items) +{ + LLM_LIST* ls; + BYTE* lsbyte; + UINT32 total_lists; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + *allocated_items = ls->assigned_items; + *free_items = ls->total_items - ls->assigned_items; + + *allocated_lists = ls->assigned_lists; + *free_lists = ls->total_lists - ls->assigned_lists; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreate +UINT32 OctApiLlmListCreate(void * l,UINT32 * list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListDelete +UINT32 OctApiLlmListDelete(void * l,UINT32 list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM_LIST_ITEM * item; + + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListLength +UINT32 OctApiLlmListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListItemData +UINT32 OctApiLlmListItemData(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (list_length <= item_number) return(OCTAPI_LLM_ELEMENT_NOT_FOUND); + + /* Determine where the search will start.*/ + if (list_length == (item_number + 1)) /* Last item in list:*/ + { + cur_list_pnt = lh->tail_pointer; + cur_list_num = item_number; + } + else if (lh->cache_item_number <= item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + /* Write new cache entry.*/ + lh->cache_item_pointer = cur_list_pnt; + lh->cache_item_number = cur_list_num; + + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| can be specified. A position of 0xFFFFFFFF means append to the +| list( use the OCTAPI_LLM_LIST_APPEND define for clarity); +| a position of 0 mean insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInsertItem +UINT32 OctApiLlmListInsertItem(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length < item_number && item_number != 0xFFFFFFFF) + return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + ls->next_empty_item = free_item->forward_link; + + if (item_number == 0xFFFFFFFF) + item_number = lh->list_length; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + free_item->forward_link = lh->head_pointer; + lh->head_pointer = free_item_pnt; + } + else if (item_number == lh->list_length) /* Append:*/ + { + LLM_LIST_ITEM * last_item; + last_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else /* Insert:*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = item_number; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreateFull. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreateFull +UINT32 OctApiLlmListCreateFull(void* l, UINT32 list_length, UINT32* plist_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + LLM_LIST_ITEM* last_item = NULL; + UINT32 free_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_handle; + UINT32 list_length_m1; + UINT32 next_empty_item; + UINT32 result; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure another list can be created.*/ + if (ls->assigned_lists == ls->total_lists) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + + /* Make sure there are enough free nodes to fill the new list.*/ + if (list_length > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Create list (i.e. get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &list_handle); + if (result != GENERIC_OK) return(result); + + /* Initialize the list head structure.*/ + lh = &ls->lh[list_handle]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + lh = &ls->lh[list_handle]; + list_length_m1 = list_length - 1; + next_empty_item = ls->next_empty_item; + + for (i=0; ili + ls->item_size * free_item_pnt); + next_empty_item = free_item->forward_link; + + /* Branch according to whether the node is the first in list, last, or in + the middle.*/ + if (i == 0) + { + /* First item.*/ + free_item->forward_link = 0xFFFFFFFF; + lh->head_pointer = free_item_pnt; + lh->tail_pointer = free_item_pnt; + } + else if (i == list_length_m1) + { + /* Last item.*/ + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else + { + /* Node somewhere in the middle.*/ + last_item->forward_link = free_item_pnt; + } + + /* Store pointer to free item as pointer to last item (for next iteration).*/ + last_item = free_item; + } + + /* Store new value of next_empty_item.*/ + ls->next_empty_item = next_empty_item; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = list_length_m1; + + /* Set the list length.*/ + lh->list_length = list_length; + ls->assigned_items += list_length; + + /* Return pointer to new list.*/ + *plist_handle = list_handle; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendItems. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendItems +UINT32 OctApiLlmListAppendItems(void* l, UINT32 list_handle, UINT32 num_items) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendAndSetItems. +| +| Description: +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendAndSetItems +UINT32 OctApiLlmListAppendAndSetItems(void* l, UINT32 list_handle, UINT32 num_items, void* data_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 user_info_bytes; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + void* data_item; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + user_info_bytes = ls->user_info_bytes; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + data_item = data_list; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + + /* Copy data to new item.*/ + OctApiLlmMemCpy(curr_item->user_info, data_item, user_info_bytes); + + /* Update data_item pointer for next iteration (item).*/ + data_item = (void *)((BYTE *)data_item + user_info_bytes); + } + + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListSetItems. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the data list to the linked list, from +| entry start_entry to (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListSetItems +UINT32 OctApiLlmListSetItems(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 total_lists; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + item_pnt = lh->head_pointer; + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(item->user_info, pdata_item, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCopyData. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the linked list to the data list, from +| entry start_entry of the linked list to +| (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCopyData +UINT32 OctApiLlmListCopyData(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(pdata_item, item->user_info, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListRemoveItem +UINT32 OctApiLlmListRemoveItem(void * l,UINT32 list_handle,UINT32 item_number) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* freed_item = NULL; + LLM_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length <= item_number) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if (item_number == 0 && lh->list_length == 1)/* First item and only item:*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + freed_item_pnt = ls->lh[list_handle].head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = freed_item->forward_link; + + lh->cache_item_number = 0; + lh->cache_item_pointer = freed_item->forward_link; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + if ((item_number + 1) == lh->list_length) + { + lh->tail_pointer = last_list_pnt; + last_item->forward_link = 0xFFFFFFFF; + } + else + { + last_item->forward_link = item->forward_link; + } + freed_item_pnt = cur_list_pnt; + freed_item = item; + + /* Reset cache entry.*/ + lh->cache_item_pointer = last_list_pnt; + lh->cache_item_number = cur_list_num - 1; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/**************************************** llm2 function section *****************************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM2_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListGetSize +UINT32 OctApiLlm2ListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM2_LIST) + (number_of_lists * sizeof(LLM2_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlm2ListGetItemPointer +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer(LLM2_LIST * ls, UINT32 item_number) +{ + return (LLM2_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInit. +| +| Description: This function intializes the LLM2_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInit +UINT32 OctApiLlm2ListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListCreate +UINT32 OctApiLlm2ListCreate(void * l,UINT32 * list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListDelete +UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM2_LIST_ITEM * item; + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListLength +UINT32 OctApiLlm2ListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListItemData +UINT32 OctApiLlm2ListItemData(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, PUINT32 item_number_pnt) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + *item_number_pnt = 0; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Determine where the search will start.*/ + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + if (cur_list_key == item_key) /* Item key found.*/ + { + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + (*item_number_pnt)++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| will be defined based on the key value. All entry are inserted +| in the list in incremental Key value. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| **prev_item_data void Address of the user data space for the previous item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInsertItem +UINT32 OctApiLlm2ListInsertItem(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 ulPassCount = 0; + UINT32 fConditionFlag = TRUE; + + /* Set the status of the insertion.*/ + *insert_status_pnt = OCTAPI_LLM2_INSERT_ERROR; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM2_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + free_item->key = item_key; + ls->next_empty_item = free_item->forward_link; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + *insert_status_pnt = OCTAPI_LLM2_INSERT_FIRST_NODE; + + /* There is no previous node information to return.*/ + *prev_item_data_pnt = NULL; + *prev_prev_item_data_pnt = NULL; + } + else /* Insert:*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + /* Increment the pass count to determine if the addition will happen next to last.*/ + ulPassCount++; + + if (cur_list_key >= item_key) /* Item new node between the last and the curent. */ + { + if (last_list_pnt == 0xFFFFFFFF) /* Must insert at the head of the list.*/ + { + free_item->forward_link = cur_list_pnt; + lh->head_pointer = free_item_pnt; + } + else /* Standard insertion.*/ + { + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + } + + /* Check if the entry was made before the last one.*/ + if ( ulPassCount == lh->list_length ) + *insert_status_pnt = OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE; + else + *insert_status_pnt = OCTAPI_LLM2_INSERT_LIST_NODE; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found, must insert at the end.*/ + { + free_item->forward_link = 0xFFFFFFFF; + item->forward_link = free_item_pnt; + lh->tail_pointer = free_item_pnt; + + *insert_status_pnt = OCTAPI_LLM2_INSERT_LAST_NODE; + + fConditionFlag = FALSE; + break; + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + } + + /* Return the previous node if possible.*/ + if ( *insert_status_pnt == OCTAPI_LLM2_INSERT_LIST_NODE || + *insert_status_pnt == OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE ) + { + if ( last_item != NULL ) + *prev_item_data_pnt = (void *)last_item->user_info; + + if ( last_last_item != NULL ) + *prev_prev_item_data_pnt = (void *)last_last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + else + { + *prev_item_data_pnt = (void *)item->user_info; + + if ( ( last_last_item != NULL ) && ( last_item != NULL ) ) + *prev_prev_item_data_pnt = (void *)last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_key UINT32 The key of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListRemoveItem +UINT32 OctApiLlm2ListRemoveItem(void * l,UINT32 list_handle,UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* freed_item = NULL; + LLM2_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + UINT32 ulPassCount = 0; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + /* Set the status of the removal to error as a default value.*/ + *remove_status_pnt = OCTAPI_LLM2_REMOVE_ERROR; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + if (lh->list_length == 1)/* First item and only item if he matches.*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + if ( freed_item->key == item_key ) + { + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + } + else + return(OCTAPI_LLM2_INTERNAL_ERROR1); + + /* Indicate that there was no node prior to the one removed.*/ + *prev_item_key_pnt = 0xFFFFFFFF; + *prev_prev_item_key_pnt = 0xFFFFFFFF; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + ulPassCount++; + if (cur_list_key == item_key) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) /* First item in the list.*/ + { + lh->head_pointer = item->forward_link; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else if ( item->forward_link == 0xFFFFFFFF) /* Last item of the list.*/ + { + last_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = last_list_pnt; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LAST_NODE; + } + else + { + last_item->forward_link = item->forward_link; + + if ( ulPassCount == ( lh->list_length - 1 ) ) + *remove_status_pnt = OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE; + else + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LIST_NODE; + } + + freed_item_pnt = cur_list_pnt; + freed_item = item; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + } + + /* Return the key of the node before the node removed if possible.*/ + if ( last_list_pnt == 0xFFFFFFFF ) + *prev_item_key_pnt = 0xFFFFFFFF; + else if ( last_item != NULL ) + *prev_item_key_pnt = last_item->key; + + /* Return the key of the node before before the node removed if possible.*/ + if ( last_last_item == NULL ) + *prev_prev_item_key_pnt = 0xFFFFFFFF; + else + *prev_prev_item_key_pnt = last_last_item->key; + + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmMemCpy. +| +| Description: This function copies data from a source to a destination. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *f_pvDestination VOID The destination where to copy the data. +| *f_pvSource VOID The source where to copy the data from. +| f_ulSize UINT32 The number of bytes to copy. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmMemCpy +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ) +{ + CHAR * pbyDst; + const CHAR * pbySrc; + UINT32 * f_pulAlignedDst; + const UINT32 * f_pulAlignedSrc; + + pbyDst = (CHAR *)f_pvDestination; + pbySrc = (const CHAR *)f_pvSource; + + /* + * If the size is small, or either SRC or DST is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + if ( ( f_ulSize < sizeof(UINT32) ) + || ( ( (unsigned long)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (unsigned long)( pbyDst ) & ( sizeof(UINT32) - 1 ) ) ) ) + { + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + return f_pvDestination; + } + + f_pulAlignedDst = (UINT32 *)pbyDst; + f_pulAlignedSrc = (const UINT32 *)pbySrc; + + /* Copy 4X long words at a time if possible. */ + while ( f_ulSize >= 4 * sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= 4 * sizeof(UINT32); + } + + /* Copy one long word at a time if possible. */ + while ( f_ulSize >= sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= sizeof(UINT32); + } + + /* Pick up any residual with a byte copier. */ + pbyDst = (CHAR *)f_pulAlignedDst; + pbySrc = (const CHAR *)f_pulAlignedSrc; + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + + return f_pvDestination; +} +#endif + +/**************************************** llm_list section **********************************************/ + diff --git a/xpp/oct612x/apilib/llman/octapi_llman_private.h b/xpp/oct612x/apilib/llman/octapi_llman_private.h new file mode 100644 index 0000000..14a053d --- /dev/null +++ b/xpp/oct612x/apilib/llman/octapi_llman_private.h @@ -0,0 +1,206 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_PRIVATE_H__ +#define __OCTAPI_LLMAN_PRIVATE_H__ + +#include "octdef.h" + + +/**************************************** llm_alloc section **********************************************/ + + +/* Most basic linked list model. + LLM_STR contains a list of "number_of_items" that + are each "unassigned" or "assigned". When requesting + a new element, llm_alloc must choose an "unassigned" + element. An element that is deallocated will be last + to be allocated. +*/ + +typedef struct _LLM_ALLOC +{ + UINT32 *linked_list; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + +} LLM_ALLOC; + +typedef struct _TLLM_ALLOC_NODE_ +{ + UINT32 value; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 timeout[2]; /* Timeout value that must be exceeded for the node to be considered free again.*/ + +} TLLM_ALLOC_NODE; + + +typedef struct _TLLM_ALLOC_ +{ + TLLM_ALLOC_NODE *linked_list; /* List of nodes used by the link list.*/ + + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + + UINT32 number_of_timeout; /* Number of block currently in timeout.*/ + UINT32 next_timeout_num; /* Points to the next block currently in timeout.*/ + UINT32 last_timeout_num; /* Last node of the timeout list.*/ + + UINT32 last_known_time[2]; /* last known time.*/ + +} TLLM_ALLOC; + +/* +void octapi_llm_alloc_build_structure(void *l, LLM_ALLOC ** ls); +*/ +/**************************************** llm_alloc section **********************************************/ + + + +/**************************************** llm_list section **********************************************/ +/* This section contains memory structures and functions used + to maintain a variable number of lists (FIFOs) that each + have a variable amount of items. A total amount of items + can be assigned through-out all the lists. Each item in + each list contains a UINT32 specified by the software using + the lists. Each used item in the list is accessible through + it's position in the list. */ + +typedef struct _LLM_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + + /* Item cache (pointer within the list of the last accessed item):*/ + UINT32 cache_item_number; /* Number of the last accessed item in the list. 0xFFFFFFFF indicates invalid cache.*/ + UINT32 cache_item_pointer; /* Number of the last accessed item in the item pool.*/ +} LLM_LIST_HEAD; + +typedef struct _LLM_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM_LIST_ITEM; + +typedef struct _LLM_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM_LIST_ITEM * li; +} LLM_LIST; + + +/**********************************************************************************/ +/* These structures are are used by the Llm2 functions to creates lists of ordered + items based on a key given by the user when a new node is inserted in a list. */ +typedef struct _LLM2_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + +} LLM2_LIST_HEAD; + +typedef struct _LLM2_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 key; /* Key used to order the entries.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM2_LIST_ITEM; + +typedef struct _LLM2_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM2_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM2_LIST_ITEM * li; +} LLM2_LIST; + +/*void octapi_llm_list_build_structure(void *l, LLM_LIST ** ls);*/ +LLM_LIST_ITEM * OctApiLlmListGetItemPointer( LLM_LIST * ls, UINT32 item_number ); +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer( LLM2_LIST * ls, UINT32 item_number ); +UINT32 OctApiTllmCheckTimeoutList( TLLM_ALLOC *ls, UINT32 current_time[2] ); +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ); +/**************************************** llm_list section **********************************************/ + + + + + +#endif /*__OCTAPI_LLMAN_PRIVATE_H__*/ diff --git a/xpp/oct612x/get_discards b/xpp/oct612x/get_discards new file mode 100755 index 0000000..5436118 --- /dev/null +++ b/xpp/oct612x/get_discards @@ -0,0 +1,51 @@ +#!/usr/bin/php + + diff --git a/xpp/oct612x/include/apilib/octapi_bt0.h b/xpp/oct612x/include/apilib/octapi_bt0.h new file mode 100644 index 0000000..a0f22ca --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_bt0.h @@ -0,0 +1,75 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_H__ +#define __OCTAPI_BT0_H__ + +#include "octdef.h" + +#define OCTAPI_BT0_BASE 0xFFFF0000 +#define OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0001 +#define OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0002 +#define OCTAPI_BT0_MALLOC_FAILED OCTAPI_BT0_BASE+0x0003 +#define OCTAPI_BT0_NO_NODES_AVAILABLE OCTAPI_BT0_BASE+0x0004 +#define OCTAPI_BT0_KEY_ALREADY_IN_TREE OCTAPI_BT0_BASE+0x0005 +#define OCTAPI_BT0_KEY_NOT_IN_TREE OCTAPI_BT0_BASE+0x0006 + +/* Possible result for Find Or Add function. */ +#define OCTAPI0_BT0_NODE_FOUND 0 +#define OCTAPI0_BT0_NODE_ADDDED 1 + +#define OCTAPI_BT0_NO_SMALLER_KEY 0xAAAAAAAA + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_bt0_get_size( number_of_items, key_size, data_size, b_size ) OctApiBt0GetSize( (UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size, (PUINT32) b_size ) +#define octapi_bt0_init( b, number_of_items, key_size, data_size ) OctApiBt0Init( (void **) b,(UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size ) +#define octapi_bt0_add_node( b, key, data ) OctApiBt0AddNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_remove_node( b, key ) OctApiBt0RemoveNode( (void *) b,(void *) key ) +#define octapi_bt0_query_node( b, key, data ) OctApiBt0QueryNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_get_first_node( b, key, data ) OctApiBt0GetFirstNode( (void *) b,(void **) key, (void **) data ) + +UINT32 OctApiBt0GetSize( UINT32 number_of_items, UINT32 key_size, UINT32 data_size, UINT32 * b_size ); +UINT32 OctApiBt0Init( void ** b, UINT32 number_of_items, UINT32 key_size, UINT32 data_size ); +UINT32 OctApiBt0AddNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0RemoveNode( void * b, void * key ); +UINT32 OctApiBt0QueryNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0GetFirstNode( void * b, void ** key, void ** data ); +UINT32 OctApiBt0FindOrAddNode( void * b, void * key, void ** data, UINT32 *fnct_result ); + +UINT32 OctApiBt0AddNodeReportPrevNodeData( void * b, void * key, void ** data, void ** prev_data, UINT32 *fnct_result ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__OCTAPI_BT0_H__*/ diff --git a/xpp/oct612x/include/apilib/octapi_largmath.h b/xpp/oct612x/include/apilib/octapi_largmath.h new file mode 100644 index 0000000..1680474 --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_largmath.h @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LARGMATH_H__ +#define __OCTAPI_LARGMATH_H__ + +#include "octdef.h" + +#define OCTAPI_LM_DIVISION_BY_ZERO 0xFFFF +#define OCTAPI_LM_OVERFLOW 0xFFFE +#define OCTAPI_LM_ARRAY_SIZE_MISMATCH 0xFFFD + +#define OCTAPI_LM_MAX_OPTIMIZE_MUL 10 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_lm_add( a, alen, b, blen, z, zlen ) OctApiLmAdd( (PUINT32) a, (USHORT) alen, (PUINT32) b, (USHORT) blen, (PUINT32) z, (USHORT) zlen ) +#define octapi_lm_subtract( a, alen, bneg, blen, z, zlen, neg ) OctApiLmSubtract( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (PUINT32) z, (USHORT) zlen, (USHORT*) neg ) +#define octapi_lm_compare( a, alen, bneg, blen, neg ) OctApiLmCompare( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (USHORT*) neg ) +#define octapi_lm_multiply( a, b, ablen, z ) OctApiLmMultiply( (PUINT32) a, (PUINT32) b, (USHORT) ablen, (PUINT32) z ) +#define octapi_lm_divide( n, d, q, r, ndqrlen ) OctApiLmDivide( (PUINT32) n, (PUINT32) d, (PUINT32) q, (PUINT32) r, (USHORT) ndqrlen ) +#define octapi_lm_shiftright1( a, alen ) OctApiLmShiftRight1( (PUINT32) a, (USHORT) alen ) +#define octapi_lm_shiftn( a, alen, shiftleft, shiftn ) OctApiLmShiftn( (PUINT32) a, (USHORT) alen, (USHORT) shiftleft, (USHORT) shiftn ) +#define octapi_lm_getmsb( a, alen, msb_pos ) OctApiLmGetMsb( (PUINT32) a, (USHORT) alen, (USHORT*) msb_pos ) + + +UINT32 OctApiLmAdd( PUINT32 a, USHORT alen, PUINT32 b, USHORT blen, PUINT32 z, USHORT zlen ); +UINT32 OctApiLmSubtract( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUINT32 z, USHORT zlen, PUSHORT neg ); +UINT32 OctApiLmCompare( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUSHORT neg ); +UINT32 OctApiLmMultiply( PUINT32 a, PUINT32 b, USHORT ablen, PUINT32 z ); +UINT32 OctApiLmDivide( PUINT32 n, PUINT32 d, PUINT32 q, PUINT32 r, USHORT ndqrlen ); +UINT32 OctApiLmShiftRight1( PUINT32 a, USHORT alen ); +UINT32 OctApiLmShiftn( PUINT32 a, USHORT alen, USHORT shiftleft, USHORT shiftn ); +UINT32 OctApiLmGetMsb( PUINT32 a, USHORT alen, PUSHORT msb_pos ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LARGMATH_H__ */ diff --git a/xpp/oct612x/include/apilib/octapi_llman.h b/xpp/oct612x/include/apilib/octapi_llman.h new file mode 100644 index 0000000..b70a851 --- /dev/null +++ b/xpp/oct612x/include/apilib/octapi_llman.h @@ -0,0 +1,142 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_H__ +#define __OCTAPI_LLMAN_H__ + +#include "octdef.h" + +/* Error defines. */ +#define OCTAPI_LLM_MEMORY_NOT_ALLOCATED 0xFFFFFFFF +#define OCTAPI_LLM_NO_STRUCTURES_LEFT 0xFFFFFFFE +#define OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE 0xFFFFFFFD +#define OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED 0xFFFFFFFC +#define OCTAPI_LLM_ELEMENT_NOT_FOUND 0xFFFFFFFB +#define OCTAPI_LLM_LIST_EMPTY 0xFFFFFFFA +#define OCTAPI_LLM_INVALID_LIST_HANDLE 0xFFFFFFF9 +#define OCTAPI_LLM_TREE_NODE_ABSENT 0xFFFFFFF8 +#define OCTAPI_LLM_INTERNAL_ERROR0 0xFFFFFFF7 +#define OCTAPI_LLM_INTERNAL_ERROR1 0xFFFFFFF6 +#define OCTAPI_LLM_INVALID_PARAMETER 0xFFFFFFF5 + +#define OCTAPI_LLM2_MEMORY_NOT_ALLOCATED 0xFEFFFFFF +#define OCTAPI_LLM2_NO_STRUCTURES_LEFT 0xFEFFFFFE +#define OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE 0xFEFFFFFD +#define OCTAPI_LLM2_ELEMENT_ALREADY_ASSIGNED 0xFEFFFFFC +#define OCTAPI_LLM2_ELEMENT_NOT_FOUND 0xFEFFFFFB +#define OCTAPI_LLM2_LIST_EMPTY 0xFEFFFFFA +#define OCTAPI_LLM2_INVALID_LIST_HANDLE 0xFEFFFFF9 +#define OCTAPI_LLM2_TREE_NODE_ABSENT 0xFEFFFFF8 +#define OCTAPI_LLM2_INTERNAL_ERROR0 0xFEFFFFF7 +#define OCTAPI_LLM2_INTERNAL_ERROR1 0xFEFFFFF6 +#define OCTAPI_LLM2_INVALID_PARAMETER 0xFEFFFFF5 + +/* Other defines. */ +#define OCTAPI_LLM_LIST_APPEND 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_FIRST_NODE 0xFFFF0000 +#define OCTAPI_LLM2_INSERT_LIST_NODE 0xFFFF0001 +#define OCTAPI_LLM2_INSERT_LAST_NODE 0xFFFF0002 +#define OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE 0xFFFF0003 +#define OCTAPI_LLM2_REMOVE_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_REMOVE_FIRST_NODE 0xFFFF0004 +#define OCTAPI_LLM2_REMOVE_LIST_NODE 0xFFFF0005 +#define OCTAPI_LLM2_REMOVE_LAST_NODE 0xFFFF0006 +#define OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE 0xFFFF0007 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_llm_alloc_get_size( number_of_items, l_size ) OctapiLlmAllocGetSize( (UINT32) number_of_items,(PUINT32) l_size ) +#define octapi_llm_alloc_init( l, number_of_items ) OctapiLlmAllocInit( (PVOID*) l,(UINT32) number_of_items ) +#define octapi_llm_alloc_info( l, allocated_items, available_items ) OctapiLlmAllocInfo( (PVOID) l, (PUINT32) allocated_items, (PUINT32) available_items ) +#define octapi_llm_alloc_alloc( l, blocknum ) OctapiLlmAllocAlloc( (PVOID) l, (PUINT32) blocknum ) +#define octapi_llm_alloc_dealloc( l, blocknum ) OctapiLlmAllocDealloc( (PVOID) l,(UINT32) blocknum ) +#define octapi_llm_list_get_size( number_of_items, number_of_lists, user_info_size, l_size ) OctApiLlmListGetSize( (UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size,(PUINT32) l_size ) +#define octapi_llm_list_init( l, number_of_items, number_of_lists, user_info_size ) OctApiLlmListInit( (PVOID*) l,(UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size ) +#define octapi_llm_list_info( l, allocated_lists, allocated_items, free_lists, free_items ) OctApiLlmListInfo( (PVOID) l,(PUINT32) allocated_lists,(PUINT32) allocated_items,(PUINT32) free_lists,(PUINT32) free_items ) +#define octapi_llm_list_create( l, list_handle ) OctApiLlmListCreate( (PVOID) l,(PUINT32) list_handle ) +#define octapi_llm_list_create_full( l, list_length, plist_handle ) OctApiLlmListCreateFull( (PVOID) l, (UINT32) list_length, (PUINT32) plist_handle ) +#define octapi_llm_list_append_items( l, list_handle, num_items ) OctApiLlmListAppendItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items ) +#define octapi_llm_list_append_and_set_items( l, list_handle, num_items, data_list ) OctApiLlmListAppendAndSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items, (PVOID) data_list ) +#define octapi_llm_list_delete( l, list_handle ) OctApiLlmListDelete( (PVOID) l,(UINT32) list_handle ) +#define octapi_llm_list_length( l, list_handle, number_of_items_in_list ) OctApiLlmListLength( (PVOID) l,(UINT32) list_handle, (PUINT32) number_of_items_in_list ) +#define octapi_llm_list_insert_item( l, list_handle, item_number, item_data_pnt ) OctApiLlmListInsertItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_remove_item( l, list_handle, item_number ) OctApiLlmListRemoveItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number ) +#define octapi_llm_list_item_data( l, list_handle, item_number, item_data_pnt ) OctApiLlmListItemData( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_copy_data( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListCopyData( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) +#define octapi_llm_list_set_items( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) + +/* Alloc man. */ +UINT32 OctapiLlmAllocGetSize( UINT32 number_of_items,PUINT32 l_size ); +UINT32 OctapiLlmAllocInit( PVOID* l,UINT32 number_of_items ); +UINT32 OctapiLlmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctapiLlmAllocAlloc( PVOID l, PUINT32 blocknum ); +UINT32 OctapiLlmAllocDealloc( PVOID l,UINT32 blocknum ); + +/* Time managed alloc man. */ +UINT32 OctApiTllmAllocGetSize( UINT32 number_of_items, PUINT32 l_size ); +UINT32 OctApiTllmAllocInit( PVOID* l, UINT32 number_of_items ); +UINT32 OctApiTllmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctApiTllmAllocAlloc( PVOID l, PUINT32 blocknum, UINT32 current_time[2] ); +UINT32 OctApiTllmAllocDealloc( PVOID l, UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2] ); + +/* List man. */ +UINT32 OctApiLlmListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlmListInit( PVOID* l, UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlmListInfo( PVOID l, PUINT32 allocated_lists, PUINT32 allocated_items, PUINT32 free_lists, PUINT32 free_items ); +UINT32 OctApiLlmListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlmListCreateFull( PVOID l, UINT32 list_length, UINT32* plist_handle ); +UINT32 OctApiLlmListAppendItems( PVOID l, UINT32 list_handle, UINT32 num_items ); +UINT32 OctApiLlmListAppendAndSetItems( PVOID l, UINT32 list_handle, UINT32 num_items, PVOID data_list ); +UINT32 OctApiLlmListDelete( PVOID l, UINT32 list_handle ); +UINT32 OctApiLlmListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlmListInsertItem( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListRemoveItem( PVOID l, UINT32 list_handle, UINT32 item_number ); +UINT32 OctApiLlmListItemData( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListCopyData( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); +UINT32 OctApiLlmListSetItems( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); + +/* Second list manager using a key to order info in the list. */ +UINT32 OctApiLlm2ListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlm2ListInit( PVOID* l,UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlm2ListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlm2ListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlm2ListInsertItem(void * l, UINT32 list_handle, UINT32 item_key, void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ); +UINT32 OctApiLlm2ListRemoveItem(void * l, UINT32 list_handle, UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ); +UINT32 OctApiLlm2ListItemData( PVOID l, UINT32 list_handle, UINT32 item_key, PVOID* item_data_pnt, PUINT32 item_number ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LLMAN_H__ */ diff --git a/xpp/oct612x/include/digium_unused.h b/xpp/oct612x/include/digium_unused.h new file mode 100644 index 0000000..ecf382f --- /dev/null +++ b/xpp/oct612x/include/digium_unused.h @@ -0,0 +1,297 @@ +/* Define macros here to suppress functions from the API being built */ + +#if 1 + +#define SKIP_Oct6100AdpcmChanOpenDef 1 +#define SKIP_Oct6100AdpcmChanOpen 1 +#define SKIP_Oct6100AdpcmChanCloseDef 1 +#define SKIP_Oct6100AdpcmChanClose 1 +#define SKIP_Oct6100AdpcmChanOpenSer 1 +#define SKIP_Oct6100ApiCheckAdpcmChanParams 1 +#define SKIP_Oct6100ApiReserveAdpcmChanResources 1 +#define SKIP_Oct6100ApiWriteAdpcmChanStructs 1 +#define SKIP_Oct6100ApiUpdateAdpcmChanEntry 1 +#define SKIP_Oct6100AdpcmChanCloseSer 1 +#define SKIP_Oct6100ApiAssertAdpcmChanParams 1 +#define SKIP_Oct6100ApiInvalidateAdpcmChanStructs 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanResources 1 +#define SKIP_Oct6100ApiReserveAdpcmChanEntry 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanEntry 1 +#define SKIP_Oct6100ChannelCloseDef 1 +#define SKIP_Oct6100ChannelClose 1 +#define SKIP_Oct6100ChannelCreateBiDirDef 1 +#define SKIP_Oct6100ChannelCreateBiDir 1 +#define SKIP_Oct6100ChannelDestroyBiDirDef 1 +#define SKIP_Oct6100ChannelDestroyBiDir 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddDef 1 +#define SKIP_Oct6100ChannelBroadcastTsstAdd 1 +#define SKIP_Oct6100ChannelBroadcastTsstRemove 1 +#define SKIP_Oct6100ChannelGetStatsDef 1 +#define SKIP_Oct6100ChannelGetStats 1 +#define SKIP_Oct6100ChannelMuteDef 1 +#define SKIP_Oct6100ChannelMute 1 +#define SKIP_Oct6100ChannelUnMuteDef 1 +#define SKIP_Oct6100ChannelUnMute 1 +#define SKIP_Oct6100ChannelCloseSer 1 +#define SKIP_Oct6100ApiAssertChannelParams 1 +#define SKIP_Oct6100ApiInvalidateChannelStructs 1 +#define SKIP_Oct6100ApiReleaseChannelResources 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddSer 1 +#define SKIP_Oct6100ApiCheckChanTsstAddParams 1 +#define SKIP_Oct6100ApiReserveTsstAddResources 1 +#define SKIP_Oct6100ApiWriteTsstAddStructs 1 +#define SKIP_Oct6100ApiUpdateTsstAddChanEntry 1 +#define SKIP_Oct6100ApiChannelGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBiDirChanEntry 1 +#define SKIP_Oct6100ApiReleaseBiDirChanEntry 1 +#define SKIP_Oct6100ApiRetrieveNlpConfDword 1 +#define SKIP_Oct6100ApiSaveNlpConfDword 1 +#define SKIP_Oct6100ChannelCreateBiDirSer 1 +#define SKIP_Oct6100ApiCheckChannelCreateBiDirParams 1 +#define SKIP_Oct6100ApiReserveChannelCreateBiDirResources 1 +#define SKIP_Oct6100ApiWriteChannelCreateBiDirStructs 1 +#define SKIP_Oct6100ApiUpdateBiDirChannelEntry 1 +#define SKIP_Oct6100ChannelDestroyBiDirSer 1 +#define SKIP_Oct6100ApiAssertDestroyBiDirChanParams 1 +#define SKIP_Oct6100ApiInvalidateBiDirChannelStructs 1 +#define SKIP_Oct6100ApiReleaseBiDirChannelResources 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyByte 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyHalf 1 +#define SKIP_Oct6100ChannelMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelMuteParams 1 +#define SKIP_Oct6100ChannelUnMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelUnMuteParams 1 +#define SKIP_Oct6100ApiMuteSinWithFeatures 1 +#define SKIP_Oct6100ApiMuteChannelPorts 1 +#define SKIP_Oct6100CreateLocalInstanceDef 1 +#define SKIP_Oct6100CreateLocalInstance 1 +#define SKIP_Oct6100DestroyLocalInstanceDef 1 +#define SKIP_Oct6100DestroyLocalInstance 1 +#define SKIP_Oct6100GetHwRevisionDef 1 +#define SKIP_Oct6100GetHwRevision 1 +#define SKIP_Oct6100FreeResourcesDef 1 +#define SKIP_Oct6100FreeResources 1 +#define SKIP_Oct6100ProductionBistDef 1 +#define SKIP_Oct6100ProductionBist 1 +#define SKIP_Oct6100ApiGetVersionDef 1 +#define SKIP_Oct6100ApiGetVersion 1 +#define SKIP_Oct6100FreeResourcesSer 1 +#define SKIP_Oct6100ProductionBistSer 1 +#define SKIP_Oct6100ChipGetStatsDef 1 +#define SKIP_Oct6100ChipGetStats 1 +#define SKIP_Oct6100ChipGetImageInfoDef 1 +#define SKIP_Oct6100ChipGetImageInfo 1 +#define SKIP_Oct6100ChipGetStatsSer 1 +#define SKIP_Oct6100ConfBridgeOpenDef 1 +#define SKIP_Oct6100ConfBridgeOpen 1 +#define SKIP_Oct6100ConfBridgeClose 1 +#define SKIP_Oct6100ConfBridgeChanAddDef 1 +#define SKIP_Oct6100ConfBridgeChanAdd 1 +#define SKIP_Oct6100ConfBridgeChanRemove 1 +#define SKIP_Oct6100ConfBridgeChanMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanMute 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanUnMute 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetDef 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSet 1 +#define SKIP_Oct6100ConfBridgeMaskChangeDef 1 +#define SKIP_Oct6100ConfBridgeMaskChange 1 +#define SKIP_Oct6100ConfBridgeGetStatsDef 1 +#define SKIP_Oct6100ConfBridgeGetStats 1 +#define SKIP_Oct6100ConfBridgeOpenSer 1 +#define SKIP_Oct6100ApiCheckBridgeParams 1 +#define SKIP_Oct6100ApiReserveBridgeResources 1 +#define SKIP_Oct6100ApiUpdateBridgeEntry 1 +#define SKIP_Oct6100ConfBridgeChanAddSer 1 +#define SKIP_Oct6100ApiCheckBridgeAddParams 1 +#define SKIP_Oct6100ApiReserveBridgeAddResources 1 +#define SKIP_Oct6100ApiBridgeEventAdd 1 +#define SKIP_Oct6100ApiBridgeAddParticipantToChannel 1 +#define SKIP_Oct6100ConfBridgeChanMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeMuteResources 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeUnMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeUnMuteResources 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetSer 1 +#define SKIP_Oct6100ApiCheckBridgeDominantSpeakerParams 1 +#define SKIP_Oct6100ApiUpdateBridgeDominantSpeakerResources 1 +#define SKIP_Oct6100ConfBridgeMaskChangeSer 1 +#define SKIP_Oct6100ApiCheckBridgeMaskChangeParams 1 +#define SKIP_Oct6100ApiUpdateMaskModifyResources 1 +#define SKIP_Oct6100ApiBridgeUpdateMask 1 +#define SKIP_Oct6100ConfBridgeGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBridgeEntry 1 +#define SKIP_Oct6100ApiReserveFlexConfParticipantEntry 1 +#define SKIP_Oct6100DebugSelectChannelDef 1 +#define SKIP_Oct6100DebugSelectChannel 1 +#define SKIP_Oct6100DebugGetDataDef 1 +#define SKIP_Oct6100DebugGetData 1 +#define SKIP_Oct6100DebugSelectChannelSer 1 +#define SKIP_Oct6100DebugGetDataSer 1 +#define SKIP_Oct6100BufferPlayoutGetEventDef 1 +#define SKIP_Oct6100BufferPlayoutGetEvent 1 +#define SKIP_Oct6100BufferPlayoutGetEventSer 1 +#define SKIP_Oct6100InterruptConfigureDef 1 +#define SKIP_Oct6100InterruptConfigure 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiCreateFeatureMask 1 +#define SKIP_Oct6100MixerCopyEventCreateDef 1 +#define SKIP_Oct6100MixerCopyEventCreate 1 +#define SKIP_Oct6100MixerCopyEventDestroyDef 1 +#define SKIP_Oct6100MixerCopyEventDestroy 1 +#define SKIP_Oct6100MixerCopyEventCreateSer 1 +#define SKIP_Oct6100ApiCheckCopyEventCreateParams 1 +#define SKIP_Oct6100ApiReserveCopyEventCreateResources 1 +#define SKIP_Oct6100ApiWriteCopyEventCreateStructs 1 +#define SKIP_Oct6100ApiUpdateCopyEventCreateEntry 1 +#define SKIP_Oct6100MixerCopyEventDestroySer 1 +#define SKIP_Oct6100ApiAssertCopyEventDestroyParams 1 +#define SKIP_Oct6100ApiInvalidateCopyEventStructs 1 +#define SKIP_Oct6100ApiReleaseCopyEventResources 1 +#define SKIP_Oct6100ApiReserveCopyEventEntry 1 +#define SKIP_Oct6100ApiReleaseCopyEventEntry 1 +#define SKIP_Oct6100PhasingTsstOpenDef 1 +#define SKIP_Oct6100PhasingTsstOpen 1 +#define SKIP_Oct6100PhasingTsstCloseDef 1 +#define SKIP_Oct6100PhasingTsstClose 1 +#define SKIP_Oct6100PhasingTsstOpenSer 1 +#define SKIP_Oct6100ApiCheckPhasingParams 1 +#define SKIP_Oct6100ApiReservePhasingResources 1 +#define SKIP_Oct6100ApiWritePhasingStructs 1 +#define SKIP_Oct6100ApiUpdatePhasingEntry 1 +#define SKIP_Oct6100PhasingTsstCloseSer 1 +#define SKIP_Oct6100ApiAssertPhasingParams 1 +#define SKIP_Oct6100ApiInvalidatePhasingStructs 1 +#define SKIP_Oct6100ApiReleasePhasingResources 1 +#define SKIP_Oct6100ApiReservePhasingEntry 1 +#define SKIP_Oct6100ApiReleasePhasingEntry 1 +#define SKIP_Oct6100BufferPlayoutLoadDef 1 +#define SKIP_Oct6100BufferPlayoutLoad 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInitDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInit 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlock 1 +#define SKIP_Oct6100BufferPlayoutUnloadDef 1 +#define SKIP_Oct6100BufferPlayoutUnload 1 +#define SKIP_Oct6100BufferPlayoutAddDef 1 +#define SKIP_Oct6100BufferPlayoutAdd 1 +#define SKIP_Oct6100BufferPlayoutStartDef 1 +#define SKIP_Oct6100BufferPlayoutStart 1 +#define SKIP_Oct6100BufferPlayoutStop 1 +#define SKIP_Oct6100BufferLoadSer 1 +#define SKIP_Oct6100BufferLoadBlockInitSer 1 +#define SKIP_Oct6100BufferLoadBlockSer 1 +#define SKIP_Oct6100ApiCheckBufferParams 1 +#define SKIP_Oct6100ApiCheckBufferLoadBlockParams 1 +#define SKIP_Oct6100ApiReserveBufferResources 1 +#define SKIP_Oct6100ApiWriteBufferInMemory 1 +#define SKIP_Oct6100ApiUpdateBufferEntry 1 +#define SKIP_Oct6100BufferUnloadSer 1 +#define SKIP_Oct6100ApiAssertBufferParams 1 +#define SKIP_Oct6100ApiReleaseBufferResources 1 +#define SKIP_Oct6100BufferPlayoutAddSer 1 +#define SKIP_Oct6100ApiCheckPlayoutAddParams 1 +#define SKIP_Oct6100ApiWriteBufferAddStructs 1 +#define SKIP_Oct6100BufferPlayoutStartSer 1 +#define SKIP_Oct6100ApiCheckPlayoutStartParams 1 +#define SKIP_Oct6100ApiWriteChanPlayoutStructs 1 +#define SKIP_Oct6100ApiReserveBufPlayoutListEntry 1 +#define SKIP_Oct6100ApiReleaseBufPlayoutListEntry 1 +#define SKIP_Oct6100RemoteDebugDef 1 +#define SKIP_Oct6100RemoteDebug 1 +#define SKIP_Oct6100ApiCheckEndianDetectField 1 +#define SKIP_Oct6100ApiCalculateChecksum 1 +#define SKIP_Oct6100ApiFormResponsePkt 1 +#define SKIP_Oct6100ApiCheckPktCommands 1 +#define SKIP_Oct6100ApiExecutePktCommands 1 +#define SKIP_Oct6100ApiCheckSessionNum 1 +#define SKIP_Oct6100ApiRpcReadWord 1 +#define SKIP_Oct6100ApiRpcReadBurst 1 +#define SKIP_Oct6100ApiRpcReadArray 1 +#define SKIP_Oct6100ApiRpcWriteWord 1 +#define SKIP_Oct6100ApiRpcWriteSmear 1 +#define SKIP_Oct6100ApiRpcWriteBurst 1 +#define SKIP_Oct6100ApiRpcSetHotChannel 1 +#define SKIP_Oct6100ApiRpcGetDebugChanIndex 1 +#define SKIP_Oct6100ApiRpcDisconnect 1 +#define SKIP_Oct6100ToneDetectionDisable 1 +#define SKIP_Oct6100TsiCnctOpenDef 1 +#define SKIP_Oct6100TsiCnctOpen 1 +#define SKIP_Oct6100TsiCnctCloseDef 1 +#define SKIP_Oct6100TsiCnctClose 1 +#define SKIP_Oct6100TsiCnctOpenSer 1 +#define SKIP_Oct6100ApiCheckTsiParams 1 +#define SKIP_Oct6100ApiReserveTsiResources 1 +#define SKIP_Oct6100ApiWriteTsiStructs 1 +#define SKIP_Oct6100ApiUpdateTsiEntry 1 +#define SKIP_Oct6100TsiCnctCloseSer 1 +#define SKIP_Oct6100ApiAssertTsiParams 1 +#define SKIP_Oct6100ApiInvalidateTsiStructs 1 +#define SKIP_Oct6100ApiReleaseTsiResources 1 +#define SKIP_Oct6100ApiReserveTsiCnctEntry 1 +#define SKIP_Oct6100ApiReleaseTsiCnctEntry 1 +#define SKIP_Oct6100UserDriverWriteOs 1 +#define SKIP_Oct6100UserDriverWriteSmearOs 1 +#define SKIP_Oct6100UserDriverWriteBurstOs 1 +#define SKIP_Oct6100UserDriverReadOs 1 +#define SKIP_Oct6100UserDriverReadBurstOs 1 +#define SKIP_OctApiBt0AddNode 1 +#define SKIP_OctApiBt0AddNode2 1 +#define SKIP_OctApiBt0AddNode3 1 +#define SKIP_OctApiBt0AddNode4 1 +#define SKIP_OctApiBt0KeyCompare 1 +#define SKIP_OctApiBt0UpdateLinkDepth 1 +#define SKIP_OctApiBt0Rebalance 1 +#define SKIP_OctApiBt0ExternalHeavy 1 +#define SKIP_OctApiBt0RemoveNode2 1 +#define SKIP_OctApiBt0RemoveNode3 1 +#define SKIP_OctApiBt0RemoveNode 1 +#define SKIP_OctApiBt0QueryNode2 1 +#define SKIP_OctApiBt0QueryNode 1 +#define SKIP_OctApiBt0GetFirstNode 1 +#define SKIP_OctApiBt0FindOrAddNode 1 +#define SKIP_OctApiBt0AddNodeReportPrevNodeData 1 +#define SKIP_OctApiLmCompare 1 +#define SKIP_OctApiLmMultiply 1 +#define SKIP_OctApiLmDivide 1 +#define SKIP_OctApiLmShiftRight1 1 +#define SKIP_OctApiLmShiftn 1 +#define SKIP_OctApiLmGetMsb 1 +#define SKIP_OctApiTllmAllocGetSize 1 +#define SKIP_OctApiTllmAllocInit 1 +#define SKIP_OctApiTllmAllocInfo 1 +#define SKIP_OctApiTllmAllocAlloc 1 +#define SKIP_OctApiTllmAllocDealloc 1 +#define SKIP_OctApiTllmCheckTimeoutList 1 +#define SKIP_OctApiLlmListGetSize 1 +#define SKIP_OctApiLlmListGetItemPointer 1 +#define SKIP_OctApiLlmListInit 1 +#define SKIP_OctApiLlmListInfo 1 +#define SKIP_OctApiLlmListCreate 1 +#define SKIP_OctApiLlmListDelete 1 +#define SKIP_OctApiLlmListLength 1 +#define SKIP_OctApiLlmListItemData 1 +#define SKIP_OctApiLlmListInsertItem 1 +#define SKIP_OctApiLlmListCreateFull 1 +#define SKIP_OctApiLlmListAppendItems 1 +#define SKIP_OctApiLlmListAppendAndSetItems 1 +#define SKIP_OctApiLlmListSetItems 1 +#define SKIP_OctApiLlmListCopyData 1 +#define SKIP_OctApiLlmListRemoveItem 1 +#define SKIP_OctApiLlm2ListGetSize 1 +#define SKIP_OctApiLlm2ListGetItemPointer 1 +#define SKIP_OctApiLlm2ListInit 1 +#define SKIP_OctApiLlm2ListCreate 1 +#define SKIP_OctApiLlm2ListDelete 1 +#define SKIP_OctApiLlm2ListLength 1 +#define SKIP_OctApiLlm2ListItemData 1 +#define SKIP_OctApiLlm2ListInsertItem 1 +#define SKIP_OctApiLlm2ListRemoveItem 1 +#define SKIP_OctApiLlmMemCpy 1 + +#endif + diff --git a/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h new file mode 100644 index 0000000..9e33909 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_INST_H__ +#define __OCT6100_ADPCM_CHAN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_ADPCM_CHAN_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* ADPCM memory entry. */ + UINT16 usAdpcmMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + UINT8 byInputNumTssts; + UINT8 byInputPcmLaw; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + UINT8 byOutputNumTssts; + UINT8 byOutputPcmLaw; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_ADPCM_CHAN, *tPOCT6100_API_ADPCM_CHAN; + +#endif /* __OCT6100_ADPCM_CHAN_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h new file mode 100644 index 0000000..e29fac4 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h @@ -0,0 +1,90 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PUB_H__ +#define __OCT6100_ADPCM_CHAN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_ADPCM_CHAN_OPEN_ +{ + PUINT32 pulChanHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulInputNumTssts; + UINT32 ulInputPcmLaw; + + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + UINT32 ulOutputNumTssts; + UINT32 ulOutputPcmLaw; + + UINT32 ulChanMode; /* Encoding or decoding. */ + + UINT32 ulEncodingRate; + UINT32 ulDecodingRate; + + UINT32 ulAdpcmNibblePosition; + +} tOCT6100_ADPCM_CHAN_OPEN, *tPOCT6100_ADPCM_CHAN_OPEN; + +typedef struct _OCT6100_ADPCM_CHAN_CLOSE_ +{ + UINT32 ulChanHndl; + +} tOCT6100_ADPCM_CHAN_CLOSE, *tPOCT6100_ADPCM_CHAN_CLOSE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100AdpcmChanOpenDef( + OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); +UINT32 Oct6100AdpcmChanOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100AdpcmChanCloseDef( + OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); +UINT32 Oct6100AdpcmChanClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +#endif /* __OCT6100_ADPCM_CHAN_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_api.h b/xpp/oct612x/include/oct6100api/oct6100_api.h new file mode 100644 index 0000000..35a9666 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_api.h @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all definitions used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_H__ +#define __OCT6100_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100_defines.h" +#include "oct6100_errors.h" + +#include "oct6100_apiud.h" +#include "oct6100_tlv_inst.h" +#include "oct6100_chip_stats_inst.h" +#include "oct6100_tsi_cnct_inst.h" +#include "oct6100_mixer_inst.h" +#include "oct6100_events_inst.h" +#include "oct6100_tone_detection_inst.h" +#include "oct6100_conf_bridge_inst.h" +#include "oct6100_playout_buf_inst.h" + +#include "oct6100_adpcm_chan_inst.h" +#include "oct6100_phasing_tsst_inst.h" +#include "oct6100_channel_inst.h" +#include "oct6100_interrupts_inst.h" +#include "oct6100_remote_debug_inst.h" +#include "oct6100_debug_inst.h" +#include "oct6100_chip_open_inst.h" +#include "oct6100_api_inst.h" + +#include "oct6100_interrupts_pub.h" +#include "oct6100_tsi_cnct_pub.h" +#include "oct6100_events_pub.h" +#include "oct6100_tone_detection_pub.h" +#include "oct6100_mixer_pub.h" +#include "oct6100_conf_bridge_pub.h" +#include "oct6100_playout_buf_pub.h" + +#include "oct6100_channel_pub.h" +#include "oct6100_remote_debug_pub.h" +#include "oct6100_debug_pub.h" +#include "oct6100_chip_open_pub.h" +#include "oct6100_chip_stats_pub.h" +#include "oct6100_adpcm_chan_pub.h" +#include "oct6100_phasing_tsst_pub.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __OCT6100_API_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_api_inst.h b/xpp/oct612x/include/oct6100api/oct6100_api_inst.h new file mode 100644 index 0000000..29bd0fd --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_api_inst.h @@ -0,0 +1,138 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing the definition of the API instance structure. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 40 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_INST_H__ +#define __OCT6100_API_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_SHARED_INFO_ +{ + /* Local copy of chip configuration structure. */ + tOCT6100_API_CHIP_CONFIG ChipConfig; + + /* Miscellaneous calculations and mapping of static structures in external memory. */ + tOCT6100_API_MISCELLANEOUS MiscVars; + tOCT6100_API_MEMORY_MAP MemoryMap; + + /* Error stats structure. */ + tOCT6100_API_CHIP_ERROR_STATS ErrorStats; + tOCT6100_API_CHIP_STATS ChipStats; + + /* Mixer information. */ + tOCT6100_API_MIXER MixerInfo; + + /* Image breakdown information. */ + tOCT6100_API_IMAGE_REGION ImageRegion[ cOCT6100_MAX_IMAGE_REGION ]; + tOCT6100_API_IMAGE_INFO ImageInfo; + + /* Configuration and management of interrupts. */ + tOCT6100_API_INTRPT_CONFIG IntrptConfig; + tOCT6100_API_INTRPT_MANAGE IntrptManage; + /* Remote debugging. */ + tOCT6100_API_REMOTE_DEBUG_INFO RemoteDebugInfo; + /* Chip debugging information. */ + tOCT6100_API_DEBUG DebugInfo; + + /* Management variables of software and hardware buffers. */ + tOCT6100_API_SOFT_BUFS SoftBufs; + + /* Caller buffer playout memory management structure. */ + tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO PlayoutInfo; + + + + UINT32 ulChannelListOfst; + UINT32 ulChannelAllocOfst; + + UINT32 ulConversionMemoryAllocOfst; + + UINT32 ulTsiMemoryAllocOfst; + UINT32 ulExtraTsiMemoryAllocOfst; + UINT32 ulEchoMemoryAllocOfst; + + UINT32 ulTsstAllocOfst; + UINT32 ulTsstListOfst; + UINT32 ulTsstListAllocOfst; + + UINT32 ulTsiCnctListOfst; + UINT32 ulTsiCnctAllocOfst; + + UINT32 ulMixerEventListOfst; + UINT32 ulMixerEventAllocOfst; + + UINT32 ulCopyEventListOfst; + UINT32 ulCopyEventAllocOfst; + + UINT32 ulBiDirChannelListOfst; + UINT32 ulBiDirChannelAllocOfst; + + UINT32 ulConfBridgeListOfst; + UINT32 ulConfBridgeAllocOfst; + + UINT32 ulFlexConfParticipantListOfst; + UINT32 ulFlexConfParticipantAllocOfst; + + UINT32 ulPlayoutBufListOfst; + UINT32 ulPlayoutBufAllocOfst; + UINT32 ulPlayoutBufMemoryNodeListOfst; + + + + UINT32 ulAdpcmChanListOfst; + UINT32 ulAdpcmChanAllocOfst; + + UINT32 ulPhasingTsstListOfst; + UINT32 ulPhasingTsstAllocOfst; + +} tOCT6100_SHARED_INFO, *tPOCT6100_SHARED_INFO; + +typedef struct _OCT6100_INSTANCE_API_ +{ + /* Pointer to portion of API instance structure shared amongst all processes. */ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Pointer to user-supplied, process context structure. The structure is + a parameter to all user-supplied functions. */ + PVOID pProcessContext; + + /* Handles to all serialization objects used by the API. */ + tOCT6100_USER_SERIAL_OBJECT ulApiSerObj; + + +} tOCT6100_INSTANCE_API, *tPOCT6100_INSTANCE_API; + +#endif /* __OCT6100_API_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_apimi.h b/xpp/oct612x/include/oct6100api/oct6100_apimi.h new file mode 100644 index 0000000..dd584ea --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_apimi.h @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apimi.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the declaration of all functions exported from the + APIMI block. The APIMI block contains only one function: + Oct6100InterruptMask. + The function is used to mask out the interrupt pin of the chip. This + function is used when a deferred procedure call treats the interrupt (new + interrupts must not be generated until the signalled interrupt is treated). + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIMI_H__ +#define __OCT6100_APIMI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_MASK_ +{ + UINT32 ulUserChipIndex; + PVOID pProcessContext; + + +} tOCT6100_INTERRUPT_MASK, *tPOCT6100_INTERRUPT_MASK; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptMaskDef( + OUT tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); +UINT32 Oct6100InterruptMask( + IN tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCT6100_APIMI_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_apiud.h b/xpp/oct612x/include/oct6100api/oct6100_apiud.h new file mode 100644 index 0000000..feff93e --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_apiud.h @@ -0,0 +1,312 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apiud.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing the definitions and prototypes that are to be + completed by the user. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIUD_H__ +#define __OCT6100_APIUD_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + + +/* Determines the maximum length of a burst of reads/writes. This value must + be in the range 8 - 1024. This value obtains best performance if set to + a power of 2 (i.e. 2^n). */ +#define cOCT6100_MAX_RW_ACCESSES 32 + +/* The define used to specify that the Oct6100SeizeSerializeObject function + is not to return until the specified serialization object has been seized. */ +#define cOCT6100_WAIT_INFINITELY 0xFFFFFFFF + + +/* Compile option: enabling this compile option inserts code to check every + call to a user provided function to make sure the function parameters + are not changed, as required by the API specification. */ +#define cOCT6100_USER_FUNCTION_CHECK + + + +#define cOCT6100_GET_TIME_FAILED_0 0xFFFF0000 +#define cOCT6100_GET_TIME_FAILED_1 0xFFFF0001 +#define cOCT6100_GET_TIME_FAILED_2 0xFFFF0002 +#define cOCT6100_GET_TIME_FAILED_3 0xFFFF0003 +#define cOCT6100_GET_TIME_FAILED_4 0xFFFF0004 + +#define cOCT6100_CREATE_SERIAL_FAILED_0 0xFFFF0010 +#define cOCT6100_CREATE_SERIAL_FAILED_1 0xFFFF0011 +#define cOCT6100_CREATE_SERIAL_FAILED_2 0xFFFF0012 +#define cOCT6100_CREATE_SERIAL_FAILED_3 0xFFFF0013 +#define cOCT6100_CREATE_SERIAL_FAILED_4 0xFFFF0014 + +#define cOCT6100_DESTROY_SERIAL_FAILED_0 0xFFFF0020 +#define cOCT6100_DESTROY_SERIAL_FAILED_1 0xFFFF0021 +#define cOCT6100_DESTROY_SERIAL_FAILED_2 0xFFFF0022 +#define cOCT6100_DESTROY_SERIAL_FAILED_3 0xFFFF0023 +#define cOCT6100_DESTROY_SERIAL_FAILED_4 0xFFFF0024 + +#define cOCT6100_INVALID_SERIAL_HANDLE_0 0xFFFF0030 +#define cOCT6100_INVALID_SERIAL_HANDLE_1 0xFFFF0031 +#define cOCT6100_INVALID_SERIAL_HANDLE_2 0xFFFF0032 +#define cOCT6100_INVALID_SERIAL_HANDLE_3 0xFFFF0033 +#define cOCT6100_INVALID_SERIAL_HANDLE_4 0xFFFF0034 + +#define cOCT6100_RELEASE_SERIAL_FAILED_0 0xFFFF0040 +#define cOCT6100_RELEASE_SERIAL_FAILED_1 0xFFFF0041 +#define cOCT6100_RELEASE_SERIAL_FAILED_2 0xFFFF0042 +#define cOCT6100_RELEASE_SERIAL_FAILED_3 0xFFFF0043 +#define cOCT6100_RELEASE_SERIAL_FAILED_4 0xFFFF0044 + +#define cOCT6100_SEIZE_SERIAL_FAILED_0 0xFFFF0050 +#define cOCT6100_SEIZE_SERIAL_FAILED_1 0xFFFF0051 +#define cOCT6100_SEIZE_SERIAL_FAILED_2 0xFFFF0052 +#define cOCT6100_SEIZE_SERIAL_FAILED_3 0xFFFF0053 +#define cOCT6100_SEIZE_SERIAL_FAILED_4 0xFFFF0054 + +#define cOCT6100_DRIVER_WRITE_FAILED_0 0xFFFF0060 +#define cOCT6100_DRIVER_WRITE_FAILED_1 0xFFFF0061 +#define cOCT6100_DRIVER_WRITE_FAILED_2 0xFFFF0062 +#define cOCT6100_DRIVER_WRITE_FAILED_3 0xFFFF0063 +#define cOCT6100_DRIVER_WRITE_FAILED_4 0xFFFF0064 + +#define cOCT6100_DRIVER_WSMEAR_FAILED_0 0xFFFF0070 +#define cOCT6100_DRIVER_WSMEAR_FAILED_1 0xFFFF0071 +#define cOCT6100_DRIVER_WSMEAR_FAILED_2 0xFFFF0072 +#define cOCT6100_DRIVER_WSMEAR_FAILED_3 0xFFFF0073 +#define cOCT6100_DRIVER_WSMEAR_FAILED_4 0xFFFF0074 + +#define cOCT6100_DRIVER_WBURST_FAILED_0 0xFFFF0080 +#define cOCT6100_DRIVER_WBURST_FAILED_1 0xFFFF0081 +#define cOCT6100_DRIVER_WBURST_FAILED_2 0xFFFF0082 +#define cOCT6100_DRIVER_WBURST_FAILED_3 0xFFFF0083 +#define cOCT6100_DRIVER_WBURST_FAILED_4 0xFFFF0084 + +#define cOCT6100_DRIVER_READ_FAILED_0 0xFFFF0090 +#define cOCT6100_DRIVER_READ_FAILED_1 0xFFFF0091 +#define cOCT6100_DRIVER_READ_FAILED_2 0xFFFF0092 +#define cOCT6100_DRIVER_READ_FAILED_3 0xFFFF0093 +#define cOCT6100_DRIVER_READ_FAILED_4 0xFFFF0094 + +#define cOCT6100_DRIVER_RBURST_FAILED_0 0xFFFF00A0 +#define cOCT6100_DRIVER_RBURST_FAILED_1 0xFFFF00A1 +#define cOCT6100_DRIVER_RBURST_FAILED_2 0xFFFF00A2 +#define cOCT6100_DRIVER_RBURST_FAILED_3 0xFFFF00A3 +#define cOCT6100_DRIVER_RBURST_FAILED_4 0xFFFF00A4 + + + + + +/***************************** TYPES ***************************************/ + +/*Change this type if your platform uses 64bits semaphores/locks */ +typedef UINT32 tOCT6100_USER_SERIAL_OBJECT; + +typedef struct _OCT6100_GET_TIME_ +{ + PVOID pProcessContext; + UINT32 aulWallTimeUs[ 2 ]; + +} tOCT6100_GET_TIME, *tPOCT6100_GET_TIME; + + + + + +typedef struct _OCT6100_CREATE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + PSZ pszSerialObjName; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_CREATE_SERIALIZE_OBJECT, *tPOCT6100_CREATE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_DESTROY_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_DESTROY_SERIALIZE_OBJECT, *tPOCT6100_DESTROY_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_SEIZE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + UINT32 ulTryTimeMs; + +} tOCT6100_SEIZE_SERIALIZE_OBJECT, *tPOCT6100_SEIZE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_RELEASE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_RELEASE_SERIALIZE_OBJECT, *tPOCT6100_RELEASE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_WRITE_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT16 usWriteData; + +} tOCT6100_WRITE_PARAMS, *tPOCT6100_WRITE_PARAMS; + + +typedef struct _OCT6100_WRITE_SMEAR_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + UINT16 usWriteData; + +} tOCT6100_WRITE_SMEAR_PARAMS, *tPOCT6100_WRITE_SMEAR_PARAMS; + + +typedef struct _OCT6100_WRITE_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + PUINT16 pusWriteData; + +} tOCT6100_WRITE_BURST_PARAMS, *tPOCT6100_WRITE_BURST_PARAMS; + + +typedef struct _OCT6100_READ_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + PUINT16 pusReadData; + +} tOCT6100_READ_PARAMS, *tPOCT6100_READ_PARAMS; + + +typedef struct _OCT6100_READ_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + UINT32 ulReadLength; + PUINT16 pusReadData; + +} tOCT6100_READ_BURST_PARAMS, *tPOCT6100_READ_BURST_PARAMS; + + + + + + + + +/************************** FUNCTION PROTOTYPES *****************************/ + +/* Time function. */ +UINT32 Oct6100UserGetTime( + IN OUT tPOCT6100_GET_TIME f_pTime ); + + + +/* Memory management functions. */ +UINT32 Oct6100UserMemSet( + IN PVOID f_pAddress, + IN UINT32 f_ulPattern, + IN UINT32 f_ulLength ); + +UINT32 Oct6100UserMemCopy( + IN PVOID f_pDestination, + IN const void *f_pSource, + IN UINT32 f_ulLength ); + +/* Serialization functions. */ +UINT32 Oct6100UserCreateSerializeObject( + IN OUT tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate); + +UINT32 Oct6100UserDestroySerializeObject( + IN tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy); + +UINT32 Oct6100UserSeizeSerializeObject( + IN tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize); + +UINT32 Oct6100UserReleaseSerializeObject( + IN tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease); + +/* Read/Write functions.*/ +UINT32 Oct6100UserDriverWriteApi( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteOs( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteSmearApi( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteSmearOs( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteBurstApi( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverWriteBurstOs( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadApi( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadOs( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadBurstApi( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadBurstOs( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + + + + + + + +#endif /* __OCT6100_APIUD_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h b/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h new file mode 100644 index 0000000..5b71bb0 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_channel_inst.h @@ -0,0 +1,374 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 90 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_INST_H__ +#define __OCT6100_CHANNEL_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +#ifndef __KERNEL__ +#include +#endif + +#ifndef PTR_TYPE +#define PTR_TYPE UINT16 +#endif + +typedef struct _OCT6100_API_CHANNEL_TDM_ +{ + /* Laws. */ + UINT8 byRinPcmLaw : 1; + UINT8 bySinPcmLaw : 1; + UINT8 byRoutPcmLaw : 1; + UINT8 bySoutPcmLaw : 1; + + UINT8 byRinNumTssts : 1; + UINT8 bySinNumTssts : 1; + UINT8 byRoutNumTssts : 1; + UINT8 bySoutNumTssts : 1; + + /* RIN port. */ + UINT16 usRinTimeslot; + UINT16 usRinStream; + + /* SIN port. */ + UINT16 usSinTimeslot; + UINT16 usSinStream; + + /* ROUT port. */ + UINT16 usRoutTimeslot; + UINT16 usRoutStream; + + /* SOUT port. */ + UINT16 usSoutTimeslot; + UINT16 usSoutStream; + + /* ROUT broadcast info. */ + UINT16 usRoutBrdcastTsstFirstEntry; + UINT16 usRoutBrdcastTsstNumEntry; + + /* SOUT broadcast info. */ + UINT16 usSoutBrdcastTsstFirstEntry; + UINT16 usSoutBrdcastTsstNumEntry; + +} tOCT6100_API_CHANNEL_TDM, *tPOCT6100_API_CHANNEL_TDM; + +typedef struct _OCT6100_API_CHANNEL_VQE_ +{ + UINT8 fEnableNlp : 1; + UINT8 fEnableTailDisplacement : 1; + UINT8 fSinDcOffsetRemoval : 1; + UINT8 fRinDcOffsetRemoval : 1; + UINT8 fRinLevelControl : 1; + UINT8 fSoutLevelControl : 1; + UINT8 fRinAutomaticLevelControl : 1; + UINT8 fSoutAutomaticLevelControl : 1; + UINT8 fRinHighLevelCompensation : 1; + UINT8 fSoutAdaptiveNoiseReduction : 1; + UINT8 fDtmfToneRemoval : 1; + UINT8 fAcousticEcho : 1; + UINT8 byComfortNoiseMode : 1; + UINT8 fSoutNaturalListenerEnhancement : 1; + UINT8 fRoutNoiseReduction : 1; + UINT8 fEnableMusicProtection : 1; + UINT8 fIdleCodeDetection : 1; + UINT8 byAnrVoiceNoiseSegregation : 1; + UINT8 byDoubleTalkBehavior : 1; + UINT8 fSoutNoiseBleaching : 1; + UINT8 fSoutConferencingNoiseReduction : 1; + UINT8 bySoutAutomaticListenerEnhancementGainDb : 1; + UINT8 byNonLinearityBehaviorA : 1; + UINT8 byNonLinearityBehaviorB : 1; + UINT8 bySoutNaturalListenerEnhancementGainDb : 1; + + OCT_INT8 chRinAutomaticLevelControlTargetDb; + OCT_INT8 chSoutAutomaticLevelControlTargetDb; + + OCT_INT8 chRinHighLevelCompensationThresholdDb; + + OCT_INT8 chRinLevelControlGainDb; + OCT_INT8 chSoutLevelControlGainDb; + + OCT_INT8 chDefaultErlDb; + OCT_INT8 chAecDefaultErlDb; + + OCT_INT8 chRoutNoiseReductionLevelGainDb; + OCT_INT8 chAnrSnrEnhancementDb; + + UINT16 usToneDisablerVqeActivationDelay; + UINT16 usAecTailLength; + + UINT16 usTailDisplacement; + UINT16 usTailLength; + +} tOCT6100_API_CHANNEL_VQE, *tPOCT6100_API_CHANNEL_VQE; + +typedef struct _OCT6100_API_CHANNEL_CODEC_ +{ + UINT8 byAdpcmNibblePosition : 1; + UINT8 fEnableSilenceSuppression : 1; + + UINT8 byEncoderPort : 1; + UINT8 byEncodingRate : 1; + + UINT8 byDecoderPort : 1; + UINT8 byDecodingRate : 1; + + UINT8 byPhase : 1; + UINT8 byPhasingType : 1; + +} tOCT6100_API_CHANNEL_CODEC, *tPOCT6100_API_CHANNEL_CODEC; + +typedef struct _OCT6100_API_CHANNEL_ +{ + /*=======================================================================*/ + /* Channel configuration. */ + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved : 1; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt : 1; + + /* Is this a bidirectionnal channel? */ + UINT8 fBiDirChannel : 1; + + /* Enable tone disabler? */ + UINT8 fEnableToneDisabler : 1; + + /* Current echo operation mode. */ + UINT8 byEchoOperationMode : 1; + + UINT8 byToneDisablerStatus : 1; + + UINT8 fMute : 1; + UINT8 fTap : 1; + UINT8 fBeingTapped : 1; + UINT8 fCopyEventCreated : 1; + + UINT8 fSoutBufPlaying : 1; + UINT8 fRinBufPlaying : 1; + + UINT8 fRinBufPlayoutNotifyOnStop : 1; + UINT8 fRinBufPlayoutRepeatUsed : 1; + + + UINT8 fSoutBufPlayoutNotifyOnStop : 1; + UINT8 fSoutBufPlayoutRepeatUsed : 1; + + UINT8 fRinHardStop : 1; + UINT8 fSoutHardStop : 1; + + UINT8 byRinPlayoutStopEventType : 1; + UINT8 bySoutPlayoutStopEventType : 1; + + UINT8 fRinBufAdded : 1; + UINT8 fSoutBufAdded : 1; + + UINT8 fBufPlayoutActive : 1; + + /* Enable extended tone detection. */ + UINT8 fEnableExtToneDetection : 1; + + /* State of the codec structure associated to this channel. */ + UINT8 fSinSoutCodecActive : 1; + UINT8 fRinRoutCodecActive : 1; + + /* TSI chariot memory entry for the Rin/Rout stream. */ + UINT16 usRinRoutTsiMemIndex; + + /* TSI chariot memory entry for the Sin/Sout stream. */ + UINT16 usSinSoutTsiMemIndex; + + /* Additional TSI entry used to temporarily store the SIN signal. */ + UINT16 usExtraSinTsiMemIndex; + UINT16 usExtraSinTsiDependencyCnt; + + /* Additional TSI entry used to temporarily store the RIN signal. */ + UINT16 usExtraRinTsiMemIndex; + UINT16 usExtraRinTsiDependencyCnt; + + /* Conversion chariot memory entry. */ + UINT16 usRinRoutConversionMemIndex; + UINT16 usSinSoutConversionMemIndex; + + /* TSST control memory entry. */ + UINT16 usRinTsstIndex; + UINT16 usSinTsstIndex; + UINT16 usRoutTsstIndex; + UINT16 usSoutTsstIndex; + + /* SSPX memory entry. */ + UINT16 usEchoMemIndex; + + /* Active mixer events count to test for last event. */ + UINT16 usMixerEventCnt; + + /* Copy events. */ + UINT16 usSinCopyEventIndex; + UINT16 usSoutCopyEventIndex; + + /* Silence events. */ + UINT16 usRinSilenceEventIndex; + UINT16 usSinSilenceEventIndex; + + /* TDM configuration. */ + tOCT6100_API_CHANNEL_TDM TdmConfig; + + /* VQE configuration. */ + tOCT6100_API_CHANNEL_VQE VqeConfig; + + /* Currently muted ports. */ + UINT16 usMutedPorts; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Statistics section. */ + + INT16 sComfortNoiseLevel; + + UINT16 usCurrentEchoDelay; + UINT16 usMaxEchoDelay; + + UINT16 usNumEchoPathChanges; + UINT16 usNumEchoPathChangesOfst; + + INT16 sCurrentERL; + INT16 sCurrentERLE; + + INT16 sMaxERL; + INT16 sMaxERLE; + + INT16 sRinLevel; + INT16 sSinLevel; + + INT16 sRinAppliedGain; + INT16 sSoutAppliedGain; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Bridge information. */ + + UINT16 usBridgeIndex; + + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + + UINT16 usFlexConfParticipantIndex; + UINT16 usTapBridgeIndex; + UINT16 usTapChanIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Buffer playout information. */ + + PTR_TYPE ulRinBufWritePtr; + PTR_TYPE ulRinBufSkipPtr; + PTR_TYPE ulSoutBufWritePtr; + PTR_TYPE ulSoutBufSkipPtr; + + /* User channel ID, transparently passed to the user. */ + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Copy events information. */ + + /* Number of copy events created. */ + UINT16 usCopyEventCnt; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Extended tone detection info. */ + + + UINT16 usExtToneChanIndex; + UINT16 usExtToneMixerIndex; + UINT16 usExtToneTsiIndex; + + /* Index of the phasing TSST */ + UINT16 usPhasingTsstIndex; + + /* Mode of operation of the channel based on the extended tone detection configuration. */ + PTR_TYPE ulExtToneChanMode; + + /*=======================================================================*/ + + /* Tone detection state. */ + /* This array is configured as follow. */ + /* Index 0 contain event 0 to 31 and Index 1 contains event 32 - 55 */ + PTR_TYPE ulLastSSToneDetected; + PTR_TYPE ulLastSSToneTimestamp; + + + PTR_TYPE ulRinUserBufPlayoutEventId; + PTR_TYPE ulSoutUserBufPlayoutEventId; + + UINT32 aulToneConf[2]; + UINT32 ulUserChanId; + /*=======================================================================*/ + + + /*=======================================================================*/ + + + /* Codec configuration. */ + tOCT6100_API_CHANNEL_CODEC CodecConfig; + +} tOCT6100_API_CHANNEL, *tPOCT6100_API_CHANNEL; + +typedef struct _OCT6100_API_BIDIR_CHANNEL_ +{ + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved : 1; + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt : 1; + +} tOCT6100_API_BIDIR_CHANNEL, *tPOCT6100_API_BIDIR_CHANNEL; + +#endif /* __OCT6100_CHANNEL_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h b/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h new file mode 100644 index 0000000..2691e10 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_channel_pub.h @@ -0,0 +1,547 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 84 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_PUB_H__ +#define __OCT6100_CHANNEL_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +/* Channel open structures. */ +typedef struct _OCT6100_CHANNEL_OPEN_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_OPEN_TDM, *tPOCT6100_CHANNEL_OPEN_TDM; + +typedef struct _OCT6100_CHANNEL_OPEN_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutNoiseBleaching; + BOOL fSoutConferencingNoiseReduction; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_OPEN_VQE, *tPOCT6100_CHANNEL_OPEN_VQE; + +typedef struct _OCT6100_CHANNEL_OPEN_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_OPEN_CODEC, *tPOCT6100_CHANNEL_OPEN_CODEC; + +typedef struct _OCT6100_CHANNEL_OPEN_ +{ + PUINT32 pulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_OPEN_TDM TdmConfig; + tOCT6100_CHANNEL_OPEN_VQE VqeConfig; + tOCT6100_CHANNEL_OPEN_CODEC CodecConfig; + + + +} tOCT6100_CHANNEL_OPEN, *tPOCT6100_CHANNEL_OPEN; + +/* Channel close structure. */ +typedef struct _OCT6100_CHANNEL_CLOSE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CHANNEL_CLOSE, *tPOCT6100_CHANNEL_CLOSE; + +/* Channel modify structures. */ +typedef struct _OCT6100_CHANNEL_MODIFY_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_MODIFY_TDM, *tPOCT6100_CHANNEL_MODIFY_TDM; + +typedef struct _OCT6100_CHANNEL_MODIFY_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + UINT32 ulComfortNoiseMode; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_MODIFY_VQE, *tPOCT6100_CHANNEL_MODIFY_VQE; + +typedef struct _OCT6100_CHANNEL_MODIFY_CODEC_ +{ + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_MODIFY_CODEC, *tPOCT6100_CHANNEL_MODIFY_CODEC; + +typedef struct _OCT6100_CHANNEL_MODIFY_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fApplyToAllChannels; + + BOOL fDisableToneDetection; + BOOL fStopBufferPlayout; + BOOL fRemoveConfBridgeParticipant; + BOOL fRemoveBroadcastTssts; + + BOOL fTdmConfigModified; /* TRUE/FALSE */ + BOOL fVqeConfigModified; /* TRUE/FALSE */ + BOOL fCodecConfigModified; /* TRUE/FALSE */ + + + tOCT6100_CHANNEL_MODIFY_TDM TdmConfig; + tOCT6100_CHANNEL_MODIFY_VQE VqeConfig; + tOCT6100_CHANNEL_MODIFY_CODEC CodecConfig; + +} tOCT6100_CHANNEL_MODIFY, *tPOCT6100_CHANNEL_MODIFY; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_ADD_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + +} tOCT6100_CHANNEL_BROADCAST_TSST_ADD, *tPOCT6100_CHANNEL_BROADCAST_TSST_ADD; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_REMOVE_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + + BOOL fRemoveAll; + +} tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE, *tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE; + +/* Channel open structures.*/ +typedef struct _OCT6100_CHANNEL_STATS_TDM_ +{ + UINT32 ulMaxBroadcastTssts; + UINT32 ulNumRoutBroadcastTssts; + BOOL fMoreRoutBroadcastTssts; + UINT32 ulNumSoutBroadcastTssts; + BOOL fMoreSoutBroadcastTssts; + + UINT32 ulSinNumTssts; + UINT32 ulSoutNumTssts; + UINT32 ulRinNumTssts; + UINT32 ulRoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + PUINT32 pulSoutBroadcastTimeslot; + PUINT32 pulSoutBroadcastStream; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + + PUINT32 pulRoutBroadcastTimeslot; + PUINT32 pulRoutBroadcastStream; + +} tOCT6100_CHANNEL_STATS_TDM, *tPOCT6100_CHANNEL_STATS_TDM; + +typedef struct _OCT6100_CHANNEL_STATS_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_STATS_VQE, *tPOCT6100_CHANNEL_STATS_VQE; + +typedef struct _OCT6100_CHANNEL_STATS_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_STATS_CODEC, *tPOCT6100_CHANNEL_STATS_CODEC; + +typedef struct _OCT6100_CHANNEL_STATS_ +{ + BOOL fResetStats; + + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + BOOL fEnableToneDisabler; + + UINT32 ulMutePortsMask; + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_STATS_TDM TdmConfig; + tOCT6100_CHANNEL_STATS_VQE VqeConfig; + tOCT6100_CHANNEL_STATS_CODEC CodecConfig; + + /* Real stats. */ + UINT32 ulNumEchoPathChanges; + UINT32 ulToneDisablerStatus; + + INT32 lCurrentERL; + INT32 lCurrentERLE; + UINT32 ulCurrentEchoDelay; + + INT32 lMaxERL; + INT32 lMaxERLE; + UINT32 ulMaxEchoDelay; + + INT32 lRinLevel; + INT32 lSinLevel; + INT32 lRinAppliedGain; + INT32 lSoutAppliedGain; + INT32 lComfortNoiseLevel; + + BOOL fEchoCancellerConverged; + BOOL fSinVoiceDetected; + + + +} tOCT6100_CHANNEL_STATS, *tPOCT6100_CHANNEL_STATS; + +typedef struct _OCT6100_CHANNEL_CREATE_BIDIR_ +{ + PUINT32 pulBiDirChannelHndl; + + UINT32 ulFirstChannelHndl; + UINT32 ulSecondChannelHndl; + + + +} tOCT6100_CHANNEL_CREATE_BIDIR, *tPOCT6100_CHANNEL_CREATE_BIDIR; + +typedef struct _OCT6100_CHANNEL_DESTROY_BIDIR_ +{ + UINT32 ulBiDirChannelHndl; + +} tOCT6100_CHANNEL_DESTROY_BIDIR, *tPOCT6100_CHANNEL_DESTROY_BIDIR; + +typedef struct _OCT6100_CHANNEL_MUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_MUTE, *tPOCT6100_CHANNEL_MUTE; + +typedef struct _OCT6100_CHANNEL_UNMUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_UNMUTE, *tPOCT6100_CHANNEL_UNMUTE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100ChannelOpenDef( + OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); +UINT32 Oct6100ChannelOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); + +UINT32 Oct6100ChannelCloseDef( + OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); +UINT32 Oct6100ChannelClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); + +UINT32 Oct6100ChannelModifyDef( + OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); +UINT32 Oct6100ChannelModify( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); + +UINT32 Oct6100ChannelBroadcastTsstAddDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); +UINT32 Oct6100ChannelBroadcastTsstAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); + +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); +UINT32 Oct6100ChannelBroadcastTsstRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); + +UINT32 Oct6100ChannelGetStatsDef( + OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); +UINT32 Oct6100ChannelGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); + +UINT32 Oct6100ChannelCreateBiDirDef( + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); +UINT32 Oct6100ChannelCreateBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); + +UINT32 Oct6100ChannelDestroyBiDirDef( + OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); +UINT32 Oct6100ChannelDestroyBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); + +UINT32 Oct6100ChannelMuteDef( + OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); +UINT32 Oct6100ChannelMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); + +UINT32 Oct6100ChannelUnMuteDef( + OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); +UINT32 Oct6100ChannelUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); + +#endif /* __OCT6100_CHANNEL_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h b/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h new file mode 100644 index 0000000..fdd2bd0 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_open_inst.h @@ -0,0 +1,515 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 122 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_INST_H__ +#define __OCT6100_CHIP_OPEN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_CONFIG_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; + UINT32 ulUpclkFreq; /* 33.33 or 66.66 MHz. */ + UINT8 fEnableMemClkOut; /* TRUE/FALSE */ + + UINT8 fMultiProcessSystem; + + UINT8 byMemoryType; /* SDRAM or DDR */ + UINT8 byNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT16 usMaxRwAccesses; + UINT16 usTailDisplacement; + + /* Resource allocation parameters. */ + UINT16 usMaxChannels; + UINT16 usMaxBiDirChannels; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + + UINT8 byMaxTdmStreams; + UINT8 byTdmSampling; + + UINT8 fEnableFastH100Mode; + UINT8 fEnableAcousticEcho; /* Acoustic echo enabled. */ + + UINT16 ausTimestampTimeslots[ 4 ]; + UINT16 ausTimestampStreams[ 4 ]; + + UINT8 fUseSynchTimestamp; + + /* Debug feature used to record stream information from a channel.*/ + UINT8 fEnableChannelRecording; + + UINT16 usMaxRemoteDebugSessions; + + UINT8 byInterruptPolarity; + + UINT16 usMaxTsiCncts; + + UINT8 fEnableExtToneDetection; + UINT8 fEnable2100StopEvent; + + + UINT16 usMaxConfBridges; + UINT16 usMaxFlexibleConfParticipants; + UINT16 usMaxPlayoutBuffers; + + /* Playout event software buffer size. */ + UINT32 ulSoftBufPlayoutEventsBufSize; + + /* Soft buffer size. */ + UINT32 ulSoftToneEventsBufSize; + + UINT16 usMaxPhasingTssts; + UINT16 usMaxAdpcmChannels; + + + + + + UINT8 fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_API_CHIP_CONFIG, *tPOCT6100_API_CHIP_CONFIG; + + +typedef struct _OCT6100_API_MISCELLANEOUS_ +{ + /* Total size of external memories. */ + UINT32 ulTotalMemSize; + + UINT32 ulH100SlaveMode; + + /* Mclk frequency generated by the chip. */ + UINT32 ulMclkFreq; + + /* Array of UINT32s used to perform a burst of writes (avoids having to + allocate on the stack. The size of this array MUST NOT CHANGE (it's + used everywhere). */ + UINT16 ausSuperArray[ cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ]; + + /* Chip ID and revision.*/ + UINT16 usChipId; + UINT16 usChipRevision; + + /* Lsu CPU access variables.*/ + UINT16 usCpuLsuWritePtr; + UINT16 usCodepoint; + + /* Max number of channel supported.*/ + UINT16 usMaxNumberOfChannels; + UINT16 usMaxH100Speed; + UINT16 usTdmClkBoundary; + + UINT16 usNumBridgesOpened; + UINT16 usFirstBridge; + + + + + +} tOCT6100_API_MISCELLANEOUS, *tPOCT6100_API_MISCELLANEOUS; + +typedef struct _OCT6100_API_MEMORY_MAP_ +{ + /*-----------------------------------------------------------------------------*/ + /* Structure contained in external memory. */ + + /* Memory mapping filled using TLV information from the chip. */ + + /* Main channel memory. */ + UINT32 ulChanMainMemBase; + UINT32 ulChanMainMemSize; + + UINT32 ulChanMainIoMemOfst; + + UINT32 ulChanMainRinCBMemOfst; + UINT32 ulChanMainRinCBMemSize; + UINT32 ulChanMainSinCBMemOfst; + UINT32 ulChanMainSinCBMemSize; + UINT32 ulChanMainSoutCBMemOfst; + UINT32 ulChanMainSoutCBMemSize; + + /* Free memory base address. */ + UINT32 ulFreeMemBaseAddress; + + /* Root channel config offset. */ + UINT32 ulChanRootConfOfst; + + /* Playout buffer info. */ + UINT32 ulChanMainRinPlayoutMemOfst; + UINT32 ulChanMainRinPlayoutMemSize; + UINT32 ulChanMainSoutPlayoutMemOfst; + UINT32 ulChanMainSoutPlayoutMemSize; + + /* Channel Stats location */ + UINT32 ulChanMainIoStatsOfst; + UINT32 ulChanMainIoStatsSize; + + /* Buffer playout fields. */ + tOCT6100_TLV_OFFSET PlayoutRinWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutRinSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutSoutSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinHardSkipOfst; + tOCT6100_TLV_OFFSET PlayoutSoutHardSkipOfst; + + /* Adaptive noise reduction. */ + tOCT6100_TLV_OFFSET AdaptiveNoiseReductionOfst; + + /* DC offset removal. */ + tOCT6100_TLV_OFFSET RinDcOffsetRemovalOfst; + tOCT6100_TLV_OFFSET SinDcOffsetRemovalOfst; + + /* Level control. */ + tOCT6100_TLV_OFFSET RinLevelControlOfst; + tOCT6100_TLV_OFFSET SoutLevelControlOfst; + + /* Auto level control. */ + tOCT6100_TLV_OFFSET RinAutoLevelControlTargetOfst; + tOCT6100_TLV_OFFSET SoutAutoLevelControlTargetOfst; + + /* High level compensation. */ + tOCT6100_TLV_OFFSET RinHighLevelCompensationThresholdOfst; + tOCT6100_TLV_OFFSET SoutHighLevelCompensationThresholdOfst; + + /* Auto level control and high level compensation status. */ + tOCT6100_TLV_OFFSET AlcHlcStatusOfst; + + /* Confort Noise Mode. */ + tOCT6100_TLV_OFFSET ComfortNoiseModeOfst; + + /* NLP control field. */ + tOCT6100_TLV_OFFSET NlpControlFieldOfst; + + /* VAD control field offset.*/ + tOCT6100_TLV_OFFSET VadControlFieldOfst; + + /* NLP Trivial field offset. */ + tOCT6100_TLV_OFFSET NlpTrivialFieldOfst; + + /* Acoustic echo field offset. */ + tOCT6100_TLV_OFFSET AecFieldOfst; + + /* Acoustic echo default ERL field offset. */ + tOCT6100_TLV_OFFSET AecDefaultErlFieldOfst; + + /* Non-linearity behavior A and B field offset. */ + tOCT6100_TLV_OFFSET PcmLeakFieldOfst; + tOCT6100_TLV_OFFSET NlpConvCapFieldOfst; + + /* Default ERL field offset. */ + tOCT6100_TLV_OFFSET DefaultErlFieldOfst; + + /* Tone Removal field offset.*/ + tOCT6100_TLV_OFFSET ToneRemovalFieldOfst; + + + + /* Channel config fields offset. */ + tOCT6100_TLV_OFFSET ChanMainIoMaxEchoPointOfst; + tOCT6100_TLV_OFFSET TailDisplEnableOfst; + + /* Pouch fields offset. */ + tOCT6100_TLV_OFFSET PouchBootInstructionOfst; + tOCT6100_TLV_OFFSET PouchBootResultOfst; + tOCT6100_TLV_OFFSET PouchTailDisplOfst; + + /* 2100 Hz Auto disabling fields offset. */ + tOCT6100_TLV_OFFSET ToneDisablerControlOfst; + + /* Conferencing dominant speaker field offset. */ + tOCT6100_TLV_OFFSET DominantSpeakerFieldOfst; + + /* Conferencing noise reduction field offset. */ + tOCT6100_TLV_OFFSET ConferencingNoiseReductionOfst; + + /* Per channel tail displacement field offset. */ + tOCT6100_TLV_OFFSET PerChanTailDisplacementFieldOfst; + + /* Per channel tail length field offset. */ + tOCT6100_TLV_OFFSET PerChanTailLengthFieldOfst; + + /* AF control/echo cancellation bypass. */ + tOCT6100_TLV_OFFSET AftControlOfst; + + /* Voice detected stat field offset. */ + tOCT6100_TLV_OFFSET SinVoiceDetectedStatOfst; + + /* Rin currently applied gain field offset. */ + tOCT6100_TLV_OFFSET RinAppliedGainStatOfst; + + /* Sout currently applied gain field offset. */ + tOCT6100_TLV_OFFSET SoutAppliedGainStatOfst; + + /* Adaptive listener enhancement field offset. */ + tOCT6100_TLV_OFFSET AdaptiveAleOfst; + + /* Rin NR field offset. */ + tOCT6100_TLV_OFFSET RinAnrOfst; + + /* Rin NR value field offset. */ + tOCT6100_TLV_OFFSET RinAnrValOfst; + + /* Sin Mute field offset. */ + tOCT6100_TLV_OFFSET SinMuteOfst; + + /* Rin Mute field offset. */ + tOCT6100_TLV_OFFSET RinMuteOfst; + + /* Sout ANR SNR enhancement offset. */ + tOCT6100_TLV_OFFSET AnrSnrEnhancementOfst; + + /* Sout ANR voice-noise segregation offset. */ + tOCT6100_TLV_OFFSET AnrVoiceNoiseSegregationOfst; + + /* Tone disabler VQE activation delay offset. */ + tOCT6100_TLV_OFFSET ToneDisablerVqeActivationDelayOfst; + + /* AF tail displacement value configuration offset. */ + tOCT6100_TLV_OFFSET AfTailDisplacementFieldOfst; + + /* Pouch counter field offset. */ + tOCT6100_TLV_OFFSET PouchCounterFieldOfst; + + /* Acoustic echo tail length. */ + tOCT6100_TLV_OFFSET AecTailLengthFieldOfst; + + /* Is ISR called field offset. */ + tOCT6100_TLV_OFFSET IsIsrCalledFieldOfst; + + /* Music protection enable field offset. */ + tOCT6100_TLV_OFFSET MusicProtectionFieldOfst; + + /* Rin port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET RinEnergyStatFieldOfst; + + /* Sout port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET SoutEnergyStatFieldOfst; + + /* Double talk behavior field offset. */ + tOCT6100_TLV_OFFSET DoubleTalkBehaviorFieldOfst; + + /* Idle code detection field offset. */ + tOCT6100_TLV_OFFSET IdleCodeDetectionFieldOfst; + + /* TSI memory mapping information.*/ + UINT32 ulNumTsiEntries; + + /*-----------------------------------------------------------------------------*/ + +} tOCT6100_API_MEMORY_MAP, *tPOCT6100_API_MEMORY_MAP; + +typedef struct _OCT6100_API_SOFT_BUFS_ +{ + /* To avoid compilation errors. */ + UINT32 ulDummyVariable; + + /* Tone events buffer pointers. */ + UINT32 ulToneEventBufferWritePtr; + UINT32 ulToneEventBufferReadPtr; + UINT32 ulToneEventBufferSize; + UINT32 ulToneEventBufferMemOfst; + UINT32 ulToneEventBufferOverflowCnt; + + /* Playout events buffer pointers. */ + UINT32 ulBufPlayoutEventBufferWritePtr; + UINT32 ulBufPlayoutEventBufferReadPtr; + UINT32 ulBufPlayoutEventBufferSize; + UINT32 ulBufPlayoutEventBufferMemOfst; + UINT32 ulBufPlayoutEventBufferOverflowCnt; + +} tOCT6100_API_SOFT_BUFS, *tPOCT6100_API_SOFT_BUFS; + +typedef struct _OCT6100_API_IMAGE_REGION_ +{ + UINT32 ulPart1Size; + UINT32 ulPart2Size; + UINT32 ulClockInfo; + + UINT32 ulReserved; + + UINT32 ulPart1BaseAddress; + UINT32 ulPart2BaseAddress; + +} tOCT6100_API_IMAGE_REGION, *tPOCT6100_API_IMAGE_REGION; + +typedef struct _OCT6100_API_IMAGE_INFO_ +{ + UINT8 fBufferPlayout; + UINT8 fAdaptiveNoiseReduction; + UINT8 fRinDcOffsetRemoval; + UINT8 fSinDcOffsetRemoval; + + UINT8 fRinAutoLevelControl; + UINT8 fSoutAutoLevelControl; + UINT8 fRinHighLevelCompensation; + UINT8 fSoutHighLevelCompensation; + + UINT8 fAlcHlcStatus; + UINT8 fComfortNoise; + UINT8 fNlpControl; + UINT8 fSilenceSuppression; + + UINT8 fToneDisabler; + UINT8 fTailDisplacement; + UINT8 fPerChannelTailDisplacement; + UINT8 fAcousticEcho; + + UINT8 fAecEnabled; + UINT8 fToneRemoval; + UINT8 fDefaultErl; + UINT8 fMaxEchoPoint; + + UINT8 fNonLinearityBehaviorA; + UINT8 fNonLinearityBehaviorB; + UINT8 fAecDefaultErl; + UINT8 fAdpcm; + + UINT8 fConferencing; + UINT8 fConferencingNoiseReduction; + UINT8 fMusicProtection; + UINT8 fDominantSpeakerEnabled; + + UINT8 fAftControl; + UINT8 fSinVoiceDetectedStat; + UINT8 fRinAppliedGainStat; + UINT8 fSoutAppliedGainStat; + + UINT8 fListenerEnhancement; + UINT8 fRoutNoiseReduction; + UINT8 fRoutNoiseReductionLevel; + UINT8 fRinMute; + UINT8 fSinMute; + + UINT8 fAnrSnrEnhancement; + UINT8 fAnrVoiceNoiseSegregation; + UINT8 fRinBufferPlayoutHardSkip; + UINT8 fSoutBufferPlayoutHardSkip; + + UINT16 usMaxNumberOfChannels; + UINT8 fPerChannelTailLength; + UINT8 fToneDisablerVqeActivationDelay; + + UINT32 ulToneProfileNumber; + + UINT16 usMaxTailDisplacement; + UINT16 usMaxTailLength; + + UINT8 byNumToneDetectors; + UINT8 byMaxNumberPlayoutEvents; + + UINT8 fAfTailDisplacement; + UINT8 fAecTailLength; + + UINT8 fMusicProtectionConfiguration; + UINT8 byImageType; + + UINT8 fBufferPlayoutSkipInEvents; + UINT8 fSoutNoiseBleaching; + + UINT8 fRinEnergyStat; + UINT8 fSoutEnergyStat; + + UINT8 fDoubleTalkBehavior; + UINT8 fDoubleTalkBehaviorFieldOfst; + + UINT8 fIdleCodeDetection; + UINT8 fIdleCodeDetectionConfiguration; + + UINT8 fSinLevel; + + + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_TLV_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_API_IMAGE_INFO, *tPOCT6100_API_IMAGE_INFO; + +typedef struct _OCT6100_API_MIXER_ +{ + /* Pointer to the various event region. */ + UINT16 usFirstSoutCopyEventPtr; + UINT16 usLastSoutCopyEventPtr; + + UINT16 usFirstBridgeEventPtr; + UINT16 usLastBridgeEventPtr; + + UINT16 usFirstSinCopyEventPtr; + UINT16 usLastSinCopyEventPtr; + + /* Recording event info. */ + UINT16 usRecordCopyEventIndex; + UINT16 usRecordSinEventIndex; + +} tOCT6100_API_MIXER, tPOCT6100_API_MIXER; + + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO_ +{ + /* Next node to be checked for free memory. */ + UINT32 ulRovingNode; + + /* First unused node in the unused list. */ + UINT32 ulFirstUnusedNode; + + /* Last unused node in the unused list. */ + UINT32 ulLastUnusedNode; + + /* Count of unused nodes. */ + UINT32 ulUnusedNodeCnt; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO; + + + + +#endif /* __OCT6100_CHIP_OPEN_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h b/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h new file mode 100644 index 0000000..7153106 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_open_pub.h @@ -0,0 +1,241 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 54 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_PUB_H__ +#define __OCT6100_CHIP_OPEN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_OPEN_ +{ + UINT32 ulUserChipId; + BOOL fMultiProcessSystem; + PVOID pProcessContext; + + UINT32 ulMaxRwAccesses; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; /* 10 - 133.3 MHz. */ + UINT32 ulUpclkFreq; /* 1 - 66.6 MHz. */ + BOOL fEnableMemClkOut; + + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + UINT32 ulNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT32 ulTailDisplacement; /* Tail displacement supported by the chip. */ + + BOOL fEnableAcousticEcho;/* Acoustic echo cancellation enabled. */ + + /* Resource allocation parameters. */ + UINT32 ulMaxChannels; + UINT32 ulMaxTsiCncts; + UINT32 ulMaxBiDirChannels; + UINT32 ulMaxConfBridges; + UINT32 ulMaxFlexibleConfParticipants; + UINT32 ulMaxPlayoutBuffers; + + + UINT32 ulMaxPhasingTssts; + UINT32 ulMaxAdpcmChannels; + BOOL fUseSynchTimestamp; + UINT32 aulTimestampTimeslots[ 4 ]; + UINT32 aulTimestampStreams[ 4 ]; + UINT32 ulInterruptPolarity; + tOCT6100_INTERRUPT_CONFIGURE InterruptConfig; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + UINT32 ulMaxTdmStreams; + UINT32 ulTdmSampling; + + BOOL fEnableFastH100Mode; + + UINT32 ulSoftToneEventsBufSize; /* In events. */ + BOOL fEnableExtToneDetection; + BOOL fEnable2100StopEvent; + + + UINT32 ulSoftBufferPlayoutEventsBufSize; /* In events. */ + UINT32 ulMaxRemoteDebugSessions; + + BOOL fEnableChannelRecording; + + BOOL fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_CHIP_OPEN, *tPOCT6100_CHIP_OPEN; + +typedef struct _OCT6100_GET_INSTANCE_SIZE_ +{ + UINT32 ulApiInstanceSize; + +} tOCT6100_GET_INSTANCE_SIZE, *tPOCT6100_GET_INSTANCE_SIZE; + +typedef struct _OCT6100_CHIP_CLOSE_ +{ + UINT32 ulDummyVariable; + +} tOCT6100_CHIP_CLOSE, *tPOCT6100_CHIP_CLOSE; + +typedef struct _OCT6100_CREATE_LOCAL_INSTANCE_ +{ + tPOCT6100_INSTANCE_API pApiInstShared; + tPOCT6100_INSTANCE_API pApiInstLocal; + PVOID pProcessContext; + UINT32 ulUserChipId; + +} tOCT6100_CREATE_LOCAL_INSTANCE, *tPOCT6100_CREATE_LOCAL_INSTANCE; + +typedef struct _OCT6100_DESTROY_LOCAL_INSTANCE_ +{ + UINT32 ulDummy; + +} tOCT6100_DESTROY_LOCAL_INSTANCE, *tPOCT6100_DESTROY_LOCAL_INSTANCE; + +typedef struct _OCT6100_GET_HW_REVISION_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulRevisionNum; + +} tOCT6100_GET_HW_REVISION, *tPOCT6100_GET_HW_REVISION; + +typedef struct _OCT6100_FREE_RESOURCES_ +{ + BOOL fFreeTsiConnections; + BOOL fFreeConferenceBridges; + BOOL fFreePlayoutBuffers; + BOOL fFreePhasingTssts; + BOOL fFreeAdpcmChannels; + +} tOCT6100_FREE_RESOURCES, *tPOCT6100_FREE_RESOURCES; + +typedef struct _OCT6100_PRODUCTION_BIST_ +{ + UINT32 ulCurrentAddress; + UINT32 ulCurrentLoop; + UINT32 ulCurrentTest; + UINT32 ulBistStatus; + UINT32 ulFailedAddress; + UINT32 ulReadValue; + UINT32 ulExpectedValue; + +} tOCT6100_PRODUCTION_BIST, *tPOCT6100_PRODUCTION_BIST; + +typedef struct _OCT6100_API_GET_VERSION_ +{ + UINT8 achApiVersion[ cOCT6100_API_VERSION_STRING_LENGTH ]; + +} tOCT6100_API_GET_VERSION, *tPOCT6100_API_GET_VERSION; + +typedef struct _OCT6100_API_GET_CAPACITY_PINS_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + BOOL fEnableMemClkOut; + UINT32 ulMemClkFreq; + UINT32 ulCapacityValue; +} tOCT6100_API_GET_CAPACITY_PINS, *tPOCT6100_API_GET_CAPACITY_PINS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipOpenDef( + OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); +UINT32 Oct6100ChipOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); + +UINT32 Oct6100ChipCloseDef( + OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); +UINT32 Oct6100ChipClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); + +UINT32 Oct6100GetInstanceSizeDef( + OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); +UINT32 Oct6100GetInstanceSize( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + IN OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); + +UINT32 Oct6100CreateLocalInstanceDef( + OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); +UINT32 Oct6100CreateLocalInstance( + IN OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); + +UINT32 Oct6100DestroyLocalInstanceDef( + OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); +UINT32 Oct6100DestroyLocalInstance( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); + +UINT32 Oct6100ApiGetVersionDef( + OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); +UINT32 Oct6100ApiGetVersion( + IN OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); + +UINT32 Oct6100GetHwRevisionDef( + OUT tPOCT6100_GET_HW_REVISION f_pRevision ); +UINT32 Oct6100GetHwRevision( + IN OUT tPOCT6100_GET_HW_REVISION f_pRevision ); + +UINT32 Oct6100FreeResourcesDef( + OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); +UINT32 Oct6100FreeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); + +UINT32 Oct6100ProductionBistDef( + OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); +UINT32 Oct6100ProductionBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); + +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins); + +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + + +#endif /* __OCT6100_CHIP_OPEN_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h new file mode 100644 index 0000000..bcba616 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_inst.h @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_INST_H__ +#define __OCT6100_CHIP_STATS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_ERROR_STATS_ +{ + UINT8 fFatalChipError; + + UINT32 ulInternalReadTimeoutCnt; + UINT32 ulSdramRefreshTooLateCnt; + UINT32 ulPllJitterErrorCnt; + + /* Internal tone detector error counter. */ + UINT32 ulToneDetectorErrorCnt; + + UINT32 ulOverflowToneEventsCnt; + + UINT32 ulH100OutOfSyncCnt; + UINT32 ulH100ClkABadCnt; + UINT32 ulH100ClkBBadCnt; + UINT32 ulH100FrameABadCnt; + + + +} tOCT6100_API_CHIP_ERROR_STATS, *tPOCT6100_API_CHIP_ERROR_STATS; + +typedef struct _OCT6100_API_CHIP_STATS_ +{ + UINT16 usNumberChannels; + UINT16 usNumberBiDirChannels; + UINT16 usNumberTsiCncts; + UINT16 usNumberConfBridges; + UINT16 usNumberPlayoutBuffers; + UINT16 usNumEcChanUsingMixer; + + UINT32 ulPlayoutMemUsed; + UINT16 usNumberActiveBufPlayoutPorts; + + UINT16 usNumberPhasingTssts; + UINT16 usNumberAdpcmChans; + +} tOCT6100_API_CHIP_STATS, *tPOCT6100_API_CHIP_STATS; + +#endif /* __OCT6100_CHIP_STATS_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h new file mode 100644 index 0000000..a718f7b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_chip_stats_pub.h @@ -0,0 +1,150 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 59 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_PUB_H__ +#define __OCT6100_CHIP_STATS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_STATS_ +{ + BOOL fResetChipStats; + + UINT32 ulNumberChannels; + UINT32 ulNumberTsiCncts; + UINT32 ulNumberConfBridges; + UINT32 ulNumberPlayoutBuffers; + UINT32 ulPlayoutFreeMemSize; + UINT32 ulNumberPhasingTssts; + UINT32 ulNumberAdpcmChannels; + + UINT32 ulH100OutOfSynchCount; + UINT32 ulH100ClockABadCount; + UINT32 ulH100FrameABadCount; + UINT32 ulH100ClockBBadCount; + + UINT32 ulInternalReadTimeoutCount; + UINT32 ulSdramRefreshTooLateCount; + UINT32 ulPllJitterErrorCount; + + UINT32 ulOverflowToneEventsCount; + UINT32 ulSoftOverflowToneEventsCount; + + UINT32 ulSoftOverflowBufferPlayoutEventsCount; + +} tOCT6100_CHIP_STATS, *tPOCT6100_CHIP_STATS; + +typedef struct _OCT6100_CHIP_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + +} tOCT6100_CHIP_TONE_INFO, *tPOCT6100_CHIP_TONE_INFO; + +typedef struct _OCT6100_CHIP_IMAGE_INFO_ +{ + BOOL fBufferPlayout; + BOOL fAdaptiveNoiseReduction; + BOOL fSoutNoiseBleaching; + BOOL fAutoLevelControl; + BOOL fHighLevelCompensation; + BOOL fSilenceSuppression; + + BOOL fAdpcm; + BOOL fConferencing; + BOOL fConferencingNoiseReduction; + BOOL fDominantSpeaker; + + BOOL fAcousticEcho; + BOOL fAecTailLength; + BOOL fToneRemoval; + + BOOL fDefaultErl; + BOOL fNonLinearityBehaviorA; + BOOL fNonLinearityBehaviorB; + BOOL fPerChannelTailDisplacement; + BOOL fPerChannelTailLength; + BOOL fListenerEnhancement; + BOOL fRoutNoiseReduction; + BOOL fRoutNoiseReductionLevel; + BOOL fAnrSnrEnhancement; + BOOL fAnrVoiceNoiseSegregation; + BOOL fToneDisablerVqeActivationDelay; + BOOL fMusicProtection; + BOOL fDoubleTalkBehavior; + BOOL fIdleCodeDetection; + BOOL fSinLevel; + + UINT32 ulMaxChannels; + UINT32 ulNumTonesAvailable; + UINT32 ulToneProfileNumber; + UINT32 ulMaxTailDisplacement; + UINT32 ulMaxTailLength; + UINT32 ulDebugEventSize; + UINT32 ulMaxPlayoutEvents; + + UINT32 ulImageType; + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_CHIP_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_CHIP_IMAGE_INFO, *tPOCT6100_CHIP_IMAGE_INFO; + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipGetStatsDef( + OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetImageInfoDef( + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +UINT32 Oct6100ChipGetImageInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +#endif /* __OCT6100_CHIP_STATS_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h new file mode 100644 index 0000000..f49a473 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h @@ -0,0 +1,104 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 19 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_INST_H__ +#define __OCT6100_CONF_BRIDGE_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CONF_BRIDGE_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Entry counter for the resources. */ + UINT8 byEntryOpenCnt; + + /* Next bridge pointer. */ + UINT16 usNextBridgePtr; + + /* Previous bridge pointer. */ + UINT16 usPrevBridgePtr; + + /* Number of clients connected to the bridge. */ + UINT16 usNumClients; + + /* Store the index of the load event, to diffentiate him form the accumulate. */ + UINT16 usLoadIndex; + + /* Pointer to the first bridge events.*/ + UINT16 usFirstLoadEventPtr; + UINT16 usFirstSubStoreEventPtr; + UINT16 usLastSubStoreEventPtr; + + /* Pointer to the silence load event, if it exists. */ + UINT16 usSilenceLoadEventPtr; + + /* Flag specifying whether the dominant speaker is set or not. */ + UINT16 usDominantSpeakerChanIndex; + UINT8 fDominantSpeakerSet; + + /* Flag specifying if this is flexible conferencing bridge. */ + UINT8 fFlexibleConferencing; + + /* Number of clients being tapped. */ + UINT16 usNumTappedClients; + +} tOCT6100_API_CONF_BRIDGE, *tPOCT6100_API_CONF_BRIDGE; + +typedef struct _OCT6100_API_FLEX_CONF_PARTICIPANT_ +{ + /* Input port of the conferencing for this participant. */ + UINT32 ulInputPort; + + /* Whether the flexible mixer has been created. */ + UINT8 fFlexibleMixerCreated; + + /* Listener mask ( who can hear us ). */ + UINT32 ulListenerMask; + + /* Our index in the listener mask. */ + UINT32 ulListenerMaskIndex; + + /* Mixer event indexes for this participant's mixer. */ + UINT16 ausLoadOrAccumulateEventIndex[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + +} tOCT6100_API_FLEX_CONF_PARTICIPANT, *tPOCT6100_API_FLEX_CONF_PARTICIPANT; + +#endif /* __OCT6100_CONF_BRIDGE_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h new file mode 100644 index 0000000..4ecea7b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h @@ -0,0 +1,169 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_PUB_H__ +#define __OCT6100_CONF_BRIDGE_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CONF_BRIDGE_OPEN_ +{ + PUINT32 pulConfBridgeHndl; /* Handle returned when the bridge is opened. */ + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_OPEN, *tPOCT6100_CONF_BRIDGE_OPEN; + +typedef struct _OCT6100_CONF_BRIDGE_CLOSE_ +{ + UINT32 ulConfBridgeHndl; + +} tOCT6100_CONF_BRIDGE_CLOSE, *tPOCT6100_CONF_BRIDGE_CLOSE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_ADD_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + UINT32 ulInputPort; + UINT32 ulListenerMaskIndex; + UINT32 ulListenerMask; + BOOL fMute; + UINT32 ulTappedChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_ADD, *tPOCT6100_CONF_BRIDGE_CHAN_ADD; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_REMOVE_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + BOOL fRemoveAll; + +} tOCT6100_CONF_BRIDGE_CHAN_REMOVE, *tPOCT6100_CONF_BRIDGE_CHAN_REMOVE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_MUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_MUTE, *tPOCT6100_CONF_BRIDGE_CHAN_MUTE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_UNMUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_UNMUTE, *tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE; + +typedef struct _OCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET, *tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET; + +typedef struct _OCT6100_CONF_BRIDGE_MASK_CHANGE_ +{ + UINT32 ulChannelHndl; + UINT32 ulNewListenerMask; + +} tOCT6100_CONF_BRIDGE_MASK_CHANGE, *tPOCT6100_CONF_BRIDGE_MASK_CHANGE; + +typedef struct _OCT6100_CONF_BRIDGE_STATS_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulNumChannels; + UINT32 ulNumTappedChannels; + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_STATS, *tPOCT6100_CONF_BRIDGE_STATS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ConfBridgeOpenDef( + OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); +UINT32 Oct6100ConfBridgeOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ConfBridgeCloseDef( + OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); +UINT32 Oct6100ConfBridgeClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); + +UINT32 Oct6100ConfBridgeChanAddDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); +UINT32 Oct6100ConfBridgeChanAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); + +UINT32 Oct6100ConfBridgeChanRemoveDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); +UINT32 Oct6100ConfBridgeChanRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); + +UINT32 Oct6100ConfBridgeChanMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); +UINT32 Oct6100ConfBridgeChanMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); + +UINT32 Oct6100ConfBridgeChanUnMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); +UINT32 Oct6100ConfBridgeChanUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); + +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); + +UINT32 Oct6100ConfBridgeMaskChangeDef( + OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); +UINT32 Oct6100ConfBridgeMaskChange( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); + +UINT32 Oct6100ConfBridgeGetStatsDef( + OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); +UINT32 Oct6100ConfBridgeGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); + +#endif /* __OCT6100_CONF_BRIDGE_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h b/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h new file mode 100644 index 0000000..6a6f573 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_debug_inst.h @@ -0,0 +1,124 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_INST_H__ +#define __OCT6100_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_DEBUG_ +{ + /* Information from the TLVs. */ + UINT32 ulDebugEventSize; + UINT32 ulMatrixBaseAddress; + UINT32 ulDebugChanStatsByteSize; + UINT32 ulDebugChanLiteStatsByteSize; + UINT32 ulHotChannelSelectBaseAddress; + UINT32 ulMatrixTimestampBaseAddress; + UINT32 ulAfWritePtrByteOffset; + UINT32 ulRecordedPcmEventByteSize; + UINT32 ulMatrixWpBaseAddress; + + /* Pouch counter presence in the image. */ + UINT8 fPouchCounter; + + /* Record channel indexes. */ + UINT16 usRecordMemIndex; + UINT16 usRecordChanIndex; + + UINT16 usRecordRinRoutTsiMemIndex; + UINT16 usRecordSinSoutTsiMemIndex; + + /* Debug channel information.*/ + UINT16 usCurrentDebugChanIndex; + + /* Matrix event mask. */ + UINT16 usMatrixCBMask; + + /* If data is being dumped now. */ + UINT8 fDebugDataBeingDumped; + + /* Index of the last event retrieved. */ + UINT16 usLastDebugEventIndex; + + /* Number of events to retrieve. */ + UINT16 usNumEvents; + + /* Chip debug event write ptr. */ + UINT16 usChipDebugEventWritePtr; + + /* Hot channel read data. */ + UINT16 ausHotChannelData[ 2 ]; + + /* Last PCM sample index. */ + UINT32 ulLastPcmSampleIndex; + + /* Last AF log read pointer. */ + UINT16 usLastAfLogReadPtr; + + /* AF log hardware write pointer. */ + UINT16 usAfLogWritePtr; + + /* Last tone event index retrieved. */ + UINT16 usLastToneEventIndex; + + /* Whether the image version string has been copied in the user buffer. */ + BOOL fImageVersionCopied; + + /* Whether the api version string has been copied in the user buffer. */ + BOOL fApiVersionCopied; + + /* Total number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataTotalNumBytes; + + /* Field to detect if the ISR is called present? */ + BOOL fIsIsrCalledField; + + /* Remaining number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataRemainingNumBytes; + + /* AF events control block size. */ + UINT32 ulAfEventCbByteSize; + + /* Current user selected data mode. Must be kept constant throughout a debug session. */ + UINT32 ulCurrentGetDataMode; + +} tOCT6100_API_DEBUG, *tPOCT6100_API_DEBUG; + +#endif /* __OCT6100_DEBUG_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h b/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h new file mode 100644 index 0000000..097ecc6 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_debug_pub.h @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_PUB_H__ +#define __OCT6100_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_DEBUG_SELECT_CHANNEL_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_DEBUG_SELECT_CHANNEL, *tPOCT6100_DEBUG_SELECT_CHANNEL; + +typedef struct _OCT6100_DEBUG_GET_DATA_ +{ + UINT32 ulGetDataMode; + UINT32 ulGetDataContent; + UINT32 ulRemainingNumBytes; + UINT32 ulTotalNumBytes; + UINT32 ulMaxBytes; + UINT32 ulValidNumBytes; + PUINT8 pbyData; + +} tOCT6100_DEBUG_GET_DATA, *tPOCT6100_DEBUG_GET_DATA; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100DebugSelectChannelDef( + OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); +UINT32 Oct6100DebugSelectChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); + +UINT32 Oct6100DebugGetDataDef( + OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); +UINT32 Oct6100DebugGetData( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); + +#endif /* __OCT6100_DEBUG_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_defines.h b/xpp/oct612x/include/oct6100api/oct6100_defines.h new file mode 100644 index 0000000..ef12119 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_defines.h @@ -0,0 +1,679 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_defines.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.7 + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 171 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEFINES_H__ +#define __OCT6100_DEFINES_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +/* 32-bits values. */ +#define cOCT6100_FFFFFFFF 0xFFFFFFFF +#define cOCT6100_FFFFFFFE 0xFFFFFFFE +#define cOCT6100_7FFFFFFF 0x7FFFFFFF + +/* 16-bits values. */ +#define cOCT6100_FFFD 0xFFFD +#define cOCT6100_FFFE 0xFFFE +#define cOCT6100_FFFF 0xFFFF +#define cOCT6100_7FFF 0x7FFF + +/* 8-bits values. */ +#define cOCT6100_FF 0xFF + +#define cOCT6100_CURRENT_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_CHIP_ID cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_HANDLE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_TIMESLOT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STREAM cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT_W cOCT6100_FFFF +#define cOCT6100_INVALID_PCM_LAW cOCT6100_FF +#define cOCT6100_INVALID_EVENT cOCT6100_FFFF +#define cOCT6100_INVALID_INDEX cOCT6100_FFFF +#define cOCT6100_INVALID_TONE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_PORT cOCT6100_FF + +#define cOCT6100_AUTO_SELECT cOCT6100_FFFFFFFE +#define cOCT6100_AUTO_SELECT_TAIL cOCT6100_FFFE + +#define cOCT6100_INVALID_BOOL 2 + +#define cOCT6100_KEEP_PREVIOUS_SETTING 0x70100000 + +#define cOCT6100_INVALID_SIGNED_STAT cOCT6100_7FFFFFFF +#define cOCT6100_INVALID_SIGNED_STAT_W cOCT6100_7FFF +#define cOCT6100_INVALID_ECHO_DELAY 0x400 + + + +#define cOCT6100_SIZE_128 128 +#define cOCT6100_SIZE_256 256 +#define cOCT6100_SIZE_512 512 +#define cOCT6100_SIZE_1K 1024 +#define cOCT6100_SIZE_2K 2048 +#define cOCT6100_SIZE_4K 4096 +#define cOCT6100_SIZE_8K 8192 +#define cOCT6100_SIZE_16K 16384 +#define cOCT6100_SIZE_32K 32768 +#define cOCT6100_SIZE_64K 65536 +#define cOCT6100_SIZE_128K 131072 +#define cOCT6100_SIZE_256K 262144 +#define cOCT6100_SIZE_512K 524288 +#define cOCT6100_SIZE_1M 1048576 +#define cOCT6100_SIZE_2M 2097152 +#define cOCT6100_SIZE_4M 4194304 +#define cOCT6100_SIZE_8M 8388608 +#define cOCT6100_SIZE_16M 16777216 +#define cOCT6100_SIZE_32M 33554432 +#define cOCT6100_SIZE_64M 67108864 +#define cOCT6100_SIZE_128M 134217728 +#define cOCT6100_SIZE_256M 268435456 +#define cOCT6100_SIZE_512M 536870912 +#define cOCT6100_SIZE_1G 1073741824 +#define cOCT6100_SIZE_2G 2147483648 + +#define cOCT6100_HNDL_TAG_MASK 0xFF000000 +#define cOCT6100_HNDL_INDEX_MASK 0x0000FFFF +#define cOCT6100_ENTRY_OPEN_CNT_MASK 0x000000FF +#define cOCT6100_ENTRY_OPEN_CNT_SHIFT 16 + +#define cOCT6100_HNDL_TAG_INVALID 0xFF000000 + +#define cOCT6100_HNDL_TAG_CHANNEL 0x01000000 +#define cOCT6100_HNDL_TAG_TSI_CNCT 0x02000000 +#define cOCT6100_HNDL_TAG_CONF_BRIDGE 0x03000000 +#define cOCT6100_HNDL_TAG_PHASING_TSST 0x04000000 +#define cOCT6100_HNDL_TAG_BIDIR_CHANNEL 0x05000000 +#define cOCT6100_HNDL_TAG_COPY_EVENT 0x06000000 +#define cOCT6100_HNDL_TAG_ADPCM_CHANNEL 0x07000000 + +#define cOCT6100_INVALID_HANDLE_TYPE cOCT6100_INVALID_VALUE + +#define cOCT6100_MEMORY_ROUND_SIZE 16 + +#define mOCT6100_ROUND_MEMORY_SIZE( ulMemorySize, ulTempVar ) \ + if ((ulTempVar = ulMemorySize % cOCT6100_MEMORY_ROUND_SIZE) != 0) \ + ulMemorySize += cOCT6100_MEMORY_ROUND_SIZE - ulTempVar; + +#define mOCT6100_ROUND_ADDRESS( ulAddress, ulBoundary, ulTempVar ) \ + if ((ulTempVar = ulAddress % ulBoundary) != 0) \ + ulAddress += ulBoundary - ulTempVar; + +#define cOCT6100_INTERNAL_CLOCK_SOURCE 0 +#define cOCT6100_EXTERNAL_CLOCK_SOURCE 1 + +#define cOCT6100_ACTIVE_HIGH_POLARITY 0 +#define cOCT6100_ACTIVE_LOW_POLARITY 1 + +#define cOCT6100_TDM_SAMPLE_AT_3_QUARTERS 0 +#define cOCT6100_TDM_SAMPLE_AT_RISING_EDGE 1 +#define cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE 2 + +#define cOCT6100_TDM_STREAM_FREQ_2MHZ 0 +#define cOCT6100_TDM_STREAM_FREQ_4MHZ 1 +#define cOCT6100_TDM_STREAM_FREQ_8MHZ 2 +#define cOCT6100_TDM_STREAM_FREQ_16MHZ 3 + +#define cOCT6100_TDM_STREAM_MAX_GROUPS 8 + +#define cOCT6100_PCM_U_LAW 0 +#define cOCT6100_PCM_A_LAW 1 +#define cOCT6100_PCM_UNCHANGED 2 +#define cOCT6100_ADPCM_ENCODED 3 + +#define cOCT6100_INTERRUPT_DISABLE 0 +#define cOCT6100_INTERRUPT_NO_TIMEOUT 1 +#define cOCT6100_INTERRUPT_TIMEOUT 2 + +#define cOCT6100_NUMBER_TSSTS_1 1 +#define cOCT6100_NUMBER_TSSTS_2 2 + +#define cOCT6100_G711_64KBPS 1 +#define cOCT6100_G726_40KBPS 2 +#define cOCT6100_G726_32KBPS 3 +#define cOCT6100_G726_24KBPS 4 +#define cOCT6100_G726_16KBPS 5 +#define cOCT6100_G727_40KBPS_4_1 6 +#define cOCT6100_G727_40KBPS_3_2 7 +#define cOCT6100_G727_40KBPS_2_3 8 +#define cOCT6100_G727_32KBPS_4_0 9 +#define cOCT6100_G727_32KBPS_3_1 10 +#define cOCT6100_G727_32KBPS_2_2 11 +#define cOCT6100_G727_24KBPS_3_0 12 +#define cOCT6100_G727_24KBPS_2_1 13 +#define cOCT6100_G727_16KBPS_2_0 14 +#define cOCT6100_G726_ENCODED 15 +#define cOCT6100_G711_G726_ENCODED 16 +#define cOCT6100_G711_G727_2C_ENCODED 17 +#define cOCT6100_G711_G727_3C_ENCODED 18 +#define cOCT6100_G711_G727_4C_ENCODED 19 +#define cOCT6100_G727_2C_ENCODED 20 +#define cOCT6100_G727_3C_ENCODED 21 +#define cOCT6100_G727_4C_ENCODED 22 + +#define cOCT6100_ADPCM_IN_HIGH_BITS 0 +#define cOCT6100_ADPCM_IN_LOW_BITS 1 + +/* The values of these defines must not change. */ +#define cOCT6100_H100_TRACKA 0 +#define cOCT6100_H100_TRACKB 1 +#define cOCT6100_H100_TRACKA_FALLBACKB 2 +#define cOCT6100_H100_TRACKB_FALLBACKA 3 +#define cOCT6100_H100_DISABLED 4 +#define cOCT6100_H100_MASTERA 5 +#define cOCT6100_H100_BACKUPA 6 +#define cOCT6100_H100_MASTERB 7 +#define cOCT6100_H100_BACKUPB 8 + +#define cOCT6100_FREE_TSST 0 +#define cOCT6100_RX_TSST 16 +#define cOCT6100_TX_TSST 32 + +#define cOCT6100_INTRPT_ACTIVE 0 +#define cOCT6100_INTRPT_WILL_TIMEOUT 1 +#define cOCT6100_INTRPT_IN_TIMEOUT 2 +#define cOCT6100_INTRPT_DISABLED 3 + +#define cOCT6100_EXTERNAL_MEM_BIST_TIMEOUT 1000000 + +/* Clocks defines */ +#define cOCT6100_UPCLK_FREQ_33_33_MHZ 33333333 + +#define cOCT6100_MCLK_FREQ_133_MHZ 133000000 +#define cOCT6100_MCLK_FREQ_125_MHZ 125000000 +#define cOCT6100_MCLK_FREQ_117_MHZ 117000000 +#define cOCT6100_MCLK_FREQ_108_MHZ 108000000 +#define cOCT6100_MCLK_FREQ_100_MHZ 100000000 +#define cOCT6100_MCLK_FREQ_92_MHZ 92000000 +#define cOCT6100_MCLK_FREQ_83_MHZ 83000000 +#define cOCT6100_MCLK_FREQ_75_MHZ 75000000 + +/* Tone buffer defines.*/ +#define cOCT6100_MAX_NUM_TONE_BUFFERS 1344 +#define cOCT6100_MAX_TONES_PER_CALL 32 + +/* Memory defines.*/ +#define cOCT6100_MEM_TYPE_SDR 0 +#define cOCT6100_MEM_TYPE_DDR 1 +#define cOCT6100_MEM_TYPE_SDR_PLL_BYPASS 2 + +#define cOCT6100_MEMORY_CHIP_SIZE_8MB cOCT6100_SIZE_8M +#define cOCT6100_MEMORY_CHIP_SIZE_16MB cOCT6100_SIZE_16M +#define cOCT6100_MEMORY_CHIP_SIZE_32MB cOCT6100_SIZE_32M +#define cOCT6100_MEMORY_CHIP_SIZE_64MB cOCT6100_SIZE_64M +#define cOCT6100_MEMORY_CHIP_SIZE_128MB cOCT6100_SIZE_128M + +#define cOCT6100_MAX_NUM_MEMORY_CHIP 2 + +#define cOCT6100_16MB_MEMORY_BANKS 0 +#define cOCT6100_32MB_MEMORY_BANKS 1 +#define cOCT6100_64MB_MEMORY_BANKS 2 +#define cOCT6100_128MB_MEMORY_BANKS 3 + +#define cOCT6100_1_MEMORY_BANKS 0 +#define cOCT6100_2_MEMORY_BANKS 1 +#define cOCT6100_3_MEMORY_BANKS 2 +#define cOCT6100_4_MEMORY_BANKS 3 + +/* Chip open defines.*/ +#define cOCT6100_INTERNAL_TONE_ARRAY_SIZE 256 /* in words.*/ +#ifndef cOCT6100_INTERNAL_SUPER_ARRAY_SIZE +#define cOCT6100_INTERNAL_SUPER_ARRAY_SIZE 128 /* in words.*/ +#endif + +/* Internal memory mapping.*/ + +/*=======================================================================*/ +#define cOCT6100_TSST_CONTROL_MEM_BASE 0x26000 + +#define cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE 2 /* Each entries are 2 bytes.*/ +#define cOCT6100_TSST_CONTROL_MEM_INPUT_TSST 0x0800 +#define cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST 0x2000 + +#define cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET 12 +#define cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET 11 +#define cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET 12 + +#define cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +#define cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY 1344 +#define cOCT6100_TSST_CONTROL_TIMESTAMP_BASE_ENTRY 1516 + +/*=======================================================================*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_BASE 0x28000 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_CONVERSION_CONTROL_MEM_ENCODER 0x0000 +#define cOCT6100_CONVERSION_CONTROL_MEM_DECODER 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR 0x8000 + +#define cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET 12 +#define cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET 9 +#define cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET 11 +#define cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET 8 +#define cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET 8 + +#define cOCT6100_CONVERSION_CONTROL_PHASE_SIZE_BASE_ADD 0x5400 + +/*=======================================================================*/ +#define cOCT6100_MIXER_CONTROL_MEM_BASE 0x28008 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_MIXER_CONTROL_MEM_SUB_STORE 0xA000 +#define cOCT6100_MIXER_CONTROL_MEM_STORE 0x8000 +#define cOCT6100_MIXER_CONTROL_MEM_LOAD 0x4000 +#define cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE 0x6000 +#define cOCT6100_MIXER_CONTROL_MEM_COPY 0x2000 +#define cOCT6100_MIXER_CONTROL_MEM_NO_OP 0x0000 + +#define cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET 11 + +#define cOCT6100_MIXER_HEAD_NODE 0 +#define cOCT6100_MIXER_TAIL_NODE 1 +#define cOCT6100_MIXER_RECORD_COPY_NODE 2 + +/*=======================================================================*/ +#define cOCT6100_ECHO_CONTROL_MEM_BASE 0x14000 + +#define cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE 4 /* Each entries are 8 bytes.*/ +#define cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL 0x2000 + +#define cOCT6100_ECHO_CONTROL_MEM_DEBUG_OFFSET 14 +#define cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL 14 +#define cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET 12 +#define cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET 11 + +#define cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +/*=======================================================================*/ +#define cOCT6100_ST_CONTROL_MEM_BASE 0x2000000 + +#define cOCT6100_ST_CONTROL_MEM_ENTRY_SIZE 16 /* Each entries are 8 bytes.*/ + +/*=======================================================================*/ +#define cOCT6100_PART1_BASE 0x00080000 +#define cOCT6100_PART1_CPU_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E3C0 /* 8 * 8 = 64 bytes */ +#define cOCT6100_PART1_HW_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E400 /* 8 * 128 = 1K byte */ +#define cOCT6100_PART1_END_STATICS_BASE cOCT6100_PART1_BASE+0x0000E9F0 /* 912 bytes available for your viewing pleasure. */ +#define cOCT6100_PART1_API_SCRATCH_PAD cOCT6100_PART1_END_STATICS_BASE+4+(12*8) +#define cOCT6100_PART1_EGO_REG cOCT6100_PART1_BASE+0x0007FF00 + +/* External Memory mapping. */ +#define cOCT6100_EXTERNAL_MEM_BLOCK_SIZE 1024 +#define cOCT6100_EXTERNAL_MEM_BASE_ADDRESS 0x08000000 + + +#define cOCT6100_TLV_BASE ( 0x00016000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_CHANNEL_ROOT_BASE ( 0x00020000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_PGSP_EVENT_OUT_BASE ( 0x002C0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_POUCH_BASE ( 0x002E0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_IMAGE_FILE_BASE ( 0x00300000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) + +#define cOCT6100_CHANNEL_ROOT_SIZE 4096 +#define cOCT6100_CHANNEL_ROOT_TOTAL_SIZE ( 672 * cOCT6100_CHANNEL_ROOT_SIZE ) +#define cOCT6100_PGSP_EVENT_OUT_SIZE 131072 +#define cOCT6100_PGSP_TONE_EVENT_SIZE 0x40 +#define cOCT6100_IMAGE_FILE_SIZE 0x100000 + +#define cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD cOCT6100_POUCH_BASE + 0x8 +#define cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD cOCT6100_POUCH_BASE + 0x14 +#define cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD cOCT6100_POUCH_BASE + 0x4 +#define cOCT6100_MATRIX_PLL_JITTER_COUNT_ADD cOCT6100_POUCH_BASE + 0x1C +#define cOCT6100_MATRIX_DWORD_BASE cOCT6100_POUCH_BASE + 0xE0000 + +#define cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET 0x0000 + +#define cOCT6100_NUM_WORDS_PER_TONE_EVENT 32 +#define cOCT6100_NUM_PGSP_EVENT_OUT 2048 /* CPTAG: Must not be modified, represents number of events stored in hardware. */ +#define cOCT6100_VALID_TONE_EVENT 0x8000 +#define cOCT6100_LOCAL_TIMESTAMP_INCREMENT 32 /* 4 ms increment. */ +#define cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT 65535 +#define cOCT6100_MIN_TIMESLOT_FOR_TIMESTAMP 5 + + +/*=======================================================================*/ +#define cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET 0x0C +#define cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET 0x10 +#define cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x14 +#define cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x18 +#define cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET 0x1C + +#define cOCT6100_GSC_BUFFER_LAW_OFFSET 27 + +/*=======================================================================*/ +#define cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET 0x00000 +#define cOCT6100_CH_MAIN_TONE_EVENT_OFFSET 0x00488 + +/*=======================================================================*/ +#define cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET 31 +#define cOCT6100_PLAYOUT_EVENT_LAW_OFFSET 30 +#define cOCT6100_PLAYOUT_EVENT_MIX_OFFSET 28 +#define cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET 27 +#define cOCT6100_PLAYOUT_EVENT_GAIN_OFFSET 24 + +#define cOCT6100_PLAYOUT_EVENT_MEM_SIZE 16 + +/* Image related defines.*/ +#define cOCT6100_MIN_IMAGE_SIZE 0x001000 +#define cOCT6100_MAX_IMAGE_SIZE 0x100000 +#define cOCT6100_MAX_IMAGE_REGION 60 +#define cOCT6100_IMAGE_AF_CST_OFFSET 0x1000; + +/* Max defines.*/ +#ifndef cOCT6100_MAX_ECHO_CHANNELS +#define cOCT6100_MAX_ECHO_CHANNELS 128 +#endif +#define cOCT6100_MAX_TSI_CNCTS 1530 +#define cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ( 3328 + 6 ) +#define cOCT6100_MAX_PLAYOUT_BUFFERS ( 1344 + cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ) +#define cOCT6100_MAX_CONF_BRIDGE 672 +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS cOCT6100_MAX_ECHO_CHANNELS +#define cOCT6100_MAX_PHASING_TSST 16 +#define cOCT6100_MAX_ADPCM_CHANNELS 672 + +#define cOCT6100_NUM_TSI_B4_PHASING 1344 +#define cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY 1534 +#define cOCT6100_MAX_TSI_CONTROL_MEM_ENTRY 1344 +#define cOCT6100_MAX_ECHO_CONTROL_MEM_ENTRY 672 +#define cOCT6100_MAX_TSI_B4_TIMESTAMP 172 +#define cOCT6100_TSI_MEM_FOR_TIMESTAMP 4 +#define cOCT6100_API_EXT_TONE_EXTRA_TSI 1533 + +/* Echo channel ports */ +#define cOCT6100_CHANNEL_PORT_RIN 0 +#define cOCT6100_CHANNEL_PORT_ROUT 1 +#define cOCT6100_CHANNEL_PORT_SIN 2 +#define cOCT6100_CHANNEL_PORT_SOUT 3 +#define cOCT6100_CHANNEL_PORT_ROUT_SOUT 4 + +#define cOCT6100_NO_ENCODING 10 +#define cOCT6100_NO_DECODING 11 + +/* Buffer playout defines */ +#define cOCT6100_NO_SKIP 0 +#define cOCT6100_BUFFER_PLAYOUT_MIN_SIZE 1024 +#define cOCT6100_DEFAULT_TIMESTAMP 0 +#define cOCT6100_MIXING_0_DB 0 +#define cOCT6100_MIXING_MINUS_6_DB 1 +#define cOCT6100_MIXING_MINUS_12_DB 2 +#define cOCT6100_MIXING_MUTE 3 +#define cOCT6100_PLAYOUT_GAIN 0x41000000 +#define cOCT6100_PLAYOUT_EVENT 1 +#define cOCT6100_MINIMUM_BUFFER_SIZE 64 +#define cOCT6100_BUFFER_SIZE_GRANULARITY 16 +#define cOCT6100_REPEAT_INFINITELY cOCT6100_INVALID_VALUE +#define cOCT6100_REPEAT_MAX 32767 +#define cOCT6100_SAMPLES_PER_MS 8 + +/* For the playout events. */ +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT_PER_CALL 32 +#define cOCT6100_MIN_BUFFER_PLAYOUT_EVENT 128 +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT 65535 +/* Event types */ +#define cOCT6100_BUFFER_PLAYOUT_EVENT_INVALID cOCT6100_INVALID_VALUE +#define cOCT6100_BUFFER_PLAYOUT_EVENT_STOP 1 + + +/* Phasing defines.*/ +#define cOCT6100_SINGLE_PHASING 0 +#define cOCT6100_DUAL_PHASING 1 +#define cOCT6100_NO_PHASING 2 + +/* Echo canceller mode.*/ +#define cOCT6100_ELECTRIC_EC 0 +#define cOCT6100_ELECTRIC_EC_DISPLACEMENT 1 +#define cOCT6100_ACCOUSTIC_ES 2 + +/* Echo control modes.*/ +#define cOCT6100_ECHO_OP_MODE_NORMAL 0 +#define cOCT6100_ECHO_OP_MODE_HT_FREEZE 1 +#define cOCT6100_ECHO_OP_MODE_HT_RESET 2 +#define cOCT6100_ECHO_OP_MODE_POWER_DOWN 3 +#define cOCT6100_ECHO_OP_MODE_EXTERNAL 4 +#define cOCT6100_ECHO_OP_MODE_NO_ECHO 5 +#define cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION 6 +#define cOCT6100_ECHO_OP_MODE_G169_ALC cOCT6100_ECHO_OP_MODE_NO_ECHO + +/* 2100 Hz disabling configuration. */ +#define cOCT6100_NEVER_DISABLED 0 +#define cOCT6100_G164_2100_HZ 1 +#define cOCT6100_G165_2100_HZ_WITH_PHASE_REV 2 + +/* TSST defines.*/ +#define cOCT6100_UNASSIGNED cOCT6100_FFFD + +#define cOCT6100_MAX_TSSTS (cOCT6100_MAX_ECHO_CHANNELS*4) /* cOCT6100_MAX_ECHO_CHANNELS channels, 4 TSSTs per channel. */ +#define cOCT6100_TWO_TSSTS_INDEX_MASK 0x8000 +#define cOCT6100_TSST_INDEX_MASK 0x7FFF +#define cOCT6100_INPUT_TSST 0 +#define cOCT6100_OUTPUT_TSST 1 + +/* Conference bridges defines.*/ +/* CPTAG: No application needs for mixer events. */ +/* 2 needed for head and tail nodes. 2 more needed to get through channel modify function. */ +/* Careful. This value cannot be zero. */ +#ifndef cOCT6100_MAX_MIXER_EVENTS +#define cOCT6100_MAX_MIXER_EVENTS 4 +#endif +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE 32 +#define cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED 672 +#define cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL cOCT6100_FFFFFFFE + +/* Conversion memory defines.*/ +#define cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS (cOCT6100_MAX_ECHO_CHANNELS*2) /* CPTAG: Max this out to the expected max number of channels * 2, was 1344 */ + +/* Tone detection defines.*/ +#define cOCT6100_MAX_TONE_NUMBER 55 + +/* Register definition and address. */ +#define cOCT6100_TONE_EVENT_WRITE_PTR_REG 0x722 +#define cOCT6100_TONE_EVENT_READ_PTR_REG 0x720 + +/* Special Signaling tone IDs. */ +#define cOCT6100_TONE_SIN_SYSTEM7_2000 0x20000023 +#define cOCT6100_TONE_SIN_SYSTEM7_1780 0x20000024 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON 0x10000000 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR 0x10000002 +#define cOCT6100_TONE_ROUT_G168_1100GB_ON 0x10000004 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A 0x10000005 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B 0x10000006 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE 0x10000008 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON 0x40000000 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR 0x40000002 +#define cOCT6100_TONE_SOUT_G168_1100GB_ON 0x40000004 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A 0x40000005 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B 0x40000006 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE 0x40000008 +#define cOCT6100_TONE_SIN_SYSTEM5_2400 0x20000020 +#define cOCT6100_TONE_SIN_SYSTEM5_2600 0x20000021 +#define cOCT6100_TONE_SIN_SYSTEM5_2400_2600 0x20000022 + +#define cOCT6100_CHIP_ID_REVISION_REG 0x17E + +/* BOOT type. */ +#define cOCT6100_AF_BOOT_TYPE 0x5 +#define cOCT6100_PRODUCTION_BOOT_TYPE 0x7 +#define cOCT6100_PRODUCTION_SHORT_BOOT_TYPE 0x8 + +/*Production Bist Modes*/ +#define cOCT6100_PRODUCTION_BIST_STANDARD 0x0 +#define cOCT6100_PRODUCTION_BIST_SHORT 0x1 + +/* Interrupt register masks.*/ +#define cOCT6100_INTRPT_MASK_REG_102H 0x0001 +#define cOCT6100_INTRPT_MASK_REG_202H 0x1C01 +#define cOCT6100_INTRPT_MASK_REG_302H 0xF100 +#define cOCT6100_INTRPT_MASK_REG_502H 0x0002 +#define cOCT6100_INTRPT_MASK_REG_702H 0x0002 + +#define cOCT6100_DECODER_MEMORY_OFFSET 672 + +/* Debug defines.*/ +#define cOCT6100_DEBUG_MAX_READ_LENGTH 10240 +#define cOCT6100_DEBUG_SOUT_MAX_READ_LENGTH 2560 +#define cOCT6100_DEBUG_CHAN_RECORD_INDEX 64 +#define cOCT6100_DEBUG_RECORD_BUFFER_BYTE_SIZE 0x20000 +#define cOCT6100_DEBUG_RECORD_MATRIX_SIZE 0x8000 +#define cOCT6100_DEBUG_RECORD_READ_DATA_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_RECORD_BLOCK_BYTE_SIZE 0x1000 + +/* Tone event defines.*/ +#define cOCT6100_MAX_TONE_EVENT 56 +#define cOCT6100_TONE_PRESENT 0 +#define cOCT6100_TONE_STOP 1 +#define cOCT6100_TONE_REFRESH 2 + +/* TLV defines.*/ +#define cOCT6100_TLV_MAX_ADDRESS 0x10000000 +#define cOCT6100_TLV_MAX_TONE_NAME_SIZE 64 + +#define cOCT6100_VERSION_NUMBER_MAX_SIZE 1016 + +/* Echo Tail defines.*/ +#define cOCT6100_TAIL_LENGTH_32MS 32 +#define cOCT6100_TAIL_LENGTH_64MS 64 +#define cOCT6100_TAIL_LENGTH_128MS 128 +#define cOCT6100_MAX_ECHO_TAIL_DISPLACEMENT 5600 /* In milliseconds */ + + + + + +/* Generic loop counter.*/ +#define cOCT6100_MAX_LOOP 0x2000 +/* CPU boot timeout counter. */ +#define cOCT6100_MAX_LOOP_CPU_TIMEOUT 0x20000 + +/* Automatic level control */ +#define cOCT6100_PASS_THROUGH_LEVEL_CONTROL 0x90 + +/* Channel stats debug info */ +#define cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE 720 + +/* Image start string define */ +#define cOCT6100_IMAGE_START_STRING "EDS3_IMAGE_NAME" + +/* Tone image info defines.*/ +#define cOCT6100_TONE_INFO_START_STRING "[ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_STOP_STRING "[~ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_EVENT_STRING "TONEEVENT=0x" + +#define cOCT6100_MAX_NLP_CONF_DWORD 20 + +/* Tail displacement info.*/ +#define cOCT6100_MAX_TAIL_DISPLACEMENT 896 + +/* Comfort noise define */ +#define cOCT6100_COMFORT_NOISE_NORMAL 0x0 +#define cOCT6100_COMFORT_NOISE_EXTENDED 0x3 +#define cOCT6100_COMFORT_NOISE_OFF 0x2 +#define cOCT6100_COMFORT_NOISE_FAST_LATCH 0x1 + +/* Mixer event type.*/ +#define cOCT6100_EVENT_TYPE_SOUT_COPY 0x0 +#define cOCT6100_EVENT_TYPE_SIN_COPY 0x1 + +/* Tone disabler status.*/ +#define cOCT6100_TONE_DISABLER_EC_ENABLED 0 +#define cOCT6100_TONE_DISABLER_EC_DISABLED 1 + +/* ADPCM Channel defines */ +#define cOCT6100_ADPCM_ENCODING 0 +#define cOCT6100_ADPCM_DECODING 1 + +/* Double talk behavior modes. */ +#define cOCT6100_DOUBLE_TALK_BEH_NORMAL 0x0 +#define cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE 0x1 + +/* Api Version string length.*/ +#define cOCT6100_API_VERSION_STRING_LENGTH 32 + +/* Extended tone detection information. */ +#define cOCT6100_API_EXT_TONE_DISABLED 0 +#define cOCT6100_API_EXT_TONE_SIN_PORT_MODE 1 +#define cOCT6100_API_EXT_TONE_RIN_PORT_MODE 2 + + + +/* Mute/UnMute defines. */ +#define cOCT6100_CHANNEL_MUTE_PORT_NONE 0x00 +#define cOCT6100_CHANNEL_MUTE_PORT_RIN 0x01 +#define cOCT6100_CHANNEL_MUTE_PORT_ROUT 0x02 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN 0x04 +#define cOCT6100_CHANNEL_MUTE_PORT_SOUT 0x08 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES 0x10 + +/* Debug get data dump modes. */ +#define cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE 0x0 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE 0x1 +#define cOCT6100_DEBUG_GET_DATA_MODE_16S 0x2 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S 0x3 + +/* Debug get data dump content. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE 0x0 /* Full binary dump to be sent for support. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM 0x1 /* Only Rin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM 0x2 /* Only Sin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM 0x3 /* Only Sout PCM stream data. */ + + + +#define cOCT6100_BIST_IN_PROGRESS 0x0 +#define cOCT6100_BIST_CONFIGURATION_FAILED 0x1 +#define cOCT6100_BIST_STATUS_CRC_FAILED 0x2 +#define cOCT6100_BIST_MEMORY_FAILED 0x3 +#define cOCT6100_BIST_SUCCESS 0x4 + +/* Image types. */ +#define cOCT6100_IMAGE_TYPE_WIRELINE 0x0 +#define cOCT6100_IMAGE_TYPE_COMBINED 0x1 + +/* Fatal general error types. */ +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_1 0x0001 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_2 0x0002 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_3 0x0004 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_4 0x0008 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_5 0x0010 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_6 0x0020 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_7 0x0040 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_8 0x0080 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_9 0x0100 + +#endif /* __OCT6100_DEFINES_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_errors.h b/xpp/oct612x/include/oct6100api/oct6100_errors.h new file mode 100644 index 0000000..a123762 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_errors.h @@ -0,0 +1,838 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_errors.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used for error codes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 205 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ERRORS_H__ +#define __OCT6100_ERRORS_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +#define cOCT6100_ERR_OK 0x00000000 +#define cOCT6100_ERR_BASE 0x00100000 + +#define cOCT6100_NOT_SUPPORTED_BASE (0xFF000 + cOCT6100_ERR_BASE) + +/* Not supported defines. */ +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD (0x00000 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL (0x00001 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE (0x00002 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM (0x00003 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM (0x00004 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC (0x00005 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC (0x00006 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR (0x00007 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT (0x00008 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING (0x00009 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING (0x0000A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION (0x0000B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO (0x0000C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL (0x0000D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK (0x0000E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B (0x0000F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL (0x00010 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP (0x00011 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL (0x00012 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP (0x00013 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO (0x00014 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE (0x00015 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE (0x00016 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE (0x00017 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE (0x00018 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR (0x00019 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES (0x0001A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT (0x0001B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION (0x0001C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP (0x0001D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH (0x0001E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x0001F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x00020 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION (0x00021 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S (0x00022 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE (0x00023 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE (0x00024 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION (0x00025 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG (0x00026 + cOCT6100_NOT_SUPPORTED_BASE) + + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x0002B + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT (0x00100 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR (0x00101 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE (0x00102 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CALLER_ID (0x00104 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING (0x00105 + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL (0x00300 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOMINANT_SPEAKER (0x00301 + cOCT6100_NOT_SUPPORTED_BASE) + + + +#define cOCT6100_ERR_OPEN_INVALID_DEVICE (0x03000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY (0x03001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE (0x03002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_UP_CLK_FREQ (0x03003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_CHIP_ID (0x03004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM (0x03005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_RW_ACCESSES (0x03006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_SIZE (0x03007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_FILE (0x03008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEM_CLK_FREQ (0x03009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER (0x0300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE (0x0300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP (0x0300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_STREAM (0x0300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TIMESLOT (0x0300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TSSTS (0x0300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_STREAM_FREQS (0x03010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_SAMPLING (0x03011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FAST_H100_MODE (0x03012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS (0x03013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS (0x03014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TSI_CNCTS (0x03015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS (0x03016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED (0x03017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_TIMEOUT (0x03018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SDRAM_BIST_FAILED (0x03019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CORRUPTED_IMAGE (0x0301A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR (0x0301B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE (0x0301C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERRUPT_POLARITY (0x0301D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG (0x0301E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS (0x0301F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT (0x03020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TDM_STREAM (0x03021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES (0x03022 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT (0x03024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_TYPE (0x03025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG (0x03026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG (0x03027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG (0x03028 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_CONFIG (0x03029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT (0x0302A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT (0x0302B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0302C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT (0x0302D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED (0x0302E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CRC_ERROR (0x0302F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EGO_TIMEOUT (0x03030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_DEBUG_EVENT_BUF_SIZE (0x03031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_START_TAG_NOT_FOUND (0x03032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND (0x03033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_EVENT (0x03034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_NAME (0x03035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_EVENT_NUMBER_SIZE (0x03036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST (0x03037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT (0x03038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING (0x03039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS (0x0303A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED (0x0303C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS (0x0303E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION (0x03040 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE (0x03041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS (0x03042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO (0x03043 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED (0x03045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED (0x03046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED (0x03047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS (0x03048 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX (0x03051 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_CALLER_ID (0x03052 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CALLER_ID_PLAYOUT_BUFFERS (0x03053 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST (0x03055 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_ACTIVATED (0x03056 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS (0x03057 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED (0x03058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED (0x03059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR (0x0305A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TLV_LENGTH (0x0305B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE (0x0305C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT (0x03060 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE (0x03081 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE (0x03082 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSI_CNCT_ALL_CHANNELS_ARE_OPENED (0x04000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_DISABLED (0x04001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE (0x04002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_TIMESLOT (0x04003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_STREAM (0x04004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_TIMESLOT (0x04005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_STREAM (0x04006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_PCM_LAW (0x04007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TIMESLOT (0x04008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_STREAM (0x04009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TSST_RESERVED (0x0400A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NOT_OPEN (0x0400B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_ASSOCIATED_TSST_RESERVED (0x0400C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NO_MORE_TSI_AVAILABLE (0x0400D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED (0x05000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN (0x05001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL (0x05002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW (0x05003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN (0x05004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE (0x05005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX (0x05006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN (0x05007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES (0x05008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID (0x05009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN (0x0500A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ROUT_PORT_PLAYING (0x0500B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_SOUT_PORT_PLAYING (0x0500C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PORT_INVALID (0x0500D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT (0x0500E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL (0x0500F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT (0x05010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING (0x05011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY (0x05012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED (0x05013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_WRITE_BYTE_COUNT (0x05015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE (0x05016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID (0x05017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID (0x05018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET (0x05019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY (0x0501A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT (0x0501B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED (0x0501C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP (0x0501D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE (0x0501E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE (0x0501F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED (0x05020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED (0x05021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_ZERO (0x05022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NO_MEMORY (0x05023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_POINT_NOT_FOUND (0x05024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT (0x05025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB (0x05026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY (0x05027 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MEMORY_ALL_TSI_MEM_ENTRY_RESERVED (0x06000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_ECHO_MEM_ENTRY_RESERVED (0x06002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_EXTERNAL_MEMORY_FULL (0x06003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_CONVERSION_MEM_ENTRY_RESERVED (0x06004 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CHANNEL_DISABLED (0x07000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_HANDLE (0x07001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS (0x07002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS (0x07003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS (0x07004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS (0x07005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT (0x07006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM (0x07007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT (0x07008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM (0x07009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT (0x0700A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM (0x0700B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT (0x0700C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM (0x0700D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MISSING_TSST (0x07012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE (0x07013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TYPE (0x07014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE (0x07015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN (0x07016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE (0x07017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEBUG (0x07018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE (0x0701F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM (0x07020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM (0x07021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL (0x07022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL (0x07023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN (0x07024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN (0x07025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION (0x07026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED (0x07027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NOT_OPEN (0x07029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE (0x0702A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_PORT (0x0702B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT (0x0702C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM (0x0702D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_INVALID (0x0702E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_PCM_LAW (0x0702F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_PCM_LAW (0x07030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW (0x07031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW (0x07032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODER_PORT (0x07033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODER_PORT (0x07034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODING_RATE (0x07035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODING_RATE (0x07036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_NLP (0x07037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE (0x07038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED (0x07039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT (0x0703A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG (0x0703B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG (0x0703C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG (0x0703D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_RIN_PORT_INVALID (0x0703E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_SIN_PORT_INVALID (0x0703F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT (0x07041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT (0x07042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM (0x07043 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST (0x07044 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST (0x07045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT (0x07046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM (0x07047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT (0x07048 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM (0x07049 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES (0x0704A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE (0x0704B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH (0x07053 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT (0x07054 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE (0x07058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST (0x07059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION (0x0705A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STATS_RESET (0x0705B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT (0x0705C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE (0x0705E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE (0x0705F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE (0x07060 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED (0x07061 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALREADY_BIDIR (0x07062 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED (0x07063 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT (0x07064 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT (0x07065 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT (0x07066 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT (0x07067 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW (0x07068 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN (0x07069 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION (0x0706A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION (0x0706B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL (0x0706C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_NO_VALID_TDM_CLOCKS (0x0706E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY (0x07073 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_REMOVAL (0x07075 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO (0x07077 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEFAULT_ERL (0x07079 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK (0x0707B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED (0x0707C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED (0x0707D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION (0x0707E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT (0x0707F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED (0x07080 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B (0x07082 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE (0x07083 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE (0x07084 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_CANNOT_MODIFY (0x07085 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B_CANNOT_MODIFY (0x07086 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_NOT_ENABLED (0x07087 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_BIDIR_DISABLED (0x0708B + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID (0x0708D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PER_CHAN_TAIL_DISPLACEMENT (0x0708E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION (0x0708F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL (0x07092 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED (0x07093 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL (0x07094 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL (0x07095 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET (0x07096 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET (0x07097 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL (0x07098 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL (0x07099 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP (0x0709A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP (0x0709C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL (0x0709D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD (0x0709E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK (0x0709F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN (0x070A0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_RATIO (0x070A1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_FLAG (0x070A2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY (0x070A3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION (0x070A4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT (0x070A5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SEGREGATION (0x070A6 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_RATIO (0x070A7 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS (0x070A8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN (0x070A9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN (0x070AA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN (0x070AB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN (0x070AC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN (0x070AD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN (0x070AE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN (0x070AF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN (0x070B0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION (0x070B1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT (0x070B2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT (0x070B3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS (0x070B4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x070B5 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS (0x070B8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x070B9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION (0x070BA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID (0x070BB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM (0x070BC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE (0x070BD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING (0x070BE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR (0x070BF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY (0x070C0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION (0x070C1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUST_ENABLE_TONE_DISABLER (0x070C2 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_REQUIRED (0x070C5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_REQUIRED (0x070C6 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_AUTO_LEVEL_CONTROL_REQUIRED (0x070C8 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED (0x070CB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x070CC + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_PHASING_TSST_ALL_ENTRIES_ARE_OPENED (0x08000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_DISABLED (0x08001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE (0x08002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_TIMESLOT (0x08003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_STREAM (0x08004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_PHASING_LENGTH (0x08005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_NOT_OPEN (0x08006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_ACTIVE_DEPENDENCIES (0x08007 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE (0x09000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_DISABLED (0x09001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN (0x09002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES (0x09003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE (0x09004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND (0x09005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ALL_BUFFERS_OPEN (0x09006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_INVALID_HANDLE (0x09007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE (0x09008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MUTE (0x09009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE (0x0900A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_ALREADY_MUTED (0x0900B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_NOT_MUTED (0x0900C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_CODEC_ACTIVE (0x0900D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MIXER_FULL (0x0900E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ALREADY_ON_BRIDGE (0x0900F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_ALL (0x09010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_EXT_TONE_ENABLED (0x09011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_INPUT_PORT (0x09012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_DOMINANT_SPEAKER (0x09013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_BIDIR (0x09015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CNR_MUST_BE_ENABLED (0x09016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NLP_MUST_BE_ENABLED (0x09017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF (0x09018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_PARTICIPANT_CNT (0x09019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_MASK_INDEX (0x0901A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_ALL_BUFFERS_OPEN (0x0901B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_DISABLED (0x0901C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_INDEX_USED (0x0901D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_SIMPLE_BRIDGE (0x0901E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_COPY_EVENTS (0x0901F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE (0x09020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_TAP_NOT_SUPPORTED (0x09021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_BRIDGE (0x09022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY (0x09023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_SAME_BRIDGE (0x09024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_TAP_SOUT_ONLY (0x09025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_ALREADY_TAPPED (0x09026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE (0x09027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION (0x09028 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MISC_CANNOT_ROUND_UP_NUMBER (0x0A000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MISC_ASCII_CONVERSION_FAILED (0x0A001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID (0x0B000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN (0x0B001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NUMBER_INVALID (0x0B002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED (0x0B003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED (0x0B004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_AVAILABLE (0x0B005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_DISABLE_ALL (0x0B006 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS (0x0C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY (0x0C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_MAX_TONES (0x0C002 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_INTRPTS_RW_ERROR (0x0D000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NOT_ACTIVE (0x0D001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_CONFIG (0x0D002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_CONFIG (0x0D003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_CONFIG (0x0D004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_CONFIG (0x0D005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_CONFIG (0x0D006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_TIMEOUT (0x0D007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_TIMEOUT (0x0D008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_TIMEOUT (0x0D009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0D00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_TIMEOUT (0x0D00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_AF_TIMESTAMP_READ_TIMEOUT (0x0D00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NLP_TIMESTAMP_READ_TIMEOUT (0x0D00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSST_TIMESLOT (0x0E000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_STREAM (0x0E001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_TSST_RESERVED (0x0E002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ASSOCIATED_TSST_RESERVED (0x0E003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ALL_TSSTS_ARE_OPENED (0x0E004 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MULTIPROC_API_INST_SHARED (0x10000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MULTIPROC_API_INST_LOCAL (0x10001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE (0x11000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PORT (0x11001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_LENGTH (0x11002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_SOUT_READ_LENGTH (0x11003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_DATA (0x11004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_RESET_BUFS (0x11005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_BUF_EMPTY (0x11006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RIN_PTR_INVALID (0x11007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SIN_PTR_INVALID (0x11008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_ROUT_PTR_INVALID (0x11009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SOUT_PTR_INVALID (0x1100A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RAW_DATA_PTR_INVALID (0x1100B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_LENGTH_INVALID (0x1100C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED (0x1100D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PCM_LAW (0x1100E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED (0x1100F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES (0x11010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID (0x11011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED (0x11012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE (0x11013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN (0x11014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_CONTENT (0x11015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE (0x11016 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED (0x12000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE (0x12001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE (0x12002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE (0x12003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_PORT (0x12004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_PORT (0x12005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_EVENT_NOT_OPEN (0x12006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED (0x12007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED (0x12008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED (0x12009 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_ADPCM_CHAN_DISABLED (0x13000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE (0x13001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT (0x13002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM (0x13003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT (0x13004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM (0x13005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS (0x13006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS (0x13007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW (0x13008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_MODE (0x13009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE (0x1300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE (0x1300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS (0x1300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE (0x1300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW (0x1300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION (0x1300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN (0x13010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED (0x13011 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHIP_STATS_RESET (0x14000 + cOCT6100_ERR_BASE) + + + +#define cOCT6100_ERR_PRODUCTION_BIST_DISABLED (0x16000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_PAYLOAD (0x2C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_PAYLOAD (0x2C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH (0x2C002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_LENGTH (0x2C003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ENDIAN_DETECTION_FIELD (0x2C004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_CHECKSUM (0x2C005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR (0x2C006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN (0x2C007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET (0x2C008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED (0x2C009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INAVLID_SESSION_NUMBER (0x2C00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_HOT_CHAN_INDEX (0x2C00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_DISABLED (0x2C00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_RPC_COMMAND_NUM (0x2C00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TLV_TIMEOUT (0x31000 + cOCT6100_ERR_BASE) + +/* Fatal errors must always be greater or equal to 0xE000. */ +#define cOCT6100_ERR_FATAL (0xDE000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_API (0xDE000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_EXT_API (0xDE001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_SMEAR_API (0xDE002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_BURST_API (0xDE003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_API (0xDE004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_BURST_API (0xDE005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_DEBUG_API (0xDE006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_ARRAY_API (0xDE007 + cOCT6100_ERR_BASE) + +#define cOCT6100_FATAL_BASE (0xDF000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_0 (0x00000 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1 (0x00001 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2 (0x00002 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3 (0x00003 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4 (0x00004 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5 (0x00005 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6 (0x00006 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7 (0x00007 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8 (0x00008 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9 (0x00009 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A (0x0000A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B (0x0000B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C (0x0000C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D (0x0000D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E (0x0000E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_F (0x0000F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_10 (0x00010 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_11 (0x00011 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_12 (0x00012 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_13 (0x00013 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_14 (0x00014 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_15 (0x00015 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_16 (0x00016 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_17 (0x00017 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_18 (0x00018 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_19 (0x00019 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1A (0x0001A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1B (0x0001B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1C (0x0001C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1D (0x0001D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1E (0x0001E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1F (0x0001F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_20 (0x00020 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_21 (0x00021 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_22 (0x00022 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_23 (0x00023 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_24 (0x00024 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_25 (0x00025 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_26 (0x00026 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_27 (0x00027 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_28 (0x00028 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_29 (0x00029 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2A (0x0002A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2B (0x0002B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2C (0x0002C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2D (0x0002D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2E (0x0002E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2F (0x0002F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_30 (0x00030 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_31 (0x00031 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_32 (0x00032 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_33 (0x00033 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_34 (0x00034 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_35 (0x00035 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_36 (0x00036 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_37 (0x00037 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_38 (0x00038 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_39 (0x00039 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3A (0x0003A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3B (0x0003B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3C (0x0003C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3D (0x0003D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3E (0x0003E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3F (0x0003F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_40 (0x00040 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_41 (0x00041 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_42 (0x00042 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_43 (0x00043 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_44 (0x00044 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_45 (0x00045 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_46 (0x00046 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_47 (0x00047 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_48 (0x00048 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_49 (0x00049 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4A (0x0004A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4B (0x0004B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4C (0x0004C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4D (0x0004D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4E (0x0004E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4F (0x0004F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_50 (0x00050 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_51 (0x00051 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_52 (0x00052 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_53 (0x00053 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_54 (0x00054 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_55 (0x00055 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_56 (0x00056 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_57 (0x00057 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_58 (0x00058 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_59 (0x00059 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5A (0x0005A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5B (0x0005B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5C (0x0005C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5D (0x0005D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5E (0x0005E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5F (0x0005F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_60 (0x00060 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_61 (0x00061 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_62 (0x00062 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_63 (0x00063 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_64 (0x00064 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_65 (0x00065 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_66 (0x00066 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_67 (0x00067 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_68 (0x00068 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_69 (0x00069 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6A (0x0006A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6B (0x0006B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6C (0x0006C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6D (0x0006D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6E (0x0006E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6F (0x0006F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_70 (0x00070 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_71 (0x00071 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_72 (0x00072 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_73 (0x00073 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_74 (0x00074 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_75 (0x00075 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_76 (0x00076 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_77 (0x00077 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_78 (0x00078 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_79 (0x00079 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7A (0x0007A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7B (0x0007B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7C (0x0007C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7D (0x0007D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7E (0x0007E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7F (0x0007F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_80 (0x00080 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_81 (0x00081 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_82 (0x00082 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_83 (0x00083 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_84 (0x00084 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_85 (0x00085 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_86 (0x00086 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_87 (0x00087 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_88 (0x00088 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_89 (0x00089 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8A (0x0008A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8B (0x0008B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8C (0x0008C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8D (0x0008D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8E (0x0008E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8F (0x0008F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_90 (0x00090 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_91 (0x00091 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_92 (0x00092 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_93 (0x00093 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_94 (0x00094 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_95 (0x00095 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_96 (0x00096 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_97 (0x00097 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_98 (0x00098 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_99 (0x00099 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9A (0x0009A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9B (0x0009B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9C (0x0009C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9D (0x0009D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9E (0x0009E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9F (0x0009F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A0 (0x000A0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A1 (0x000A1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A2 (0x000A2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A3 (0x000A3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A4 (0x000A4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A5 (0x000A5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A6 (0x000A6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A7 (0x000A7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A8 (0x000A8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A9 (0x000A9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AA (0x000AA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AB (0x000AB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AC (0x000AC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AD (0x000AD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AE (0x000AE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AF (0x000AF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B0 (0x000B0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B1 (0x000B1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B2 (0x000B2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B3 (0x000B3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B4 (0x000B4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B5 (0x000B5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B6 (0x000B6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B7 (0x000B7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B8 (0x000B8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B9 (0x000B9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BA (0x000BA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BB (0x000BB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BC (0x000BC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BD (0x000BD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BE (0x000BE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BF (0x000BF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C0 (0x000C0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C1 (0x000C1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C2 (0x000C2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C3 (0x000C3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C4 (0x000C4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C5 (0x000C5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C6 (0x000C6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C7 (0x000C7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C8 (0x000C8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C9 (0x000C9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CA (0x000CA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CB (0x000CB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CC (0x000CC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CD (0x000CD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CE (0x000CE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CF (0x000CF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D0 (0x000D0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D1 (0x000D1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D2 (0x000D2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D3 (0x000D3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D4 (0x000D4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D5 (0x000D5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D6 (0x000D6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D7 (0x000D7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D8 (0x000D8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D9 (0x000D9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DA (0x000DA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DB (0x000DB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DC (0x000DC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DD (0x000DD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DE (0x000DE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DF (0x000DF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E0 (0x000E0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E1 (0x000E1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E2 (0x000E2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E3 (0x000E3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E4 (0x000E4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E5 (0x000E5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E6 (0x000E6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E7 (0x000E7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E8 (0x000E8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E9 (0x000E9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_EA (0x000EA + cOCT6100_FATAL_BASE) + +#endif /* __OCT6100_ERRORS_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_events_inst.h b/xpp/oct612x/include/oct6100api/oct6100_events_inst.h new file mode 100644 index 0000000..323cd5b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_events_inst.h @@ -0,0 +1,69 @@ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_INST_H__ +#define __OCT6100_EVENTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TONE_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulToneDetected; /* Tone number of the tone detected. */ + UINT32 ulTimestamp; + UINT32 ulEventType; + UINT32 ulExtToneDetectionPort; + +} tOCT6100_API_TONE_EVENT, *tPOCT6100_API_TONE_EVENT; + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + UINT32 ulTimestamp; + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_API_BUFFER_PLAYOUT_EVENT, *tPOCT6100_API_BUFFER_PLAYOUT_EVENT; + +#endif /* __OCT6100_EVENTS_INST_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_events_pub.h b/xpp/oct612x/include/oct6100api/oct6100_events_pub.h new file mode 100644 index 0000000..4ee131a --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_events_pub.h @@ -0,0 +1,111 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_PUB_H__ +#define __OCT6100_EVENTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulToneDetected; + + UINT32 ulTimestamp; + UINT32 ulEventType; + + UINT32 ulExtToneDetectionPort; + +} tOCT6100_TONE_EVENT, *tPOCT6100_TONE_EVENT; + +typedef struct _OCT6100_EVENT_GET_TONE_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxToneEvent; + UINT32 ulNumValidToneEvent; + + tPOCT6100_TONE_EVENT pToneEvent; + +} tOCT6100_EVENT_GET_TONE, *tPOCT6100_EVENT_GET_TONE; + +typedef struct _OCT6100_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + + UINT32 ulTimestamp; + + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_BUFFER_PLAYOUT_EVENT, *tPOCT6100_BUFFER_PLAYOUT_EVENT; + +typedef struct _OCT6100_BUFFER_PLAYOUT_GET_EVENT_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxEvent; + UINT32 ulNumValidEvent; + + tPOCT6100_BUFFER_PLAYOUT_EVENT pBufferPlayoutEvent; + +} tOCT6100_BUFFER_PLAYOUT_GET_EVENT, *tPOCT6100_BUFFER_PLAYOUT_GET_EVENT; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100EventGetToneDef( + OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); +UINT32 Oct6100EventGetTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); + +UINT32 Oct6100BufferPlayoutGetEventDef( + OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); +UINT32 Oct6100BufferPlayoutGetEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); + +#endif /* __OCT6100_EVENTS_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h b/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h new file mode 100644 index 0000000..fc82cdd --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_interrupts_inst.h @@ -0,0 +1,134 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_INST_H__ +#define __OCT6100_INTERRUPTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_INTRPT_CONFIG_ +{ + /* The configuration of each group of interrupts. Each can have one of the + following values: + cOCT6100_INTRPT_DISABLE, + cOCT6100_INTRPT_NO_TIMEOUT, + cOCT6100_INTRPT_TIMEOUT. */ + UINT8 byFatalGeneralConfig; + UINT8 byFatalMemoryConfig; + UINT8 byErrorMemoryConfig; + UINT8 byErrorOverflowToneEventsConfig; + UINT8 byErrorH100Config; + + /* The timeout value for each interrupt group, if the corresponding + configuration variable is set to cOCT6100_INTRPT_TIMEOUT. This + value is kept in mclk cycles. */ + UINT32 ulFatalMemoryTimeoutMclk; + UINT32 ulErrorMemoryTimeoutMclk; + UINT32 ulErrorOverflowToneEventsTimeoutMclk; + UINT32 ulErrorH100TimeoutMclk; + +} tOCT6100_API_INTRPT_CONFIG, *tPOCT6100_API_INTRPT_CONFIG; + +typedef struct _OCT6100_API_INTRPT_MANAGE_ +{ + /* Number of mclk cycles in 1ms. */ + UINT32 ulNumMclkCyclesIn1Ms; + + /* Whether the mclk interrupt is active. */ + UINT8 fMclkIntrptActive; + UINT32 ulNextMclkIntrptTimeHigh; + UINT32 ulNextMclkIntrptTimeLow; + + /* Mclk time read from registers. */ + UINT32 ulRegMclkTimeHigh; + UINT32 ulRegMclkTimeLow; + + /* Used by the interrupt service routine. */ + UINT16 usRegister102h; + UINT16 usRegister202h; + UINT16 usRegister302h; + UINT16 usRegister502h; + UINT16 usRegister702h; + + /* The state of each interrupt group. Can be one of the following: + cOCT6100_INTRPT_ACTIVE, + cOCT6100_INTRPT_WILL_TIMEOUT, + cOCT6100_INTRPT_IN_TIMEOUT, + cOCT6100_INTRPT_WILL_DISABLED. */ + UINT16 byFatalGeneralState; + UINT16 byFatalMemoryState; + UINT16 byErrorMemoryState; + UINT16 byErrorOverflowToneEventsState; + UINT16 byErrorH100State; + + /* The time at which each disabled interrupt was disabled, in mclk cycles. */ + UINT32 ulFatalMemoryDisableMclkHigh; + UINT32 ulFatalMemoryDisableMclkLow; + UINT32 ulErrorMemoryDisableMclkHigh; + UINT32 ulErrorMemoryDisableMclkLow; + UINT32 ulErrorOverflowToneEventsDisableMclkHigh; + UINT32 ulErrorOverflowToneEventsDisableMclkLow; + UINT32 ulErrorH100DisableMclkHigh; + UINT32 ulErrorH100DisableMclkLow; + + /* The time at which each disabled interrupt group is to be reenabled, + in number of mclk cycles. */ + UINT32 ulFatalGeneralEnableMclkHigh; + UINT32 ulFatalGeneralEnableMclkLow; + UINT32 ulFatalMemoryEnableMclkHigh; + UINT32 ulFatalMemoryEnableMclkLow; + UINT32 ulErrorMemoryEnableMclkHigh; + UINT32 ulErrorMemoryEnableMclkLow; + UINT32 ulErrorOverflowToneEventsEnableMclkHigh; + UINT32 ulErrorOverflowToneEventsEnableMclkLow; + UINT32 ulErrorH100EnableMclkHigh; + UINT32 ulErrorH100EnableMclkLow; + + /* If this is set, buffer playout events are pending. */ + UINT8 fBufferPlayoutEventsPending; + /* If this is set, tone events are pending. */ + UINT8 fToneEventsPending; + + + + UINT8 fIsrCalled; + +} tOCT6100_API_INTRPT_MANAGE, *tPOCT6100_API_INTRPT_MANAGE; + +#endif /* __OCT6100_INTERRUPTS_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h b/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h new file mode 100644 index 0000000..a90fdcf --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_interrupts_pub.h @@ -0,0 +1,102 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_PUB_H__ +#define __OCT6100_INTERRUPTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_CONFIGURE_ +{ + UINT32 ulFatalGeneralConfig; + UINT32 ulFatalMemoryConfig; + + UINT32 ulErrorMemoryConfig; + UINT32 ulErrorOverflowToneEventsConfig; + UINT32 ulErrorH100Config; + + UINT32 ulFatalMemoryTimeout; + UINT32 ulErrorMemoryTimeout; + UINT32 ulErrorOverflowToneEventsTimeout; + UINT32 ulErrorH100Timeout; + +} tOCT6100_INTERRUPT_CONFIGURE, *tPOCT6100_INTERRUPT_CONFIGURE; + +typedef struct _OCT6100_INTERRUPT_FLAGS_ +{ + BOOL fFatalGeneral; + UINT32 ulFatalGeneralFlags; + + BOOL fFatalReadTimeout; + + BOOL fErrorRefreshTooLate; + BOOL fErrorPllJitter; + + BOOL fErrorOverflowToneEvents; + + BOOL fErrorH100OutOfSync; + BOOL fErrorH100ClkA; + BOOL fErrorH100ClkB; + BOOL fErrorH100FrameA; + + BOOL fToneEventsPending; + BOOL fBufferPlayoutEventsPending; + + BOOL fApiSynch; + + + +} tOCT6100_INTERRUPT_FLAGS, *tPOCT6100_INTERRUPT_FLAGS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptConfigureDef( + OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); +UINT32 Oct6100InterruptConfigure( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); + +UINT32 Oct6100InterruptServiceRoutineDef( + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); +UINT32 Oct6100InterruptServiceRoutine( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +#endif /* __OCT6100_INTERRUPTS_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h b/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h new file mode 100644 index 0000000..1415e86 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_mixer_inst.h @@ -0,0 +1,86 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_INST_H__ +#define __OCT6100_MIXER_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_MIXER_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Type of the event.*/ + UINT16 usEventType; + + /* Source channel index */ + UINT16 usSourceChanIndex; + + /* Destination channel index */ + UINT16 usDestinationChanIndex; + + /* Pointer to the next entry.*/ + UINT16 usNextEventPtr; + +} tOCT6100_API_MIXER_EVENT, *tPOCT6100_API_MIXER_EVENT; + + +typedef struct _OCT6100_API_COPY_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Source + destination ports. */ + UINT8 bySourcePort; + UINT8 byDestinationPort; + + /* Index of the channels associated to this event.*/ + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + + UINT16 usMixerEventIndex; + +} tOCT6100_API_COPY_EVENT, *tPOCT6100_API_COPY_EVENT; + + +#endif /* __OCT6100_MIXER_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h b/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h new file mode 100644 index 0000000..08aa28b --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_mixer_pub.h @@ -0,0 +1,77 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_PUB_H__ +#define __OCT6100_MIXER_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_COPY_EVENT_CREATE_ +{ + PUINT32 pulCopyEventHndl; + + UINT32 ulSourceChanHndl; + UINT32 ulSourcePort; + + UINT32 ulDestinationChanHndl; + UINT32 ulDestinationPort; + +} tOCT6100_COPY_EVENT_CREATE, *tPOCT6100_COPY_EVENT_CREATE; + +typedef struct _OCT6100_COPY_EVENT_DESTROY_ +{ + UINT32 ulCopyEventHndl; + +} tOCT6100_COPY_EVENT_DESTROY, *tPOCT6100_COPY_EVENT_DESTROY; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100MixerCopyEventCreateDef( + OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); +UINT32 Oct6100MixerCopyEventCreate( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); + +UINT32 Oct6100MixerCopyEventDestroyDef( + OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); +UINT32 Oct6100MixerCopyEventDestroy( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); + +#endif /* __OCT6100_MIXER_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h new file mode 100644 index 0000000..a2b2e27 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h @@ -0,0 +1,68 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_INST_H__ +#define __OCT6100_PHASING_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_PHASING_TSST_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Count of number of resources connected in some way to this buffer. */ + UINT16 usDependencyCnt; + + /* TDM timeslot and stream where the counter is read. */ + UINT16 usStream; + UINT16 usTimeslot; + + /* Length of the phasing TSST counter. */ + UINT16 usPhasingLength; + + /* TSST control index where the counter comes from. */ + UINT16 usPhasingTsstIndex; + +} tOCT6100_API_PHASING_TSST, *tPOCT6100_API_PHASING_TSST; + +#endif /* __OCT6100_PHASING_TSST_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h new file mode 100644 index 0000000..b5af946 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h @@ -0,0 +1,78 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_PUB_H__ +#define __OCT6100_PHASING_TSST_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_PHASING_TSST_OPEN_ +{ + PUINT32 pulPhasingTsstHndl; + + UINT32 ulPhasingLength; + UINT32 ulTimeslot; + UINT32 ulStream; + + + +} tOCT6100_PHASING_TSST_OPEN, *tPOCT6100_PHASING_TSST_OPEN; + +typedef struct _OCT6100_PHASING_TSST_CLOSE_ +{ + UINT32 ulPhasingTsstHndl; + +} tOCT6100_PHASING_TSST_CLOSE, *tPOCT6100_PHASING_TSST_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100PhasingTsstOpenDef( + OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); +UINT32 Oct6100PhasingTsstOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100PhasingTsstCloseDef( + OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); +UINT32 Oct6100PhasingTsstClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); + +#endif /* __OCT6100_PHASING_TSST_PUB_H__ */ + diff --git a/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h new file mode 100644 index 0000000..046a639 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_inst.h @@ -0,0 +1,88 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_INST_H__ +#define __OCT6100_PLAYOUT_BUF_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst ); + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst)) + ulIndex; + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE_ +{ + /* Next node. */ + UINT32 ulNext; + + /* Previous node. */ + UINT32 ulPrevious; + + /* Start address of this node. */ + UINT32 ulStartAddress; + + /* Size of this node. */ + UINT32 ulSize; + + /* Allocated node? Free node? */ + UINT8 fAllocated; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE; + +typedef struct _OCT6100_API_BUFFER_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Pcm law of the buffer. */ + UINT8 byBufferPcmLaw; + + /* Number of channels currently playing this buffer.*/ + UINT16 usDependencyCnt; + + /* Length of the buffer ( in bytes ).*/ + UINT32 ulBufferSize; + + /* Address in external memory of the buffer. */ + UINT32 ulBufferBase; + +} tOCT6100_API_BUFFER, *tPOCT6100_API_BUFFER; + +#endif /* __OCT6100_PLAYOUT_BUF_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h new file mode 100644 index 0000000..9fe0d6f --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_playout_buf_pub.h @@ -0,0 +1,183 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_PUB_H__ +#define __OCT6100_PLAYOUT_BUF_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_BUFFER_LOAD_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + PUINT8 pbyBufferPattern; /* A byte pointer pointing to a valid buffer to be loaded into the chip's external memory. */ + UINT32 ulBufferSize; /* Size of the buffer loaded into external memory. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD, *tPOCT6100_BUFFER_LOAD; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_INIT_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + UINT32 ulBufferSize; /* Size of the buffer to be loaded in memory. This space will be reserved. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD_BLOCK_INIT, *tPOCT6100_BUFFER_LOAD_BLOCK_INIT; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + /* Offset, in bytes, of the first byte in the block to be loaded. */ + /* This offset is with respect to the beginning of the buffer. */ + /* This value must be modulo 2 */ + UINT32 ulBlockOffset; + + /* Size of the block to be loaded into external memory. */ + /* This value must be modulo 2. */ + UINT32 ulBlockLength; + + /* A pointer pointing to a valid buffer block to be loaded */ + /* into the chip's external memory. This is a pointer to the entire */ + /* buffer. The API uses the ulBlockOffset and ulBlockLength to index */ + /* within this buffer and obtain the block to be loaded. */ + PUINT8 pbyBufferPattern; + +} tOCT6100_BUFFER_LOAD_BLOCK, *tPOCT6100_BUFFER_LOAD_BLOCK; + +typedef struct _OCT6100_BUFFER_UNLOAD_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + +} tOCT6100_BUFFER_UNLOAD, *tPOCT6100_BUFFER_UNLOAD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_ADD_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + UINT32 ulMixingMode; /* Weither or not the voice stream will be muted while playing the buffer. */ + + INT32 lGainDb; /* Gain applied to the buffer that will be played on the specified port. */ + + BOOL fRepeat; /* Use ulRepeatCount variable. */ + UINT32 ulRepeatCount; /* Number of times to repeat playing the selected buffer. */ + + UINT32 ulDuration; /* Duration in millisecond that this buffer should play. Setting this overrides fRepeat. */ + + UINT32 ulBufferLength; /* Length of the buffer to play (starting at the beginning), AUTO_SELECT for all. */ + +} tOCT6100_BUFFER_PLAYOUT_ADD, *tPOCT6100_BUFFER_PLAYOUT_ADD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_START_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + + BOOL fNotifyOnPlayoutStop; /* Check if the buffers have finished playing on this channel/port. */ + /* The events are queued in a soft buffer that the user must empty regularly. */ + UINT32 ulUserEventId; /* Returned to the user when the playout is finished and the user has set the fNotifyOnPlayoutStop flag. */ + + BOOL fAllowStartWhileActive; /* Use this to add buffers to something that is already playing on the channel/port. */ + +} tOCT6100_BUFFER_PLAYOUT_START, *tPOCT6100_BUFFER_PLAYOUT_START; + +typedef struct _OCT6100_BUFFER_PLAYOUT_STOP_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + BOOL fStopCleanly; /* Whether or not the skip will be clean. */ + + PBOOL pfAlreadyStopped; /* Whether playout was already stopped or not. */ + PBOOL pfNotifyOnPlayoutStop; /* Whether the user chosed to receive an event on playout stop. */ + +} tOCT6100_BUFFER_PLAYOUT_STOP, *tPOCT6100_BUFFER_PLAYOUT_STOP; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100BufferPlayoutLoadDef( + OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); +UINT32 Oct6100BufferPlayoutLoad( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); + +UINT32 Oct6100BufferPlayoutLoadBlockInitDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); +UINT32 Oct6100BufferPlayoutLoadBlockInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); + +UINT32 Oct6100BufferPlayoutLoadBlockDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); +UINT32 Oct6100BufferPlayoutLoadBlock( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); + +UINT32 Oct6100BufferPlayoutUnloadDef( + OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); +UINT32 Oct6100BufferPlayoutUnload( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); + +UINT32 Oct6100BufferPlayoutAddDef( + OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); +UINT32 Oct6100BufferPlayoutAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); + +UINT32 Oct6100BufferPlayoutStartDef( + OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); +UINT32 Oct6100BufferPlayoutStart( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); + +UINT32 Oct6100BufferPlayoutStopDef( + OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); +UINT32 Oct6100BufferPlayoutStop( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); + +#endif /* __OCT6100_PLAYOUT_BUF_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h new file mode 100644 index 0000000..85a8d39 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_inst.h @@ -0,0 +1,73 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_INST_H__ +#define __OCT6100_REMOTE_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_REMOTE_DEBUG_INFO_ +{ + UINT32 ulSessionTreeOfst; + UINT32 ulSessionListOfst; + UINT32 ulSessionListHead; + UINT32 ulSessionListTail; + + UINT32 ulPktCacheOfst; + UINT32 ulDataBufOfst; + + UINT32 ulNumSessionsOpen; + UINT32 ulMaxSessionsOpen; + +} tOCT6100_API_REMOTE_DEBUG_INFO, *tPOCT6100_API_REMOTE_DEBUG_INFO; + +typedef struct _OCT6100_API_REMOTE_DEBUG_SESSION_ +{ + UINT32 ulSessionNum; + UINT32 ulTransactionNum; + UINT32 ulPktRetryNum; + UINT32 ulPktByteSize; + + UINT32 aulLastPktTime[ 2 ]; + UINT32 ulForwardLink; + UINT32 ulBackwardLink; + +} tOCT6100_API_REMOTE_DEBUG_SESSION, *tPOCT6100_API_REMOTE_DEBUG_SESSION; + +#endif /* __OCT6100_REMOTE_DEBUG_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h new file mode 100644 index 0000000..18a7e22 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_remote_debug_pub.h @@ -0,0 +1,64 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_PUB_H__ +#define __OCT6100_REMOTE_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_REMOTE_DEBUG_ +{ + PUINT32 pulReceivedPktPayload; + UINT32 ulReceivedPktLength; + + PUINT32 pulResponsePktPayload; + UINT32 ulMaxResponsePktLength; + UINT32 ulResponsePktLength; + +} tOCT6100_REMOTE_DEBUG, *tPOCT6100_REMOTE_DEBUG; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100RemoteDebugDef( + OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); +UINT32 Oct6100RemoteDebug( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); + +#endif /* __OCT6100_REMOTE_DEBUG_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h new file mode 100644 index 0000000..093ce0d --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tlv_inst.h @@ -0,0 +1,72 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tlv.c. All elements defined in this file are for public + usage of the API. All instate elements are defined in the + oct6100_tlv_inst.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TLV_INST_H__ +#define __OCT6100_TLV_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TLV_OFFSET_ +{ + /* The dword offset contain the number of dword from a base address to reach the desired dword. + + i.e. usDwordOffset = (total bit offset) / 32; */ + + UINT16 usDwordOffset; + + /* The bit offset will contain the bit offset required to right shift the DWORD read and obtain + the desired value. This field is depend on the field size. + + i.e. byBitOffset = 31 - ((total bit offset) % 32) - byFieldSize; */ + + UINT8 byBitOffset; + UINT8 byFieldSize; + +} tOCT6100_TLV_OFFSET, *tPOCT6100_TLV_OFFSET; + +typedef struct _OCT6100_TLV_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + + + +} tOCT6100_TLV_TONE_INFO, *tPOCT6100_TLV_TONE_INFO; + +#endif /* __OCT6100_TLV_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h new file mode 100644 index 0000000..1ee86fe --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_inst.h @@ -0,0 +1,46 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection_buf.c. All elements defined in this file are for + public usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_INST_H__ +#define __OCT6100_TONE_DETECTION_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +#endif /* __OCT6100_TONE_DETECTION_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h new file mode 100644 index 0000000..cf28069 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tone_detection_pub.h @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_PUB_H__ +#define __OCT6100_TONE_DETECTION_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_DETECTION_ENABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + +} tOCT6100_TONE_DETECTION_ENABLE, *tPOCT6100_TONE_DETECTION_ENABLE; + +typedef struct _OCT6100_TONE_DETECTION_DISABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + BOOL fDisableAll; + +} tOCT6100_TONE_DETECTION_DISABLE, *tPOCT6100_TONE_DETECTION_DISABLE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ToneDetectionEnableDef( + OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); +UINT32 Oct6100ToneDetectionEnable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); + +UINT32 Oct6100ToneDetectionDisableDef( + OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); +UINT32 Oct6100ToneDetectionDisable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); + +#endif /* __OCT6100_TONE_DETECTION_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h new file mode 100644 index 0000000..9eb23ba --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h @@ -0,0 +1,70 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_INST_H__ +#define __OCT6100_TSI_CNCT_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSI_CNCT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Input PCM law. */ + UINT8 byInputPcmLaw; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_TSI_CNCT, *tPOCT6100_API_TSI_CNCT; + +#endif /* __OCT6100_TSI_CNCT_INST_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h new file mode 100644 index 0000000..c030468 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_PUB_H__ +#define __OCT6100_TSI_CNCT_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TSI_CNCT_OPEN_ +{ + PUINT32 pulTsiCnctHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + +} tOCT6100_TSI_CNCT_OPEN, *tPOCT6100_TSI_CNCT_OPEN; + +typedef struct _OCT6100_TSI_CNCT_CLOSE_ +{ + UINT32 ulTsiCnctHndl; + +} tOCT6100_TSI_CNCT_CLOSE, *tPOCT6100_TSI_CNCT_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100TsiCnctOpenDef( + OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); +UINT32 Oct6100TsiCnctOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100TsiCnctCloseDef( + OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); +UINT32 Oct6100TsiCnctClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); + +#endif /* __OCT6100_TSI_CNCT_PUB_H__ */ diff --git a/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h b/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h new file mode 100644 index 0000000..6b9fe77 --- /dev/null +++ b/xpp/oct612x/include/oct6100api/oct6100_tsst_inst.h @@ -0,0 +1,55 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSST_INST_H__ +#define __OCT6100_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSST_ENTRY_ +{ + UINT16 usTsstMemoryIndex; /* Index in the TSST memory of the TSST */ + UINT16 usTsstValue; /* Tsst value given by the user. */ + /* bit 5:0 = stream value, bit 13:6 = timeslot value. */ + + UINT16 usNextEntry; /* Pointer to the next entry in the list. */ + +} tOCT6100_API_TSST_ENTRY, *tPOCT6100_API_TSST_ENTRY; + +#endif /* __OCT6100_TSST_INST_H__ */ diff --git a/xpp/oct612x/include/octdef.h b/xpp/oct612x/include/octdef.h new file mode 100644 index 0000000..7e534b7 --- /dev/null +++ b/xpp/oct612x/include/octdef.h @@ -0,0 +1,120 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octdef.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common system definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTDEF_H__ +#define __OCTDEF_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __KERNEL__ +#include +#endif + +/***************************** INCLUDE FILES *******************************/ + +/*-------------------------------------------------------------------------- + Get Platform Dependency headers +----------------------------------------------------------------------------*/ +#include "octosdependant.h" + + +/*-------------------------------------------------------------------------- + Common Type definitions +----------------------------------------------------------------------------*/ +#include "octtype.h" + +/***************************** DEFINES *************************************/ + +/* List of functions to skip compiling since we don't use them */ +#include "digium_unused.h" + + + +/*-------------------------------------------------------------------------- + Miscellaneous constants +----------------------------------------------------------------------------*/ + +#ifndef PROTO +#define PROTO extern +#endif + +/* Generic return codes. */ +#define cOCTDEF_RC_OK 0 /* Generic Ok */ +#define cOCTDEF_RC_ERROR 1 /* Generic Error */ + +/* Default return values of all OCTAPI functions. */ +#ifndef GENERIC_OK +#define GENERIC_OK 0x00000000 +#endif + +#ifndef GENERIC_ERROR +#define GENERIC_ERROR 0x00000001 +#endif + +#ifndef GENERIC_BAD_PARAM +#define GENERIC_BAD_PARAM 0x00000002 +#endif + +/* Defines of boolean expressions (TRUE/FALSE) */ +#ifndef FALSE +#define FALSE (BOOL)0 +#endif + +#ifndef TRUE +#define TRUE (BOOL)1 +#endif + +/*-------------------------------------------------------------------------- + DLL Import-Export +----------------------------------------------------------------------------*/ + +#ifdef OCT_WINENV +#define DLLIMP __declspec( dllimport ) +#define DLLEXP __declspec( dllexport ) +#else +#define DLLIMP +#define DLLEXP +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTDEF_H__ */ diff --git a/xpp/oct612x/include/octmac.h b/xpp/oct612x/include/octmac.h new file mode 100644 index 0000000..2e930ae --- /dev/null +++ b/xpp/oct612x/include/octmac.h @@ -0,0 +1,98 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octmac.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common macro definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTMAC_H__ +#define __OCTMAC_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** DEFINES *************************************/ + +/* Combine l & h to form a 32 bit quantity. */ +#define mMAKEULONG(l, h) ((ULONG)(((USHORT)(l)) | (((ULONG)((USHORT)(h))) << 16))) + +#define mLOUCHAR(w) ((UCHAR)(w)) +#define mHIUCHAR(w) ((UCHAR)(((USHORT)(w) >> 8) & 0xff)) +#define mLOUSHORT(l) ((USHORT)((ULONG)l)) +#define mHIUSHORT(l) ((USHORT)(((ULONG)(l) >> 16) & 0xffff)) +#define mLOSHORT(l) ((SHORT)((ULONG)l)) +#define mHISHORT(l) ((SHORT)(((ULONG)(l) >> 16) & 0xffff)) + +/* Combine l & h to form a 16 bit quantity. */ +#define mMAKEUSHORT(l, h) (((USHORT)(l)) | ((USHORT)(h)) << 8) +#define mMAKESHORT(l, h) ((SHORT)mMAKEUSHORT(l, h)) + +/* Extract high and low order parts of 16 and 32 bit quantity */ +#define mLOBYTE(w) mLOUCHAR(w) +#define mHIBYTE(w) mHIUCHAR(w) +#define mMAKELONG(l, h) ((LONG)mMAKEULONG(l, h)) + +/*-------------------------------------------------------------------------- + Bite conversion macro +----------------------------------------------------------------------------*/ +#define mSWAP_INT16(x) mMAKEUSHORT( mHIBYTE(x), mLOBYTE(x) ) +#define mSWAP_INT32(x) mMAKEULONG( mSWAP_INT16(mHIUSHORT(x)), mSWAP_INT16(mLOUSHORT(x)) ) + + +/* Cast any variable to an instance of the specified type. */ +#define mMAKETYPE(v, type) (*((type *)&v)) + +/* Calculate the byte offset of a field in a structure of type type. */ +#define mFIELDOFFSET(type, field) ((UINT32)&(((type *)0)->field)) +#define mCOUNTOF(array) (sizeof(array)/sizeof(array[0])) + +#define mMAX(a,b) (((a) > (b)) ? (a) : (b)) +#define mMIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define mDIM(x) (sizeof(x) / sizeof(x[0])) + +#define mFROMDIGIT(ch) ((ch) - 0x30) /* digit to char */ +#define mTODIGIT(ch) ((ch) + 0x30) /* int to char */ + +#define mISLEAP(a) ( !( a % 400 ) || ( ( a % 100 ) && !( a % 4 ) ) ) + +#define mFOREVER for( ;; ) + +#define mROUND_TO_NEXT_4( a ) ( ((a) % 4) ? ( (a) + 4 - ((a)%4) ) : (a) ) + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTMAC_H__ */ diff --git a/xpp/oct612x/include/octosdependant.h b/xpp/oct612x/include/octosdependant.h new file mode 100644 index 0000000..d7008a4 --- /dev/null +++ b/xpp/oct612x/include/octosdependant.h @@ -0,0 +1,170 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octosdependant.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file is included to set target-specific constants. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTOSDEPENDANT_H__ +#define __OCTOSDEPENDANT_H__ + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/***************************************************************************** + + Known define values + + MSDEV: + WIN32 == WINDOWS 32 bit app + __WIN32__ == WINDOWS 32 bit app + _Windows == WINDOWS 16 bit app + + _WINDOWS == Windows application .. not console + _DLL == Dll Application + _CONSOLE == Console Application .. no windows + + BORLANDC + __TURBOC__ == Turbo Compiler + __BORLANDC__ == Borland compiler + __OS2__ == Borland OS2 compiler + _Windows == Windows 16 bit app + + GCC Compiler + __GNUC__ == GCC Compiler + __unix__ == Unix system + __vax__ == Unix system + unix == Unix system + vax == vax system + + TORNADO + _VXWORKS_ == VXWORK + + ECOS/CYGWIN + _ECOS_ == eCos + + SOLARIS + _SOLARIS_ == Solaris + +*****************************************************************************/ + +/* Machine endian type */ + +#define OCT_MACH_LITTLE_ENDIAN 1 +#define OCT_MACH_BIG_ENDIAN 2 + +/* Try to find current OCT_MACH_ENDIAN from compiler define values */ +#if !defined( MACH_TYPE_BIG_ENDIAN ) && !defined( MACH_TYPE_LITTLE_ENDIAN ) + /* Does GNU defines the endian ? */ + #if defined(__GNU_C__) + #if defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #elif defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif + + /* Try with cpu type */ + #if !defined(OCT_MACH_ENDIAN) + /* Look for intel */ + #if defined( _M_IX86 ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + /* Look for PowerPC */ + #elif defined( _M_MPPC ) || defined( _M_PPC ) || defined(PPC) || defined(__PPC) || defined(_ARCH_PPC) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + /* Look for Blackfin */ + #elif defined( __bfin__ ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #elif defined( CPU ) + #if CPU==PPC860 || CPU==SIMNT + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif +#else + #if defined( MACH_TYPE_BIG_ENDIAN ) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif +#endif + +/* Find system type if not already defined */ +#if !defined( OCT_NTDRVENV ) && !defined( OCT_VXENV ) && !defined( OCT_WINENV ) + +#if defined( WIN32 ) || defined( __WIN32__ ) || defined( _WIN32_ ) || defined( WIN32S ) + /* Verif if building a win32 driver */ + #if ( defined( WIN32 ) && WIN32==100 ) + #define OCT_NTDRVENV + #else + #define OCT_WINENV + #endif +#elif defined( _VXWORKS_ ) + #define OCT_VXENV +#elif defined( _ECOS_ ) +#ifndef OCT_ECOSENV + #define OCT_ECOSENV +#endif /* OCT_ECOSENV */ +#elif defined( _SOLARIS_ ) + #define OCT_SOLARISENV +#elif defined( _LINUX_ ) + #define OCT_LINUXENV +#else + /* Unknown environment */ + #define OCT_UNKNOWNENV +#endif /* WIN env */ + +#endif /* Already defined */ + +#if defined( __KERNEL__ ) && defined( OCT_LINUXENV ) +#define OCT_LINUXDRVENV +#endif + +#ifdef _DEBUG +#define OCT_OPT_USER_DEBUG +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTOSDEPENDANT_H__ */ diff --git a/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h b/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h new file mode 100644 index 0000000..fcee581 --- /dev/null +++ b/xpp/oct612x/include/octrpc/oct6100_rpc_protocol.h @@ -0,0 +1,348 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines and prototypes related to the OCT6100 RPC + protocol for exchanging debug commands. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_RPC_PROTOCOL_H__ +#define __OCT6100_RPC_PROTOCOL_H__ + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_INTERFACE_VERSION 0x00010002 + +/* Octasic commands. */ +#define cOCT6100_RPC_CHIP_LIST 0xFF000000 +#define cOCT6100_RPC_CHIP_CHOICE 0xFF000001 +#define cOCT6100_RPC_ENV_DISCONNECT 0xFF000002 + +/* Commands */ +/* Read commands */ +#define cOCT6100_RPC_READ_WORD 0x00000000 +#define cOCT6100_RPC_READ_BURST 0x00000001 +#define cOCT6100_RPC_READ_DEBUG 0x00000002 +#define cOCT6100_RPC_READ_ARRAY 0x00000003 +#define cOCT6100_RPC_API_DISCONNECT 0x00000004 + +/* Write commands */ +#define cOCT6100_RPC_WRITE_WORD 0x00000010 +#define cOCT6100_RPC_WRITE_BURST 0x00000011 +#define cOCT6100_RPC_WRITE_SMEAR 0x00000012 +#define cOCT6100_RPC_WRITE_INC 0x00000013 + +/* Debug commands.*/ +#define cOCT6100_RPC_SET_HOT_CHANNEL 0x00000014 +#define cOCT6100_RPC_GET_DEBUG_CHAN_INDEX 0x00000015 + +#define cOCTRPC_UNKNOWN_COMMAND_NUM 0xFFFFFFFF + +/* Errors */ +#define cOCT6100_RPCERR_OK 0x00000000 +#define cOCT6100_RPCERR_INVALID_COMMAND_NUMBER 0x00000001 +#define cOCT6100_RPCERR_INVALID_COMMAND_PAYLOAD 0x00000002 +#define cOCT6100_RPCERR_INVALID_COMMAND_LENGTH 0x00000003 + + +/***************************** TYPES ***************************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_WORD + +Description: Command structure for the read of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +OUT ulReadData The word read, returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_WORD_ +{ + UINT32 IN ulAddress; + UINT32 OUT ulReadData; + +} tOCT6100_RPC_READ_WORD, *tPOCT6100_RPC_READ_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_BURST + +Description: Command structure for a read burst. The burst starts at the + given address and reads the specified number of consecutive + words. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulReadData -> | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the read data at ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +IN ulBurstLength The number of consecutive words to be read. +OUT aulReadData The read data returned. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 OUT aulReadData[ 1 ]; + +} tOCT6100_RPC_READ_BURST, *tPOCT6100_RPC_READ_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_ARRAY + +Description: Command structure for a variable number of reads. The reads do + not have to be at contiguous addresses. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword, and the + parity bits are returned 16 per dword (two parity bits per read + access). + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulArrayLength = 0x3 | + ------------------------------------------- + aulArrayData ->| A0 | + ------------------------------------------- + | A1 | + ------------------------------------------- + | A2 | + ------------------------------------------- + | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Ay is the address for access y. + Dy is the read data at Ay. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulArrayLength Number of reads to do. +IN OUT aulArrayData The addresses at which to read (IN) and the read data + returned (OUT). The dwords of the command structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_ARRAY +{ + UINT32 IN ulArrayLength; + UINT32 IN OUT aulArrayData[ 1 ]; + +} tOCT6100_RPC_READ_ARRAY, *tPOCT6100_RPC_READ_ARRAY; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_WORD + +Description: Command structure for the write of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to write. +IN ulWriteData The word to write. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_WORD_ +{ + UINT32 IN ulAddress; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_WORD, *tPOCT6100_RPC_WRITE_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_SMEAR + +Description: Command structure for the write of one word at one or many + consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulSmearLength Number of consecutive addresses to write. +IN ulWriteData The word to write at each address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_SMEAR_ +{ + UINT32 IN ulAddress; + UINT32 IN ulSmearLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_SMEAR, *tPOCT6100_RPC_WRITE_SMEAR; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_INC + +Description: Command structure for the write of an incremental pattern at + one or many consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulIncLength Number of consecutive addresses to write. +IN ulWriteData The first word of the incremental pattern. For each + consecutive write the word will be incremented by 1. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_INC_ +{ + UINT32 IN ulAddress; + UINT32 IN ulIncLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_INC, *tPOCT6100_RPC_WRITE_INC; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_BURST + +Description: Command structure for a write burst. The burst starts at the + given address and writes a given word for each address. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the write data. To save bandwidth + the write data words are sent two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulWriteData ->| D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the write data for ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress First address at which to write. +IN ulBurstLength The number of consecutive addresses to be write. +IN aulWriteData The write data words. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 IN ulParity; + UINT32 IN aulWriteData[ 1 ]; + +} tOCT6100_RPC_WRITE_BURST, *tPOCT6100_RPC_WRITE_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_SET_HOT_CHANNEL + +Description: Command structure to set the hot channel. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_SET_HOT_CHANNEL_ +{ + UINT32 IN ulHotChannel; + UINT32 IN ulPcmLaw; + +} tOCT6100_RPC_SET_HOT_CHANNEL, *tPOCT6100_RPC_SET_HOT_CHANNEL; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_GET_DEBUG_CHAN_INDEX + +Description: Command structure to get the debug channel index used by the API. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_GET_DEBUG_CHAN_INDEX_ +{ + UINT32 OUT ulDebugChanIndex; + +} tOCT6100_RPC_GET_DEBUG_CHAN_INDEX, *tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX; + +#endif /* __OCT6100_RPC_PROTOCOL_H__ */ diff --git a/xpp/oct612x/include/octrpc/rpc_protocol.h b/xpp/oct612x/include/octrpc/rpc_protocol.h new file mode 100644 index 0000000..24e1596 --- /dev/null +++ b/xpp/oct612x/include/octrpc/rpc_protocol.h @@ -0,0 +1,115 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + +This file contains RPC related definitions and prototypes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __RPC_PROTOCOL_H__ +#define __RPC_PROTOCOL_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_ENDIAN_DETECT 0x27182819 +#define cOCTRPC_ENDIAN_DETECT_BYTE_W 0x19 +#define cOCTRPC_ENDIAN_DETECT_BYTE_X 0x28 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Y 0x18 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Z 0x27 +#define cOCTRPC_ECHO_PROTOCOL 0x00000000 + +#define cOCTRPC_MIN_PACKET_BYTE_LENGTH (sizeof( tOCTRPC_OGRDTP_HEADER )) +#define cOCTRPC_FIRST_COMMAND_BYTE_OFFSET (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) +#define cOCTRPC_GENERIC_HEADERS_BYTE_SIZE (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER ) + sizeof( tOCTRPC_COMMAND_HEADER )) +#define cOCTRPC_MAX_PACKET_BYTE_LENGTH 32768 + +/* Protocol versions */ +#define cOCTRPC_PROTOCOL_V1_0 0x00010000 +#define cOCTRPC_PROTOCOL_V1_1 0x00010001 +#define cOCTRPC_PROTOCOL_V1_2 0x00010002 +#define cOCTRPC_PROTOCOL_V1_3 0x00010003 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_0 0xFF010000 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_1 0xFF010001 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_2 0xFF010002 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_3 0xFF010003 + +/* Chips */ +#define cOCTRPC_OCT8304_INTERFACE 0x00000000 +#define cOCTRPC_OCT6100_INTERFACE 0x00000001 + +/* Timeout values. */ +#define cOCTRPC_SESSION_TIMEOUT 30 + +/* Generic errors */ +#define cOCTRPC_RDBGERR_OK 0x00000000 +#define cOCTRPC_RDBGERR_NO_ANSWER 0xFFFF0000 +#define cOCTRPC_RDBGERR_ALL_SESSIONS_OPEN 0xFFFF0001 +#define cOCTRPC_RDBGERR_PROTOCOL_NUMBER 0xFFFF0002 +#define cOCTRPC_RDBGERR_NO_COMMAND_HEADER 0xFFFF0003 +#define cOCTRPC_RDBGERR_INTERFACE_TYPE 0xFFFF0004 +#define cOCTRPC_RDBGERR_INTERFACE_VERSION 0xFFFF0005 +#define cOCTRPC_RDBGERR_INVALID_PACKET_LENGTH 0xFFFF0006 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_LENGTH 0xFFFF0007 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_NUMBER 0xFFFF0008 +#define cOCTRPC_RDBGERR_PACKET_TOO_LARGE 0xFFFF0009 +#define cOCTRPC_RDBGERR_LIST_EMPTY 0xFFFF000A + +#define cOCTRPC_RDBGERR_FATAL 0xFFFFFFFF + + +/***************************** TYPES ***************************************/ + +typedef struct _OCTRPC_OGRDTP_HEADER_ +{ + UINT32 IN ulEndianDetect; + UINT32 IN ulDebugSessionNum; + UINT32 IN ulTransactionNum; + UINT32 IN ulPktRetryNum; + UINT32 IN ulPktByteSize; + UINT32 IN ulChecksum; + UINT32 OUT ulParsingError; + UINT32 IN ulRpcProtocolNum; + +} tOCTRPC_OGRDTP_HEADER, *tPOCTRPC_OGRDTP_HEADER; + +typedef struct _OCTRPC_INTERFACE_HEADER_ +{ + UINT32 IN ulInterfaceType; + UINT32 IN ulInterfaceVersion; + +} tOCTRPC_INTERFACE_HEADER, *tPOCTRPC_INTERFACE_HEADER; + +typedef struct _OCTRPC_COMMAND_HEADER_ +{ + UINT32 IN ulCommandByteSize; + UINT32 IN OUT ulRpcCommandNum; + UINT32 OUT ulFunctionResult; + +} tOCTRPC_COMMAND_HEADER, *tPOCTRPC_COMMAND_HEADER; + +#endif /* __RPC_PROTOCOL_H__ */ diff --git a/xpp/oct612x/include/octtype.h b/xpp/oct612x/include/octtype.h new file mode 100644 index 0000000..7bed715 --- /dev/null +++ b/xpp/oct612x/include/octtype.h @@ -0,0 +1,159 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtype.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTTYPE_H__ +#define __OCTTYPE_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------- + Include target-specific header if available +----------------------------------------------------------------------------*/ +#if defined( OCT_NTDRVENV ) + #include "octtypentdrv.h" /* All NT driver typedef */ +#elif defined( OCT_WINENV ) + #include "octtypewin.h" /* All Win32 typedef */ +#elif defined( OCT_VXENV ) + #include "octtypevx.h" /* All VxWorks typedef */ +#else +/*-------------------------------------------------------------------------- + No target-specific header available +----------------------------------------------------------------------------*/ + +#ifdef SZ +#undef SZ +#endif + +/***************************** DEFINES *************************************/ +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + + +/* 32 bit integer */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer */ +typedef signed long LONG; +typedef unsigned long ULONG; +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +typedef unsigned char BYTE; +typedef BYTE * PBYTE; +typedef unsigned char UCHAR; + +/* Character and strings */ +typedef char CHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef CHAR * PCHAR; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void VOID; +typedef void * PVOID; + +/* Booleans */ +typedef int BOOL; +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int UINT; +typedef unsigned int * PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +#if defined(__FreeBSD__) +#include +#else +#include +#endif + +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPE_H__ */ diff --git a/xpp/oct612x/include/octtypevx.h b/xpp/oct612x/include/octtypevx.h new file mode 100644 index 0000000..6588ae2 --- /dev/null +++ b/xpp/oct612x/include/octtypevx.h @@ -0,0 +1,132 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypevx.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the VxWorks environment. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEVX_H__ +#define __OCTTYPEVX_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" + +/* 16-bit pointer integer */ +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer pointer */ +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +/* 32-bit integer pointer */ +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer pointer */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef long LONG; +#endif +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer pointer */ +typedef short SHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +#if (CPU!=SIMNT) && !defined(DATATYPE_H) +typedef char BYTE; +#endif + + +typedef BYTE * PBYTE; + +/* Character and strings */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef char CHAR; +#endif +typedef char * PCHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef signed char OCT_INT8; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void * PVOID; + +/* Booleans */ +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEVX_H__ */ diff --git a/xpp/oct612x/include/octtypewin.h b/xpp/oct612x/include/octtypewin.h new file mode 100644 index 0000000..8bdd690 --- /dev/null +++ b/xpp/oct612x/include/octtypewin.h @@ -0,0 +1,100 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypewin.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the Windows environment. + Includes the Windows definition file and add the missing ones here. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEWIN_H__ +#define __OCTTYPEWIN_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#define WIN32_LEAN_AND_MEAN /* just get the base type definition from Windows */ +#include + +/* Disable argument not used warning */ +#pragma warning( disable : 4100 ) +/* Disable Level 4 warning: nonstandard extension used : translation unit is empty */ +#pragma warning( disable : 4206 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +typedef double DOUBLE; + + +/* 32 bit integer */ +#if ( defined( _MSC_VER ) && _MSC_VER == 1100 ) +/* MFC5 compiler does not define UINT32 */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; +#endif /* _MSC_VER */ + +/* LONG LONG */ +#define LLONG signed __int64 +#define PLLONG signed __int64 * +#define ULLONG unsigned __int64 +#define PULLONG unsigned __int64 * + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEWIN_H__ */ diff --git a/xpp/oct612x/octasic-helper b/xpp/oct612x/octasic-helper new file mode 100755 index 0000000..ab100d1 --- /dev/null +++ b/xpp/oct612x/octasic-helper @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Jeffrey C. Ollie +# +# $1 == information requested +# $2 == path to octasic directory +# + +APIDIR=$2/octdeviceapi/oct6100api/oct6100_api + +case $1 in + objects) + echo $APIDIR/oct6100_adpcm_chan.o \ + $APIDIR/oct6100_channel.o \ + $APIDIR/oct6100_chip_open.o \ + $APIDIR/oct6100_chip_stats.o \ + $APIDIR/oct6100_conf_bridge.o \ + $APIDIR/oct6100_debug.o \ + $APIDIR/oct6100_events.o \ + $APIDIR/oct6100_interrupts.o \ + $APIDIR/oct6100_memory.o \ + $APIDIR/oct6100_miscellaneous.o \ + $APIDIR/oct6100_mixer.o \ + $APIDIR/oct6100_phasing_tsst.o \ + $APIDIR/oct6100_playout_buf.o \ + $APIDIR/oct6100_remote_debug.o \ + $APIDIR/oct6100_tlv.o \ + $APIDIR/oct6100_tone_detection.o \ + $APIDIR/oct6100_tsi_cnct.o \ + $APIDIR/oct6100_tsst.o \ + $2/apilib/bt/octapi_bt0.o \ + $2/apilib/largmath/octapi_largmath.o \ + $2/apilib/llman/octapi_llman.o + ;; + cflags) + echo -I$2/include -I$2/octdeviceapi -I$2/octdeviceapi/oct6100api + ;; +esac diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h new file mode 100644 index 0000000..a078070 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h @@ -0,0 +1,131 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_adpcm_chan.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_adpcm_chan_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PRIV_H__ +#define __OCT6100_ADPCM_CHAN_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* ADPCM channel list pointer macros. */ +#define mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst ); + +#define mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst)) + ulIndex; + +#define mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + + +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ); + +#endif /* __OCT6100_ADPCM_CHAN_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c new file mode 100644 index 0000000..aec4c5e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c @@ -0,0 +1,1237 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close ADPCM channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpen + +Description: This function opens an ADPCM channel between two TDM timeslots. + This channel will perform ADPCM compression or decompression + depending on the channel mode. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenDef +UINT32 Oct6100AdpcmChanOpenDef( + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + f_pAdpcmChanOpen->pulChanHndl = NULL; + + f_pAdpcmChanOpen->ulInputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulInputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulInputNumTssts = 1; + f_pAdpcmChanOpen->ulInputPcmLaw = cOCT6100_PCM_U_LAW; + + f_pAdpcmChanOpen->ulOutputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulOutputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulOutputPcmLaw = cOCT6100_PCM_U_LAW; + f_pAdpcmChanOpen->ulOutputNumTssts = 1; + + f_pAdpcmChanOpen->ulChanMode = cOCT6100_ADPCM_ENCODING; + f_pAdpcmChanOpen->ulEncodingRate = cOCT6100_G726_32KBPS; + f_pAdpcmChanOpen->ulDecodingRate = cOCT6100_G726_32KBPS; + + f_pAdpcmChanOpen->ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanOpen +UINT32 Oct6100AdpcmChanOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanOpenSer( f_pApiInstance, f_pAdpcmChanOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanClose + +Description: This function closes an opened ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseDef +UINT32 Oct6100AdpcmChanCloseDef( + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanClose +UINT32 Oct6100AdpcmChanClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanCloseSer( f_pApiInstance, f_pAdpcmChanClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetAdpcmChanSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetAdpcmChanSwSizes +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API ADPCM channel list.*/ + f_pInstSizes->ulAdpcmChannelList = f_pOpenChip->ulMaxAdpcmChannels * sizeof( tOCT6100_API_ADPCM_CHAN ); + + if ( f_pOpenChip->ulMaxAdpcmChannels > 0 ) + { + /* Calculate memory needed for ADPCM memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxAdpcmChannels, &f_pInstSizes->ulAdpcmChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_48; + } + else + { + f_pInstSizes->ulAdpcmChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAdpcmChanSwInit + +Description: Initializes all elements of the instance structure associated + to the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAdpcmChanSwInit +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_ADPCM_CHAN pChannelsTsiList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxAdpcmChannels; + PVOID pAdpcmChannelsAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ADPCM channel API list.*/ + ulMaxAdpcmChannels = pSharedInfo->ChipConfig.usMaxAdpcmChannels; + + /* Set all entries in the ADPCM channel list to unused. */ + mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pChannelsTsiList ) + + /* Clear the memory */ + Oct6100UserMemSet( pChannelsTsiList, 0x00, sizeof(tOCT6100_API_ADPCM_CHAN) * ulMaxAdpcmChannels ); + + /* Initialize the ADPCM channel allocation structures to "all free". */ + if ( ulMaxAdpcmChannels > 0 ) + { + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChannelsAlloc ) + + ulResult = OctapiLlmAllocInit( &pAdpcmChannelsAlloc, ulMaxAdpcmChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BD; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpenSer + +Description: Opens an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to an ADPCM channel open structure + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenSer +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the ADPCM channel open structure for errors. */ + ulResult = Oct6100ApiCheckAdpcmChanParams( f_pApiInstance, f_pAdpcmChanOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the ADPCM channel. */ + ulResult = Oct6100ApiReserveAdpcmChanResources( f_pApiInstance, f_pAdpcmChanOpen, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the ADPCM channel. */ + ulResult = Oct6100ApiWriteAdpcmChanStructs( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the ADPCM channel entry in the API list. */ + ulResult = Oct6100ApiUpdateAdpcmChanEntry( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckAdpcmChanParams + +Description: Checks the user's ADPCM channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckAdpcmChanParams +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxAdpcmChannels == 0 ) + return cOCT6100_ERR_ADPCM_CHAN_DISABLED; + + if ( f_pAdpcmChanOpen->pulChanHndl == NULL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Check the input TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulInputNumTssts != 1 && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputNumTssts, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM; + } + else + { + return ulResult; + } + } + + if( f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW; + + /* Check the output TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulOutputNumTssts != 1 && + f_pAdpcmChanOpen->ulOutputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM; + } + else + { + return ulResult; + } + } + if( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW; + + /* Now, check the channel mode. */ + if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_ENCODING && + f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) + return cOCT6100_ERR_ADPCM_CHAN_MODE; + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + /* Check the encoding rate. */ + if ( ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + /* Check the decoding rate. */ + if ( f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE; + + /* Make sure that two timeslots are allocated if PCM-ECHO encoded is selected. */ + if ( (f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS; + } + + /* Check the nibble position. */ + if ( f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanResources + +Description: Reserves all resources needed for the new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanResources +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + BOOL fAdpcmChanEntry = FALSE; + BOOL fAdpcmMemEntry = FALSE; + BOOL fTsiMemEntry = FALSE; + BOOL fInputTsst = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReserveAdpcmChanEntry( f_pApiInstance, f_pusAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmChanEntry = TRUE; + + /* Find a TSI memory entry.*/ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, f_pusTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiMemEntry = TRUE; + + /* Find a conversion memory entry. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, f_pusAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmMemEntry = TRUE; + + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + f_pusInputTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fInputTsst = TRUE; + + /* Reserve the output TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + f_pAdpcmChanOpen->ulOutputNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusOutputTsstIndex, + NULL ); + } + } + } + else + { + /* Return an error other than a fatal error. */ + ulResult = cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE; + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if( fAdpcmChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, *f_pusAdpcmChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, *f_pusTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fAdpcmMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, *f_pusAdpcmMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fInputTsst == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteAdpcmChanStructs + +Description: Performs all the required structure writes to configure the + new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteAdpcmChanStructs +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulCompType = 0; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Configure the TSST control memory. */ + + /* Set the input TSST control entry. */ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usInputTsstIndex, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulInputPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry. */ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usOutputTsstIndex, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Configure the ADPCM memory. */ + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + switch( f_pAdpcmChanOpen->ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + + if ( f_pAdpcmChanOpen->ulOutputPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* if ( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW ) */ + ulCompType = 0x5; + break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_40KBPS_4_1: ulCompType = 0xD; break; + case cOCT6100_G727_40KBPS_3_2: ulCompType = 0xA; break; + case cOCT6100_G727_40KBPS_2_3: ulCompType = 0x6; break; + case cOCT6100_G727_32KBPS_4_0: ulCompType = 0xE; break; + case cOCT6100_G727_32KBPS_3_1: ulCompType = 0xB; break; + case cOCT6100_G727_32KBPS_2_2: ulCompType = 0x7; break; + case cOCT6100_G727_24KBPS_3_0: ulCompType = 0xC; break; + case cOCT6100_G727_24KBPS_2_1: ulCompType = 0x8; break; + case cOCT6100_G727_16KBPS_2_0: ulCompType = 0x9; break; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + FALSE, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + cOCT6100_INVALID_INDEX, + cOCT6100_INVALID_VALUE, + cOCT6100_INVALID_VALUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + switch( f_pAdpcmChanOpen->ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: ulCompType = 0x8; break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_2C_ENCODED: ulCompType = 0x4; break; + case cOCT6100_G727_3C_ENCODED: ulCompType = 0x5; break; + case cOCT6100_G727_4C_ENCODED: ulCompType = 0x6; break; + case cOCT6100_G726_ENCODED: ulCompType = 0x9; break; + case cOCT6100_G711_G726_ENCODED: ulCompType = 0xA; break; + case cOCT6100_G711_G727_2C_ENCODED: ulCompType = 0xC; break; + case cOCT6100_G711_G727_3C_ENCODED: ulCompType = 0xD; break; + case cOCT6100_G711_G727_4C_ENCODED: ulCompType = 0xE; break; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulOutputPcmLaw, + f_pAdpcmChanOpen->ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateAdpcmChanEntry + +Description: Updates the new ADPCM channel in the ADPCM channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. +f_usAdpcmChanIndex Allocated entry in the ADPCM channel list. +f_usAdpcmMemIndex Allocated entry in ADPCM memory. +f_usTsiMemIndex Allocated entry in TSI chariot memory. +f_usInputTsstIndex TSST control memory index of the input TSST. +f_usOutputTsstIndex TSST control memory index of the output TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateAdpcmChanEntry +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + + /*------------------------------------------------------------------------------*/ + /* Obtain a pointer to the new ADPCM channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( f_pApiInstance->pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ) + + /* Copy the buffer's configuration and allocated resources. */ + pAdpcmChanEntry->usInputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulInputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usInputStream = (UINT16)( f_pAdpcmChanOpen->ulInputStream & 0xFFFF ); + pAdpcmChanEntry->byInputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulInputNumTssts & 0xFF ); + pAdpcmChanEntry->byInputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulInputPcmLaw & 0xFF ); + + pAdpcmChanEntry->usOutputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulOutputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usOutputStream = (UINT16)( f_pAdpcmChanOpen->ulOutputStream & 0xFFFF ); + pAdpcmChanEntry->byOutputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulOutputNumTssts & 0xFF ); + pAdpcmChanEntry->byOutputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulOutputPcmLaw & 0xFF ); + + /* Store hardware related information. */ + pAdpcmChanEntry->usTsiMemIndex = f_usTsiMemIndex; + pAdpcmChanEntry->usAdpcmMemIndex = f_usAdpcmMemIndex; + pAdpcmChanEntry->usInputTsstIndex = f_usInputTsstIndex; + pAdpcmChanEntry->usOutputTsstIndex = f_usOutputTsstIndex; + + /* Form handle returned to user. */ + *f_pAdpcmChanOpen->pulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usAdpcmChanIndex; + + /* Finally, mark the ADPCM channel as opened. */ + pAdpcmChanEntry->fReserved = TRUE; + + /* Increment the number of ADPCM channel opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans++; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanCloseSer + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseSer +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertAdpcmChanParams( f_pApiInstance, f_pAdpcmChanClose, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiInvalidateAdpcmChanStructs( f_pApiInstance, usAdpcmMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiReleaseAdpcmChanResources( f_pApiInstance, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertAdpcmChanParams + +Description: Validate the handle given by the user and verify the state of + the ADPCM channel about to be closed. + Also return all required information to deactivate the channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pAdpcmChanClose Pointer to ADPCM channel close structure. +f_pusAdpcmChanIndex Index of the ADPCM channel structure in the API list. +f_pusAdpcmMemIndex Index of the ADPCM memory structure in the API list. +f_pusTsiMemIndex Index of the TSI chariot memory used for this channel. +f_pusInputTsstIndex Index of the input entry in the TSST control memory. +f_pusOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertAdpcmChanParams +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_ADPCM_CHANNEL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + *f_pusAdpcmChanIndex = (UINT16)( f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_INDEX_MASK ); + + if ( *f_pusAdpcmChanIndex >= pSharedInfo->ChipConfig.usMaxAdpcmChannels ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /*------------------------------------------------------------------------------*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, *f_pusAdpcmChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pAdpcmChanClose->ulChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pAdpcmChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pAdpcmChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Return info needed to close the channel and release all resources. */ + *f_pusInputTsstIndex = pAdpcmChanEntry->usInputTsstIndex; + *f_pusOutputTsstIndex = pAdpcmChanEntry->usOutputTsstIndex; + *f_pusTsiMemIndex = pAdpcmChanEntry->usTsiMemIndex; + *f_pusAdpcmMemIndex = pAdpcmChanEntry->usAdpcmMemIndex; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateAdpcmChanStructs + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usAdpcmMemIndex Index of the ADPCM memory. +f_usInputTsstIndex Index of the input entry in the TSST control memory. +f_usOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateAdpcmChanStructs +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usInputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usOutputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the ADPCM memory. */ + + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanResources + +Description: Release and clear the API entry associated to the ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulAdpcmChanIndex Index of the ADPCM channel in the API list. +f_usAdpcmMemIndex Index of the ADPCM memory used. +f_usTsiMemIndex Index of the TSI memory used. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanResources +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ); + + /*------------------------------------------------------------------------------*/ + /* Release all resources associated with ADPCM channel. */ + + /* Release the entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, f_usAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, f_usTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the input TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usInputTimeslot, + pAdpcmChanEntry->usInputStream, + pAdpcmChanEntry->byInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the output TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usOutputTimeslot, + pAdpcmChanEntry->usOutputStream, + pAdpcmChanEntry->byOutputNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + } + } + } + } + + /* Check if an error occured while releasing the reserved resources. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult >= cOCT6100_ERR_FATAL ) + return ulResult; + else + return cOCT6100_ERR_FATAL_4A; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Update the ADPCM channel's list entry. */ + + /* Mark the channel as closed. */ + pAdpcmChanEntry->fReserved = FALSE; + pAdpcmChanEntry->byEntryOpenCnt++; + + /* Decrement the number of ADPCM channels opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans--; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanEntry + +Description: Reserves one of the ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusAdpcmChanIndex Resulting index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanEntry +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + UINT32 ulAdpcmChanIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pAdpcmChanAlloc, &ulAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_BE; + } + + *f_pusAdpcmChanIndex = (UINT16)( ulAdpcmChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanEntry + +Description: Releases the specified ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usAdpcmChanIndex Index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanEntry +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pAdpcmChanAlloc, f_usAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_BF; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c new file mode 100644 index 0000000..2a9f940 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c @@ -0,0 +1,13858 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open, modify and close echo + cancellation channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 492 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#if defined(__FreeBSD__) +#include +#include +#else +#ifndef __KERNEL__ +#include +#include +#define kmalloc(size, type) malloc(size) +#define kfree(ptr) free(ptr) +#define GFP_ATOMIC 0 /* Dummy */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#else +#include +#include +#endif +#endif + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_tsst_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_playout_buf_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_debug_priv.h" + + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpen + +Description: This function opens a echo cancellation channel. An echo cancellation + channel is constituted of two voice stream (RIN/ROUT and SIN/SOUT), and + an echo cancelling core. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenDef +UINT32 Oct6100ChannelOpenDef( + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + f_pChannelOpen->pulChannelHndl = NULL; + f_pChannelOpen->ulUserChanId = cOCT6100_INVALID_VALUE; + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + f_pChannelOpen->fEnableToneDisabler = FALSE; + f_pChannelOpen->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = -10; + f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + f_pChannelOpen->VqeConfig.fEnableNlp = TRUE; + f_pChannelOpen->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelOpen->VqeConfig.ulTailDisplacement = cOCT6100_AUTO_SELECT_TAIL; + f_pChannelOpen->VqeConfig.ulTailLength = cOCT6100_AUTO_SELECT_TAIL; + + f_pChannelOpen->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelOpen->VqeConfig.fAcousticEcho = FALSE; + f_pChannelOpen->VqeConfig.lDefaultErlDb = -6; + f_pChannelOpen->VqeConfig.ulAecTailLength = 128; + f_pChannelOpen->VqeConfig.lAecDefaultErlDb = 0; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA = 1; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB = 0; + f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior = cOCT6100_DOUBLE_TALK_BEH_NORMAL; + f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelOpen->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = -18; + f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb = -18; + f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation = 6; + f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay = 300; + f_pChannelOpen->VqeConfig.fEnableMusicProtection = FALSE; + /* Older images have idle code detection hard-coded to enabled. */ + f_pChannelOpen->VqeConfig.fIdleCodeDetection = TRUE; + + /* TDM configuration.*/ + f_pChannelOpen->TdmConfig.ulRinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulRoutNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSoutNumTssts = 1; + + f_pChannelOpen->TdmConfig.ulRinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulRoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutPcmLaw = cOCT6100_PCM_U_LAW; + + /* CODEC configuration.*/ + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + f_pChannelOpen->CodecConfig.ulEncoderPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pChannelOpen->CodecConfig.ulEncodingRate = cOCT6100_G711_64KBPS; + f_pChannelOpen->CodecConfig.ulDecoderPort = cOCT6100_CHANNEL_PORT_RIN; + f_pChannelOpen->CodecConfig.ulDecodingRate = cOCT6100_G711_64KBPS; + + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + f_pChannelOpen->CodecConfig.ulPhase = 1; + f_pChannelOpen->CodecConfig.ulPhasingType = cOCT6100_NO_PHASING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelOpen +UINT32 Oct6100ChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelOpenSer( f_pApiInstance, f_pChannelOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelClose + +Description: This function closes an echo canceller channel + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseDef +UINT32 Oct6100ChannelCloseDef( + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelClose +UINT32 Oct6100ChannelClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCloseSer( f_pApiInstance, f_pChannelClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModify + +Description: This function will modify the parameter of an echo channel. If + the call to this channel allows the channel to go from power down + to enable, the API will activate it. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo channel change structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifyDef +UINT32 Oct6100ChannelModifyDef( + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + f_pChannelModify->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelModify->ulUserChanId = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->ulEchoOperationMode = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fEnableToneDisabler = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fApplyToAllChannels = FALSE; + + f_pChannelModify->fDisableToneDetection = FALSE; + f_pChannelModify->fStopBufferPlayout = FALSE; + f_pChannelModify->fRemoveConfBridgeParticipant = FALSE; + f_pChannelModify->fRemoveBroadcastTssts = FALSE; + + f_pChannelModify->fTdmConfigModified = FALSE; + f_pChannelModify->fVqeConfigModified = FALSE; + f_pChannelModify->fCodecConfigModified = FALSE; + + /* VQE config. */ + f_pChannelModify->VqeConfig.fSinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinHighLevelCompensation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinHighLevelCompensationThresholdDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAdaptiveNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNoiseBleaching = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutConferencingNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulComfortNoiseMode = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableNlp = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fDtmfToneRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fAcousticEcho = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAecTailLength = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAecDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulDoubleTalkBehavior = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNaturalListenerEnhancement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRoutNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableMusicProtection = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fIdleCodeDetection = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* TDM config. */ + f_pChannelModify->TdmConfig.ulRinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* CODEC config. */ + f_pChannelModify->CodecConfig.ulEncoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulEncodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->CodecConfig.fEnableSilenceSuppression = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingTsstHndl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhase = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingType = cOCT6100_KEEP_PREVIOUS_SETTING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelModify +UINT32 Oct6100ChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Check the apply to all channels flag first. */ + if ( f_pChannelModify->fApplyToAllChannels != TRUE && + f_pChannelModify->fApplyToAllChannels != FALSE ) + return cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS; + + /* Check if must apply modification to all channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + tPOCT6100_API_CHANNEL pChanEntry; + UINT16 usChanIndex; + + /* Loop through all channels and look for the opened ones. */ + for ( usChanIndex = 0; usChanIndex < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; usChanIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ); + + /* Check if this one is opened. */ + if ( pChanEntry->fReserved == TRUE ) + { + /* Channel is opened. Form handle and call actual modify function. */ + f_pChannelModify->ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | usChanIndex; + + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + if ( ulFncRes != cOCT6100_ERR_OK ) + break; + } + } + } + else /* if ( f_pChannelModify->fApplyToAllChannels == FALSE ) */ + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + } + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDir + +Description: This function creates a bidirectional channel using two standard + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to channel create BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirDef +UINT32 Oct6100ChannelCreateBiDirDef( + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + f_pChannelCreateBiDir->pulBiDirChannelHndl = NULL; + + f_pChannelCreateBiDir->ulFirstChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelCreateBiDir->ulSecondChannelHndl = cOCT6100_INVALID_HANDLE; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelCreateBiDir +UINT32 Oct6100ChannelCreateBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCreateBiDirSer( f_pApiInstance, f_pChannelCreateBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDir + +Description: This function destroys a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to channel destroy BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirDef +UINT32 Oct6100ChannelDestroyBiDirDef( + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelDestroyBiDir +UINT32 Oct6100ChannelDestroyBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, f_pChannelDestroyBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAdd + +Description: This function adds a TSST to one of the two output ports of a channel. + This TSST can never be modified by a call to Oct6100ChannelModify. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstAdd Pointer to the an Add Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddDef +UINT32 Oct6100ChannelBroadcastTsstAddDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + f_pChannelBroadcastTsstAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstAdd->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstAdd->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstAdd->ulStream = cOCT6100_INVALID_STREAM; + + return cOCT6100_ERR_OK; + +} +#endif + +#if !SKIP_Oct6100ChannelBroadcastTsstAdd +UINT32 Oct6100ChannelBroadcastTsstAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstAddSer( f_pApiInstance, f_pChannelBroadcastTsstAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemove + +Description: This function removes a TSST from one of the two output ports of a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstRemove Pointer to the a Remove Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveDef +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + f_pChannelBroadcastTsstRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstRemove->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstRemove->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstRemove->ulStream = cOCT6100_INVALID_STREAM; + + f_pChannelBroadcastTsstRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChannelBroadcastTsstRemove +UINT32 Oct6100ChannelBroadcastTsstRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, f_pChannelBroadcastTsstRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelGetStats + +Description: This function retrieves all the config and stats related to the channel + designated by ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a tOCT6100_CHANNEL_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelGetStatsDef +UINT32 Oct6100ChannelGetStatsDef( + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + f_pChannelStats->fResetStats = FALSE; + + f_pChannelStats->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelStats->ulUserChanId = cOCT6100_INVALID_STAT; + f_pChannelStats->ulEchoOperationMode = cOCT6100_INVALID_STAT; + f_pChannelStats->fEnableToneDisabler = FALSE; + f_pChannelStats->ulMutePortsMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + f_pChannelStats->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = FALSE; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelStats->VqeConfig.ulTailDisplacement = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulTailLength = cOCT6100_INVALID_STAT; + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelStats->VqeConfig.fAcousticEcho = FALSE; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + + f_pChannelStats->VqeConfig.ulComfortNoiseMode = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAecTailLength = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fEnableMusicProtection = FALSE; + f_pChannelStats->VqeConfig.fIdleCodeDetection = FALSE; + + + + /* TDM configuration.*/ + f_pChannelStats->TdmConfig.ulMaxBroadcastTssts = 0; + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = 0; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = 0; + + f_pChannelStats->TdmConfig.ulRinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutNumTssts = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulSinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream = NULL; + + f_pChannelStats->TdmConfig.ulSoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream = NULL; + + + /* CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.ulEncoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulEncodingRate = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecodingRate = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhase = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhasingType = cOCT6100_INVALID_STAT; + + f_pChannelStats->ulNumEchoPathChanges = cOCT6100_INVALID_STAT; + f_pChannelStats->ulToneDisablerStatus = cOCT6100_INVALID_STAT; + f_pChannelStats->fEchoCancellerConverged = FALSE; + f_pChannelStats->fSinVoiceDetected = FALSE; + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lRinAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSoutAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lComfortNoiseLevel = cOCT6100_INVALID_SIGNED_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelGetStats +UINT32 Oct6100ChannelGetStats( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ApiChannelGetStatsSer( f_pApiInstance, f_pChannelStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMute + +Description: This function mutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelMute Pointer to a tPOCT6100_CHANNEL_MUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteDef +UINT32 Oct6100ChannelMuteDef( + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + f_pChannelMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelMute +UINT32 Oct6100ChannelMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelMuteSer( f_pApiInstance, f_pChannelMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMute + +Description: This function unmutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelUnMute Pointer to a tPOCT6100_CHANNEL_UNMUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteDef +UINT32 Oct6100ChannelUnMuteDef( + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + f_pChannelUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelUnMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelUnMute +UINT32 Oct6100ChannelUnMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelUnMuteSer( f_pApiInstance, f_pChannelUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChannelsEchoSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChannelsEchoSwSizes +UINT32 Oct6100ApiGetChannelsEchoSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + UINT32 ulMaxChannels; + + ulMaxChannels = f_pOpenChip->ulMaxChannels; + + if ( f_pOpenChip->fEnableChannelRecording == TRUE && ulMaxChannels != 672 ) + ulMaxChannels++; + + /* Determine the amount of memory required for the API echo channel list.*/ + f_pInstSizes->ulChannelList = ulMaxChannels * sizeof( tOCT6100_API_CHANNEL ); /* Add one for the record channel.*/ + f_pInstSizes->ulBiDirChannelList = f_pOpenChip->ulMaxBiDirChannels * sizeof( tOCT6100_API_BIDIR_CHANNEL ); + if ( ulMaxChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( ulMaxChannels, &f_pInstSizes->ulChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulChannelAlloc = 0; + } + if ( f_pOpenChip->ulMaxBiDirChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxBiDirChannels, &f_pInstSizes->ulBiDirChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulBiDirChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelAlloc, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelAlloc, ulTempVar ) + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelsEchoSwInit + +Description: Initializes all elements of the instance structure associated + to the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelsEchoSwInit +UINT32 Oct6100ApiChannelsEchoSwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_CHANNEL pChannelsEchoList; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChannelsList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT16 usMaxChannels; + PVOID pEchoChanAlloc; + PVOID pBiDirChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ECHO channel API list.*/ + usMaxChannels = pSharedInfo->ChipConfig.usMaxChannels; + + /* add a channel to initialize if the recording is activated. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + usMaxChannels++; + + /* Set all entries in the ADCPM channel list to unused. */ + mOCT6100_GET_CHANNEL_LIST_PNT( pSharedInfo, pChannelsEchoList ); + + /* Initialize the API ECHO channels allocation software to "all free". */ + if ( usMaxChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pChannelsEchoList, 0x00, sizeof(tOCT6100_API_CHANNEL) * usMaxChannels ); + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pEchoChanAlloc, usMaxChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1; + } + + mOCT6100_GET_BIDIR_CHANNEL_LIST_PNT( pSharedInfo, pBiDirChannelsList ); + + if ( pSharedInfo->ChipConfig.usMaxBiDirChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pBiDirChannelsList, 0x00, sizeof(tOCT6100_API_BIDIR_CHANNEL) * pSharedInfo->ChipConfig.usMaxBiDirChannels ); + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pBiDirChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pBiDirChanAlloc, pSharedInfo->ChipConfig.usMaxBiDirChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A9; + + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpenSer + +Description: Opens a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to channel configuration structure. Then handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenSer +UINT32 Oct6100ChannelOpenSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_API_ECHO_CHAN_INDEX *ChannelIndexConf; + UINT32 ulResult; + + ChannelIndexConf = kmalloc(sizeof(*ChannelIndexConf), GFP_ATOMIC); + + if (!ChannelIndexConf) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelParams( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiReserveChannelResources( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelStructs( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateChannelEntry( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + kfree(ChannelIndexConf); + return cOCT6100_ERR_OK; + +out: + kfree(ChannelIndexConf); + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelParams + +Description: Checks the user's echo cancellation channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel open configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelParams +UINT32 Oct6100ApiCheckChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + UINT32 ulDecoderNumTssts; + UINT32 ulResult; + + /* Dereference the configuration structure for clearer code and faster access.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels == 0 ) + return cOCT6100_ERR_CHANNEL_DISABLED; + + if ( f_pChannelOpen->pulChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelOpen->fEnableToneDisabler != TRUE && + f_pChannelOpen->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the extended Tone Detection flag value.*/ + if ( f_pChannelOpen->fEnableExtToneDetection != TRUE && + f_pChannelOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION; + + /* Check that extented tone detection is actually enabled by the user. */ + if ( ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) && + ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableExtToneDetection == FALSE ) ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED; + + + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, pTdmConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now validate the VQE parameters */ + + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, pVqeConfig, f_pChannelOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Finally, validate the CODEC configuration.*/ + + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = pTdmConfig->ulRinNumTssts; + else /* pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = pTdmConfig->ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, pCodecConfig, ulDecoderNumTssts, &f_pChanIndexConf->usPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( pCodecConfig->fEnableSilenceSuppression == TRUE && pVqeConfig->fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if law conversion is allowed. */ + if ( pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING || + pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* No law conversion can occurs if one ADPCM memory is not reserved.*/ + if ( pTdmConfig->ulRinPcmLaw != pTdmConfig->ulRoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + + if ( pTdmConfig->ulSinPcmLaw != pTdmConfig->ulSoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + } + + /* Verify if the config supports extended tone detection.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelResources + +Description: Reserves all resources needed for the new channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pulChannelIndex Allocated entry in ECHO channel list. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelResources +UINT32 Oct6100ApiReserveChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + UINT32 ulResult; + UINT32 ulTempVar; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinTsstEntry = FALSE; + BOOL fSinTsstEntry = FALSE; + BOOL fRoutTsstEntry = FALSE; + BOOL fSoutTsstEntry = FALSE; + + BOOL fRinRoutTsiMemEntry = FALSE; + BOOL fSinSoutTsiMemEntry = FALSE; + + BOOL fEchoChanEntry = FALSE; + + PUINT16 pusRinRoutConversionMemIndex = NULL; + PUINT16 pusSinSoutConversionMemIndex = NULL; + BOOL fRinRoutConversionMemEntry = FALSE; + BOOL fSinSoutConversionMemEntry = FALSE; + + BOOL fExtToneChanEntry = FALSE; + BOOL fExtToneTsiEntry = FALSE; + BOOL fExtToneMixerEntry = FALSE; + + /* Obtain a local pointer to the configuration structures.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /*===============================================================================*/ + /* Reserve Echo and TSI entries. */ + + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fEchoChanEntry = TRUE; + + /* Set the echo, encoder and decoder memory indexes.*/ + f_pChanIndexConf->usEchoMemIndex = f_pChanIndexConf->usEchoChanIndex; + + /* Reserve an entry for the RIN/ROUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutTsiMemEntry = TRUE; + + /* Reserve an entry for the SIN/SOUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutTsiMemEntry = TRUE; + + /* Reserve an ADPCM memory block for compression if required.*/ + if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + /* Reserve an ADPCM memory block for decompression if required.*/ + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + + /* Reserve the conversion memories. */ + if ( pusRinRoutConversionMemIndex != NULL ) + { + /* Reserve a conversion memory for the Rin/Rout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pusSinSoutConversionMemIndex != NULL ) && + ( ulResult == cOCT6100_ERR_OK ) ) + { + /* Reserve a conversion memory for the Sin/Sout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Reserve any resources required if the extended Tone detection is enabled.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneChanEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneTsiEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtToneMixerEntry = TRUE; + } + } + } + else + { + f_pChanIndexConf->usExtToneChanIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneMixerIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneTsiIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Now reserve the TSST entries if required.*/ + + /* Reserve the Rin TSST entry */ + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED) ) + { + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sin TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Rout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( f_pChanIndexConf->usRinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + if ( f_pChanIndexConf->usSinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved resources .*/ + if( fRinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRinRoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if( fEchoChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved resources for the extended tone detection.*/ + if( fExtToneChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneTsiEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneMixerEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the conversion resources. */ + if( fRinRoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelStructs +UINT32 Oct6100ApiWriteChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulDwordAddress; + UINT32 ulDwordData; + BOOL fProgramAdpcmMem; + UINT32 ulCompType = 0; + UINT32 ulPcmLaw; + UINT16 usTempTsiMemIndex; + UINT16 usConversionMemIndex; + UINT32 ulToneEventNumber; + BOOL fSSTone; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the TDM configuration structure.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ); + + /*==============================================================================*/ + /* Configure the Input Tsst control memory.*/ + + /* Set the RIN Tsst control entry.*/ + if ( f_pChanIndexConf->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + pTdmConfig->ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SIN Tsst control entry.*/ + if ( f_pChanIndexConf->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSinTsstIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex, + pTdmConfig->ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Decoder.*/ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = FALSE; + f_pChanIndexConf->fSinSoutCodecActive = FALSE; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + break; + default: + return cOCT6100_ERR_FATAL_D4; + } + + if ( fProgramAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulRoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulSoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Encoder */ + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pTdmConfig->ulRoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( pTdmConfig->ulSoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + break; + + default: + return cOCT6100_ERR_FATAL_D5; + } + + /* Program the APDCM memory only if ADPCM is requried.*/ + if ( fProgramAdpcmMem == TRUE || f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + f_pChanIndexConf->usPhasingTsstIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usEchoChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the VQE memory */ + + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Write the echo memory */ + + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + pTdmConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoMemIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + /* Initialize the silence indexes to invalid for now. */ + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + + /* Set the TSI memory indexes. */ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the dominant speaker to unassigned, if required. */ + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled == TRUE ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_pChanIndexConf->usEchoChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the extended tone detection channel.*/ + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + UINT32 ulTempSinLaw; + UINT32 ulTempSoutLaw; + UINT32 ulTempEchoOpMode; + + /* save the original law.*/ + ulTempSinLaw = pTdmConfig->ulSinPcmLaw; + ulTempSoutLaw = pTdmConfig->ulSoutPcmLaw; + ulTempEchoOpMode = f_pChannelOpen->ulEchoOperationMode; + + /* Now, make sure the Sin and Sout law are the same as the Rin law.*/ + + pTdmConfig->ulSinPcmLaw = pTdmConfig->ulRinPcmLaw; + pTdmConfig->ulSoutPcmLaw = pTdmConfig->ulRinPcmLaw; + + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + /* Write the Echo and VQE memory of the extended channel.*/ + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + pTdmConfig, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usExtToneChanIndex, + f_pChanIndexConf->usExtToneChanIndex, + cOCT6100_API_EXT_TONE_EXTRA_TSI, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the original channel + into the SIN signal of the exteded channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_pChanIndexConf->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_pChanIndexConf->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pTdmConfig->ulRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = f_pChanIndexConf->usExtToneTsiIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Write back the original values in the channel open structure.*/ + + pTdmConfig->ulSinPcmLaw = ulTempSinLaw; + pTdmConfig->ulSoutPcmLaw = ulTempSoutLaw; + + f_pChannelOpen->ulEchoOperationMode = ulTempEchoOpMode; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the SS tone detection. */ + + for ( ulToneEventNumber = 0; ulToneEventNumber < cOCT6100_MAX_TONE_EVENT; ulToneEventNumber++ ) + { + /* Check if the current tone is a SS tone. */ + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Write to all resources needed to activate tone detection on this SS tone. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + ulToneEventNumber, + + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the Output Tsst control memory.*/ + + /* Set the ROUT Tsst control entry.*/ + if ( f_pChanIndexConf->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulRoutNumTssts, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SOUT Tsst control entry.*/ + if ( f_pChanIndexConf->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulSoutNumTssts, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateChannelEntry + +Description: Updates the new channel in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateChannelEntry +UINT32 Oct6100ApiUpdateChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + /* Obtain a pointer to the config structures of the tPOCT6100_CHANNEL_OPEN structure. */ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ) + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + pChanEntry->fEnableExtToneDetection = (UINT8)( f_pChannelOpen->fEnableExtToneDetection & 0xFF ); + + /* Save the VQE configuration.*/ + pChanEntry->VqeConfig.byComfortNoiseMode = (UINT8)( pVqeConfig->ulComfortNoiseMode & 0xFF ); + pChanEntry->VqeConfig.fEnableNlp = (UINT8)( pVqeConfig->fEnableNlp & 0xFF ); + pChanEntry->VqeConfig.fEnableTailDisplacement = (UINT8)( pVqeConfig->fEnableTailDisplacement ); + pChanEntry->VqeConfig.usTailDisplacement = (UINT16)( pVqeConfig->ulTailDisplacement & 0xFFFF ); + pChanEntry->VqeConfig.usTailLength = (UINT16)( pVqeConfig->ulTailLength & 0xFFFF ); + + pChanEntry->VqeConfig.fSinDcOffsetRemoval = (UINT8)( pVqeConfig->fSinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinDcOffsetRemoval = (UINT8)( pVqeConfig->fRinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinLevelControl = (UINT8)( pVqeConfig->fRinLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinLevelControlGainDb = (OCT_INT8)( pVqeConfig->lRinLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutLevelControl = (UINT8)( pVqeConfig->fSoutLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutLevelControlGainDb = (OCT_INT8)( pVqeConfig->lSoutLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fRinAutomaticLevelControl = (UINT8)( pVqeConfig->fRinAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lRinAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAutomaticLevelControl = (UINT8)( pVqeConfig->fSoutAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lSoutAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fRinHighLevelCompensation = (UINT8)( pVqeConfig->fRinHighLevelCompensation & 0xFF ); + pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb = (OCT_INT8)( pVqeConfig->lRinHighLevelCompensationThresholdDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction = (UINT8)( pVqeConfig->fSoutAdaptiveNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.fSoutNoiseBleaching = (UINT8)( pVqeConfig->fSoutNoiseBleaching & 0xFF ); + pChanEntry->VqeConfig.fSoutConferencingNoiseReduction = (UINT8)( pVqeConfig->fSoutConferencingNoiseReduction & 0xFF ); + + pChanEntry->VqeConfig.fAcousticEcho = (UINT8)( pVqeConfig->fAcousticEcho & 0xFF ); + + pChanEntry->VqeConfig.fDtmfToneRemoval = (UINT8)( pVqeConfig->fDtmfToneRemoval & 0xFF ); + + pChanEntry->VqeConfig.chDefaultErlDb = (OCT_INT8)( pVqeConfig->lDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.chAecDefaultErlDb = (OCT_INT8)( pVqeConfig->lAecDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.usAecTailLength = (UINT16)( pVqeConfig->ulAecTailLength & 0xFFFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorA = (UINT8)( pVqeConfig->ulNonLinearityBehaviorA & 0xFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorB = (UINT8)( pVqeConfig->ulNonLinearityBehaviorB & 0xFF ); + pChanEntry->VqeConfig.byDoubleTalkBehavior = (UINT8)( pVqeConfig->ulDoubleTalkBehavior & 0xFF ); + pChanEntry->VqeConfig.chAnrSnrEnhancementDb = (OCT_INT8)( pVqeConfig->lAnrSnrEnhancementDb & 0xFF ); + pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation = (UINT8)( pVqeConfig->ulAnrVoiceNoiseSegregation & 0xFF ); + pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay = (UINT16)( pVqeConfig->ulToneDisablerVqeActivationDelay & 0xFFFF ); + + pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement = (UINT8)( pVqeConfig->fSoutNaturalListenerEnhancement & 0xFF ); + pChanEntry->VqeConfig.fRoutNoiseReduction = (UINT8)( pVqeConfig->fRoutNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb = (OCT_INT8) (pVqeConfig->lRoutNoiseReductionLevelGainDb & 0xFF); + pChanEntry->VqeConfig.fEnableMusicProtection = (UINT8)( pVqeConfig->fEnableMusicProtection & 0xFF ); + pChanEntry->VqeConfig.fIdleCodeDetection = (UINT8)( pVqeConfig->fIdleCodeDetection & 0xFF ); + + /* Save the codec information.*/ + pChanEntry->CodecConfig.byAdpcmNibblePosition = (UINT8)( pCodecConfig->ulAdpcmNibblePosition & 0xFF ); + + pChanEntry->CodecConfig.byDecoderPort = (UINT8)( pCodecConfig->ulDecoderPort & 0xFF ); + pChanEntry->CodecConfig.byDecodingRate = (UINT8)( pCodecConfig->ulDecodingRate & 0xFF ); + pChanEntry->CodecConfig.byEncoderPort = (UINT8)( pCodecConfig->ulEncoderPort & 0xFF ); + pChanEntry->CodecConfig.byEncodingRate = (UINT8)( pCodecConfig->ulEncodingRate & 0xFF ); + + pChanEntry->CodecConfig.fEnableSilenceSuppression = (UINT8)( pCodecConfig->fEnableSilenceSuppression & 0xFF ); + pChanEntry->CodecConfig.byPhase = (UINT8)( pCodecConfig->ulPhase & 0xFF ); + pChanEntry->CodecConfig.byPhasingType = (UINT8)( pCodecConfig->ulPhasingType & 0xFF ); + + /* Save the RIN settings.*/ + pChanEntry->TdmConfig.byRinPcmLaw = (UINT8)( pTdmConfig->ulRinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRinTimeslot = (UINT16)( pTdmConfig->ulRinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRinStream = (UINT16)( pTdmConfig->ulRinStream & 0xFFFF ); + + /* Save the SIN settings.*/ + pChanEntry->TdmConfig.bySinPcmLaw = (UINT8)( pTdmConfig->ulSinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSinTimeslot = (UINT16)( pTdmConfig->ulSinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSinStream = (UINT16)( pTdmConfig->ulSinStream & 0xFFFF ); + + /* Save the ROUT settings.*/ + pChanEntry->TdmConfig.byRoutPcmLaw = (UINT8)( pTdmConfig->ulRoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRoutTimeslot = (UINT16)( pTdmConfig->ulRoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRoutStream = (UINT16)( pTdmConfig->ulRoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + + /* Save the SOUT settings.*/ + pChanEntry->TdmConfig.bySoutPcmLaw = (UINT8)( pTdmConfig->ulSoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSoutTimeslot = (UINT16)( pTdmConfig->ulSoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSoutStream = (UINT16)( pTdmConfig->ulSoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.byRinNumTssts = (UINT8)( pTdmConfig->ulRinNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySinNumTssts = (UINT8)( pTdmConfig->ulSinNumTssts & 0xFF ); + pChanEntry->TdmConfig.byRoutNumTssts = (UINT8)( pTdmConfig->ulRoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySoutNumTssts = (UINT8)( pTdmConfig->ulSoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + + /* Save the extended Tone detection information.*/ + pChanEntry->usExtToneChanIndex = f_pChanIndexConf->usExtToneChanIndex; + pChanEntry->usExtToneMixerIndex = f_pChanIndexConf->usExtToneMixerIndex; + pChanEntry->usExtToneTsiIndex = f_pChanIndexConf->usExtToneTsiIndex; + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + /* Set the mode of the original channel. He is the channel performing detection on the + SIN port. The extended channel will perform detection on the RIN port.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_SIN_PORT_MODE; + + /* Now, program the associated channel.*/ + + /* Obtain a pointer to the extended tone detection channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pExtToneChanEntry, f_pChanIndexConf->usExtToneChanIndex ); + + pExtToneChanEntry->fReserved = TRUE; + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_RIN_PORT_MODE; /* Detect on RIN port.*/ + pExtToneChanEntry->usExtToneChanIndex = f_pChanIndexConf->usEchoChanIndex; + + pExtToneChanEntry->aulToneConf[ 0 ] = 0; + pExtToneChanEntry->aulToneConf[ 1 ] = 0; + + } + else + { + /* No extended tone detection supported.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Store hardware related information.*/ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + + /* We are not being tapped for now. */ + pChanEntry->fBeingTapped = FALSE; + + pChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + + /* The copy event has not yet been created. */ + pChanEntry->fCopyEventCreated = FALSE; + + pChanEntry->usRinRoutConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + pChanEntry->usSinSoutConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + + pChanEntry->usPhasingTsstIndex = f_pChanIndexConf->usPhasingTsstIndex; + + pChanEntry->fSinSoutCodecActive = f_pChanIndexConf->fSinSoutCodecActive; + pChanEntry->fRinRoutCodecActive = f_pChanIndexConf->fRinRoutCodecActive; + + + + pChanEntry->usEchoMemIndex = f_pChanIndexConf->usEchoMemIndex; + + pChanEntry->usRinTsstIndex = f_pChanIndexConf->usRinTsstIndex; + pChanEntry->usSinTsstIndex = f_pChanIndexConf->usSinTsstIndex; + pChanEntry->usRoutTsstIndex = f_pChanIndexConf->usRoutTsstIndex; + pChanEntry->usSoutTsstIndex = f_pChanIndexConf->usSoutTsstIndex; + + pChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Nothing muted for now. */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + /* Set all the GW feature initial value.*/ + /* Bridge info */ + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pChanEntry->fMute = FALSE; + + pChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + + /* Buffer playout info.*/ + pChanEntry->fRinBufPlaying = FALSE; + pChanEntry->fSoutBufPlaying = FALSE; + + /* Tone detection state. */ + /* This array is configured as follow.*/ + /* Index 0 contain event 0 to 31 (msb = event 31) and Index 1 contain index 32 - 55 */ + pChanEntry->aulToneConf[ 0 ] = 0; + pChanEntry->aulToneConf[ 1 ] = 0; + pChanEntry->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pChanEntry->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + + /* Initialize the bidirectional flag.*/ + pChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + /* Init some of the stats.*/ + + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + pChanEntry->usNumEchoPathChangesOfst = 0; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanIndexConf->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt++; + } + /*=======================================================================*/ + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelOpen->pulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanIndexConf->usEchoChanIndex; + + /* Finally, mark the channel as open. */ + pChanEntry->fReserved = TRUE; + pChanEntry->usExtraSinTsiDependencyCnt = 0; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCloseSer + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseSer +UINT32 Oct6100ChannelCloseSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + UINT16 usChannelIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelParams( f_pApiInstance, + f_pChannelClose, + + &usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateChannelStructs( f_pApiInstance, + + usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseChannelResources( f_pApiInstance, usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. +f_pulFpgaChanIndex Pointer to the FPGA channel index associated to this channel. +f_pusChanIndex Pointer to the index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelParams +UINT32 Oct6100ApiAssertChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose, + + IN OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelClose->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check if the channel is bound to a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateChannelStructs + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulFpgaChanIndex Index of the channel within the SCN_PLC FPGA. +f_usChanIndex Index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateChannelStructs +UINT32 Oct6100ApiInvalidateChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + UINT16 usCurrentEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Obtain local pointer to the TDM configuration of the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* If this channel is currently debugged, automatically close the debug channel. */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == f_usChanIndex ) ) + { + tOCT6100_DEBUG_SELECT_CHANNEL SelectDebugChan; + + /* Ensure forward compatibility. */ + Oct6100DebugSelectChannelDef( &SelectDebugChan ); + + /* Set the hot channel to an invalid handle to disable recording. */ + SelectDebugChan.ulChannelHndl = cOCT6100_INVALID_HANDLE; + + /* Call the serialized fonction. */ + ulResult = Oct6100DebugSelectChannelSer( f_pApiInstance, &SelectDebugChan, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Deactivate the TSST control memory if used. */ + + /* RIN port.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* SIN port.*/ + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* ROUT port.*/ + + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* SOUT port.*/ + + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Deactivate the conversion control memories if used. */ + + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Rin/Rout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Sin/Sout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the silence copy events if they were created. */ + + /* Unmute the Rin port if it was muted. */ + if ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*------------------------------------------------------------------------------*/ + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = FALSE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + + + /* Free all resources reserved for extended tone detection.*/ + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry of the extended channel.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usExtToneChanIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Remove the mixer event used to copy the RIN signal to the SIN port of the extended + channel.*/ + + /* Clear the Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + } + + /*------------------------------------------------------------------------------*/ + /* Reset PGSP */ + + WriteParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + WriteParams.usWriteData = 0x0800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the mute with feature bit. */ + + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the VQE memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x20; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------*/ + /* Clear the NLP memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x28; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /* Clear the AF information memory. */ + + SmearParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 12; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*Reset ALC status*/ + WriteParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + 0x3A; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseChannelResources + +Description: Release and clear the API entry associated to the echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChannelIndex Index of the echo cancellation channel in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseChannelResources +UINT32 Oct6100ApiReleaseChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT16 usCurrentEntry; + UINT32 ulTimeslot; + UINT32 ulStream; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChannelIndex ); + + /* Obtain local pointer to the TDM configurationof the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3; + + /* Now release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, f_usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4; + + /* Release the conversion resources.*/ + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B9; + + pChanEntry->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BA; + + pChanEntry->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /*=========================================================================*/ + /* Release the TSST control memory entries if any were reserved.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRinTimeslot, + pTdmConfig->usRinStream, + pTdmConfig->byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_5; + } + + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSinTimeslot, + pTdmConfig->usSinStream, + pTdmConfig->bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_6; + } + + /*=======================================================================*/ + /* Release all the TSSTs associated to the ROUT port of this channel. */ + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRoutTimeslot, + pTdmConfig->usRoutStream, + pTdmConfig->byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_7; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_8; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release all the TSSTs associated to the SOUT port of this channel. */ + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSoutTimeslot, + pTdmConfig->usSoutStream, + pTdmConfig->bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_9; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, pChanEntry->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt--; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release any resources reserved for the extended tone detection.*/ + + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pExtToneChanEntry, pChanEntry->usExtToneChanIndex ); + + /* Release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, pChanEntry->usExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C1; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C2; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usExtToneMixerIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C3; + + /* Now release the channel entry */ + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + pExtToneChanEntry->fReserved = FALSE; + + /* Set the current entry to disable, just in case.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the channel's list entry. */ + + /* Clear the NLP dword array. */ + Oct6100UserMemSet( pChanEntry->aulNlpConfDword, 0, sizeof( pChanEntry->aulNlpConfDword ) ); + + /* Clear the echo operation mode. */ + pChanEntry->byEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + + /* Mark the channel as closed. */ + pChanEntry->fReserved = FALSE; + pChanEntry->byEntryOpenCnt++; + + /* Reset the port, the bridge and BidirInfo */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + pChanEntry->fBiDirChannel = FALSE; + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels--; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; + +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModifySer + +Description: Modify an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to channel configuration structure. The handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifySer +UINT32 Oct6100ChannelModifySer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + UINT16 usChanIndex; + UINT32 ulResult; + UINT16 usNewRinTsstIndex; + UINT16 usNewSinTsstIndex; + UINT16 usNewRoutTsstIndex; + UINT16 usNewSoutTsstIndex; + UINT8 fSinSoutCodecActive = FALSE; + UINT8 fRinRoutCodecActive = FALSE; + UINT16 usNewPhasingTsstIndex; + tOCT6100_CHANNEL_OPEN *pTempChanOpen; + + /* We don't want this 290 byte structure on the stack */ + pTempChanOpen = kmalloc(sizeof(*pTempChanOpen), GFP_ATOMIC); + if (!pTempChanOpen) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelModify( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + &usNewPhasingTsstIndex, + &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelResources( f_pApiInstance, + f_pChannelModify, + usChanIndex, + &usNewRinTsstIndex, + &usNewSinTsstIndex, + &usNewRoutTsstIndex, + &usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelStructs( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + &fSinSoutCodecActive, + &fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiModifyChannelEntry( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + fSinSoutCodecActive, + fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); +out: + kfree(pTempChanOpen); + + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelModify + +Description: Checks the user's echo cancellation channel modify structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pTempChanOpen Pointer to a channel open structure. +f_pusNewPhasingTsstIndex Pointer to a new phasing TSST index within the API instance. +f_pusChanIndex Pointer to the channel index within the API instance channel list + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelModify +UINT32 Oct6100ApiCheckChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pTempChanOpen, + OUT PUINT16 f_pusNewPhasingTsstIndex, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulEntryOpenCnt; + UINT32 ulDecoderNumTssts; + + /* Check the provided handle. */ + if ( (f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelModify->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check the general modify parameters. */ + + if ( f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->fEnableToneDisabler != TRUE && + f_pChannelModify->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the disable tone detection flag. */ + if ( f_pChannelModify->fDisableToneDetection != TRUE && + f_pChannelModify->fDisableToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION; + + /* Check the stop buffer playout flag. */ + if ( f_pChannelModify->fStopBufferPlayout != TRUE && + f_pChannelModify->fStopBufferPlayout != FALSE ) + return cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT; + + /* Check the remove conference bridge participant flag. */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant != TRUE && + f_pChannelModify->fRemoveConfBridgeParticipant != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT; + + /* Check the remove broadcast timeslots flag. */ + if ( f_pChannelModify->fRemoveBroadcastTssts != TRUE && + f_pChannelModify->fRemoveBroadcastTssts != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS; + + if ( f_pChannelModify->fCodecConfigModified != TRUE && + f_pChannelModify->fCodecConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG; + + if ( f_pChannelModify->fVqeConfigModified != TRUE && + f_pChannelModify->fVqeConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG; + + if ( f_pChannelModify->fTdmConfigModified != TRUE && + f_pChannelModify->fTdmConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify if any law change was requested. If so reprogram all structures.*/ + + if (( f_pChannelModify->fTdmConfigModified == TRUE ) && + ( f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING )) + { + f_pChannelModify->fVqeConfigModified = TRUE; + f_pChannelModify->fCodecConfigModified = TRUE; + } + /*=======================================================================*/ + + ulResult = Oct6100ApiUpdateOpenStruct( f_pApiInstance, f_pChannelModify, f_pTempChanOpen, pChanEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* All further check will now be performed using the TempOpenChan structure in order + to reuse the checks written for the open channel structure.*/ + + + + /* Check the TDM config.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + tPOCT6100_CHANNEL_OPEN_TDM pOpenTdm; + + pOpenTdm = &f_pTempChanOpen->TdmConfig; + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, + pOpenTdm ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if that Stream and Timeslot values are valid.*/ + + /* Check the RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( pChanEntry->fBeingTapped == TRUE ) + { + /* Check that the Rin stream + timeslot are not being assigned. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + } + + /* Check the SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + + /* Check the ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + + /* Check the SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + + /* Verify if the channel is currently part of a bidirectional channel, and if */ + /* so perform the required checks. */ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + /* Check that no PCM law change is requested.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* If this channel is on a conference bridge, a few more things must be checked. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* If conferencing, law conversion cannot be applied. */ + /* This check is done only if both input and output ports are assigned. */ + if ( ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + } + + /* Check for Sin. */ + if ( ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* Check if ADPCM is requested. */ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + } + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + } + + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort == cOCT6100_NO_ENCODING || + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* Make sure no law conversion is attempted since it is not supported by the device.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + if ( pChanEntry->fEnableExtToneDetection == TRUE && + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + + /* A few special checks must be done if the configuration is to be applied */ + /* to all opened channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + /* When the configuration to be applied is for all channels, */ + /* check that the stream and timeslot parameters are not being assigned. */ + + /* Check the Rout port. */ + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN; + } + + /* Check the Rin port. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN; + } + + /* Check the Sout port. */ + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN; + } + + /* Check the Sin port. */ + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN; + } + } + } + + /* Check the VQE config.*/ + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, + &f_pTempChanOpen->VqeConfig, + f_pTempChanOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /* Check the Codec config.*/ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulRinNumTssts; + else /* f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, + &f_pTempChanOpen->CodecConfig, + ulDecoderNumTssts, + f_pusNewPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( f_pTempChanOpen->CodecConfig.fEnableSilenceSuppression == TRUE && f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if the channel is currently part of a bidirectional channel, and if so perform + the required checks.*/ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + + } + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelResources + +Description: Reserves any new resources needed for the channel +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_usChanIndex Allocated entry in ECHO channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelResources +UINT32 Oct6100ApiModifyChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewRinTsstIndex, + OUT PUINT16 f_pusNewSinTsstIndex, + OUT PUINT16 f_pusNewRoutTsstIndex, + OUT PUINT16 f_pusNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdmConf; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar = cOCT6100_ERR_OK; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinReleased = FALSE; + BOOL fSinReleased = FALSE; + BOOL fRoutReleased = FALSE; + BOOL fSoutReleased = FALSE; + + BOOL fRinReserved = FALSE; + BOOL fSinReserved = FALSE; + BOOL fRoutReserved = FALSE; + BOOL fSoutReserved = FALSE; + + BOOL fReserveRin = FALSE; + BOOL fReserveSin = FALSE; + BOOL fReserveRout = FALSE; + BOOL fReserveSout = FALSE; + + BOOL fRinRoutConversionMemReserved = FALSE; + BOOL fSinSoutConversionMemReserved = FALSE; + + + UINT32 ulRinNumTssts = 1; + UINT32 ulSinNumTssts = 1; + UINT32 ulRoutNumTssts = 1; + UINT32 ulSoutNumTssts = 1; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_CHANNEL_MODIFY structure. */ + pModifyTdmConf = &f_pChannelModify->TdmConfig; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_API_CHANNEL structure. */ + pApiTdmConf = &pChanEntry->TdmConfig; + + /*===============================================================================*/ + /* Modify TSST resources if required.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* First release any entry that need to be released.*/ + if ( ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReleased = TRUE; + } + } + + fReserveRin = TRUE; + } + + /* Release SIN port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReleased = TRUE; + } + } + + fReserveSin = TRUE; + } + + /* Release ROUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReleased = TRUE; + } + } + + fReserveRout = TRUE; + } + + /* Release the SOUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReleased = TRUE; + } + } + + fReserveSout = TRUE; + } + + /* Now reserve any new entry required.*/ + + /* Modify RIN port.*/ + if ( ( fReserveRin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRinNumTssts = pApiTdmConf->byRinNumTssts; + } + else /* if ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRinNumTssts = pModifyTdmConf->ulRinNumTssts; + } + + if ( pModifyTdmConf->ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRinTimeslot, + pApiTdmConf->usRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReserved = TRUE; + } + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SIN port.*/ + if ( ( fReserveSin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSinNumTssts = pApiTdmConf->bySinNumTssts; + } + else /* if ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSinNumTssts = pModifyTdmConf->ulSinNumTssts; + } + + if ( pModifyTdmConf->ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSinTimeslot, + pApiTdmConf->usSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReserved = TRUE; + } + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify ROUT port.*/ + if ( ( fReserveRout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRoutNumTssts = pApiTdmConf->byRoutNumTssts; + } + else /* if ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRoutNumTssts = pModifyTdmConf->ulRoutNumTssts; + } + + if ( pModifyTdmConf->ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRoutTimeslot, + pApiTdmConf->usRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReserved = TRUE; + } + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SOUT port.*/ + if ( ( fReserveSout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSoutNumTssts = pApiTdmConf->bySoutNumTssts; + } + else /* if ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSoutNumTssts = pModifyTdmConf->ulSoutNumTssts; + } + + if ( pModifyTdmConf->ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSoutTimeslot, + pApiTdmConf->usSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReserved = TRUE; + } + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + } + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usRinRoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemReserved = TRUE; + } + } + + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usSinSoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemReserved = TRUE; + } + } + } + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( *f_pusNewRinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + ulMixerEventCntNeeded++; + } + } + + if ( ( *f_pusNewSinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulMixerEventCntNeeded++; + } + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + /* Verify if an error occured. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release any resources newly reserved.*/ + if ( fRinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now make sure any resources released gets reserved back again.*/ + + /* For the RIN port.*/ + if ( fRinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usRinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usSinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usRoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usSoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Release the conversion memories if they were reserved.*/ + if ( fRinRoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSinSoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now return the error.*/ + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelStructs + +Description: Performs all the required structure writes to configure the + echo cancellation channel based on the new modifications. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_pChannelOpen Pointer to a structure used to store the multiple resources indexes. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_pfSinSoutCodecActive Pointer to the state of the SIN/SOUT codec. +f_pfRinRoutCodecActive Pointer to the state of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelStructs +UINT32 Oct6100ApiModifyChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + OUT PUINT8 f_pfSinSoutCodecActive, + OUT PUINT8 f_pfRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + + UINT32 ulResult; + UINT16 usReadData; + + UINT16 usSinTsstIndex; + UINT16 usRinTsstIndex; + + UINT32 ulToneConfIndex; + BOOL fClearPlayoutPointers = FALSE; + + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + + /*=======================================================================*/ + /* Init the RIN and SIN TSST index */ + + usRinTsstIndex = pChanEntry->usRinTsstIndex; + usSinTsstIndex = pChanEntry->usSinTsstIndex; + + + /*==============================================================================*/ + /* Clear the TSST that will be release.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now, Configure the Tsst control memory.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usRinTsstIndex = f_usNewRinTsstIndex; + + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usSinTsstIndex = f_usNewSinTsstIndex; + + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify ROUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Modify SOUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulSoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + + + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Modify the Encoder/Decoder memory if required.*/ + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + UINT32 ulCompType = 0; + UINT16 usTempTsiMemIndex; + UINT16 usDecoderMemIndex; + UINT16 usEncoderMemIndex; + UINT32 ulPcmLaw; + UINT16 usPhasingIndex; + BOOL fModifyAdpcmMem = TRUE; + + /*==============================================================================*/ + /* Reprogram the Decoder memory.*/ + + if ( pChanEntry->CodecConfig.byDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usDecoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usDecoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( pChanEntry->CodecConfig.byEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usEncoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usEncoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( usDecoderMemIndex != cOCT6100_INVALID_INDEX ) + { + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + break; + + default: + return cOCT6100_ERR_FATAL_D6; + } + + if ( fModifyAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usDecoderMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + pApiCodecConf->byAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usDecoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Flag the entry as deactivated.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + + + + + /*==============================================================================*/ + /* Reprogram the Encoder memory.*/ + + if ( usEncoderMemIndex != cOCT6100_INVALID_INDEX ) + { + + fModifyAdpcmMem = TRUE; + + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + } + + /* Set the phasing index .*/ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + usPhasingIndex = f_usNewPhasingTsstIndex; + else + usPhasingIndex = pChanEntry->usPhasingTsstIndex; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( ulPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* ulPcmLaw == cOCT6100_PCM_A_LAW */ + ulCompType = 0x5; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + break; + + default: + return cOCT6100_ERR_FATAL_D7; + } + + if ( fModifyAdpcmMem == TRUE ) + { + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usEncoderMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + pApiCodecConf->byAdpcmNibblePosition, + usPhasingIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usEncoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + } + + + + + /*==============================================================================*/ + /* Modify the VQE parameter if required.*/ + + if ( ( f_pChannelModify->fVqeConfigModified == TRUE ) + || ( (UINT8)f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) + { + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_usChanIndex, + pChanEntry->usEchoMemIndex, + FALSE, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Modify the Echo memory if required.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + &f_pChannelOpen->TdmConfig, + f_pChannelOpen, + pChanEntry->usEchoMemIndex, + pChanEntry->usRinRoutTsiMemIndex, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Synch all the buffer playout field if needed by echo operation mode. */ + /* Note that Oct6100ApiWriteVqeMemory does not clear the playout pointers */ + /* since the flag is set to FALSE. */ + if ( ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + && ( ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) + || ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) ) ) + { + /* Buffer playout must be stopped. */ + fClearPlayoutPointers = TRUE; + } + } + + /*==============================================================================*/ + /* Modify the Mixer events if law changes are requested. */ + + if ( pChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSinPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSoutCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSoutPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usChanIndex, + usRinTsstIndex, + usSinTsstIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Completely disable tone detection? */ + if ( f_pChannelModify->fDisableToneDetection == TRUE ) + { + /* Check if tone detection has been enabled on this channel. */ + for (ulToneConfIndex = 0; ulToneConfIndex < ARRAY_SIZE(pChanEntry->aulToneConf); ulToneConfIndex++) + { + /* Check if some tone has been activated on this channel. */ + if ( pChanEntry->aulToneConf[ ulToneConfIndex ] != 0 ) + { + tOCT6100_TONE_DETECTION_DISABLE ToneDetectDisable; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ToneDetectionDisableDef( &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + ToneDetectDisable.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Disable all tones activated on this channel. */ + ToneDetectDisable.fDisableAll = TRUE; + + /* Call tone detection serialized function. */ + ulResult = Oct6100ToneDetectionDisableSer( f_pApiInstance, &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get out of the loop, tone detection has been disabled! */ + break; + } + } + } + + /* Hard-stop buffer playout? */ + if ( f_pChannelModify->fStopBufferPlayout == TRUE ) + { + /* Check if playout has been started on the Rout port. */ + if ( ( pChanEntry->fRinBufPlaying == TRUE ) || ( pChanEntry->fRinBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + + /* Check if playout has been started on the Sout port. */ + if ( ( pChanEntry->fSoutBufPlaying == TRUE ) || ( pChanEntry->fSoutBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + } + + /* Remove participant from bridge? */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant == TRUE ) + { + /* Check if this channel is on a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* Channel is on a bridge, remove it. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Do not remove all channels, only the one specified. */ + BridgeChanRemove.fRemoveAll = FALSE; + + /* No need to assign conference bridge handle, the remove function will figure it out. */ + + /* Call conference bridge channel remove serialized function. */ + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY ) + { + tPOCT6100_API_CHANNEL pTapChanEntry; + + /* Get a pointer to the tap channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTapChanEntry, pChanEntry->usTapChanIndex ) + + /* Form tap channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pTapChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | pChanEntry->usTapChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Re-form original channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + return ulResult; + } + } + } + } + + /* Remove all broadcast TSSTs? */ + if ( f_pChannelModify->fRemoveBroadcastTssts == TRUE ) + { + /* Check if broadcast TSSTs were used on the Rout port. */ + if ( pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Rout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + /* Check if broadcast TSSTs were used on the Sout port. */ + if ( pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Sout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_SOUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Check if have to make sure buffer playout is stopped. */ + if ( fClearPlayoutPointers == TRUE ) + { + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.fStopCleanly = FALSE; + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelEntry + +Description: Updates the channel structure in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_fSinSoutCodecActive State of the SIN/SOUT codec. +f_fRinRoutCodecActive State of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelEntry +UINT32 Oct6100ApiModifyChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + IN UINT8 f_fSinSoutCodecActive, + IN UINT8 f_fRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_API_CHANNEL_VQE pApiVqeConf; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + pApiVqeConf = &pChanEntry->VqeConfig; + + /*=======================================================================*/ + /* Copy the channel's general configuration. */ + + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + + /* Save the codec state.*/ + pChanEntry->fSinSoutCodecActive = (UINT8)( f_fSinSoutCodecActive & 0xFF ); + pChanEntry->fRinRoutCodecActive = (UINT8)( f_fRinRoutCodecActive & 0xFF ); + + /*=======================================================================*/ + /* Copy the channel's TDM configuration of all the modified fields. */ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + pApiTdmConf->byRinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRinPcmLaw & 0xFF ); + pApiTdmConf->bySinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSinPcmLaw & 0xFF ); + pApiTdmConf->byRoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutPcmLaw & 0xFF ); + pApiTdmConf->bySoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutPcmLaw & 0xFF ); + + pApiTdmConf->byRinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRinNumTssts & 0xFF ); + pApiTdmConf->bySinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSinNumTssts & 0xFF ); + pApiTdmConf->byRoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutNumTssts & 0xFF ); + pApiTdmConf->bySoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutNumTssts & 0xFF ); + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRinStream & 0xFFFF ); + pApiTdmConf->usRinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRinTimeslot & 0xFFFF ); + pChanEntry->usRinTsstIndex = f_usNewRinTsstIndex; + } + else /* f_ulNewRinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSinStream & 0xFFFF ); + pApiTdmConf->usSinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSinTimeslot & 0xFFFF ); + pChanEntry->usSinTsstIndex = f_usNewSinTsstIndex; + } + else /* f_ulNewSinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutStream & 0xFFFF ); + pApiTdmConf->usRoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutTimeslot & 0xFFFF ); + pChanEntry->usRoutTsstIndex = f_usNewRoutTsstIndex; + } + else /* f_ulNewRoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutStream & 0xFFFF ); + pApiTdmConf->usSoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutTimeslot & 0xFFFF ); + pChanEntry->usSoutTsstIndex = f_usNewSoutTsstIndex; + } + else /* f_ulNewSoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + } + + /*=======================================================================*/ + /* Copy the channel's VQE configuration of all the modified fields. */ + + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + pApiVqeConf->fEnableNlp = (UINT8)( f_pChannelOpen->VqeConfig.fEnableNlp & 0xFF ); + pApiVqeConf->byComfortNoiseMode = (UINT8)( f_pChannelOpen->VqeConfig.ulComfortNoiseMode & 0xFF ); + pApiVqeConf->fSinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinLevelControl & 0xFF ); + pApiVqeConf->fSoutLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutLevelControl & 0xFF ); + pApiVqeConf->fRinAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl & 0xFF ); + pApiVqeConf->fSoutAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl & 0xFF ); + pApiVqeConf->fRinHighLevelCompensation = (UINT8)( f_pChannelOpen->VqeConfig.fRinHighLevelCompensation & 0xFF ); + + pApiVqeConf->fSoutAdaptiveNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction & 0xFF ); + pApiVqeConf->fSoutNoiseBleaching = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNoiseBleaching & 0xFF ); + pApiVqeConf->fSoutConferencingNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction & 0xFF ); + pApiVqeConf->chRinLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinLevelControlGainDb & 0xFF ); + pApiVqeConf->chSoutLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb & 0xFF ); + pApiVqeConf->chRinAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chRinHighLevelCompensationThresholdDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb & 0xFF ); + pApiVqeConf->fEnableTailDisplacement = (UINT8)( f_pChannelOpen->VqeConfig.fEnableTailDisplacement & 0xFF ); + pApiVqeConf->usTailDisplacement = (UINT16)( f_pChannelOpen->VqeConfig.ulTailDisplacement & 0xFFFF ); + pApiVqeConf->usTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulTailLength & 0xFFFF ); + pApiVqeConf->fAcousticEcho = (UINT8)( f_pChannelOpen->VqeConfig.fAcousticEcho & 0xFF ); + pApiVqeConf->fDtmfToneRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fDtmfToneRemoval & 0xFF ); + + pApiVqeConf->chDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lDefaultErlDb & 0xFF ); + pApiVqeConf->chAecDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAecDefaultErlDb & 0xFF ); + pApiVqeConf->usAecTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulAecTailLength & 0xFFFF ); + pApiVqeConf->chAnrSnrEnhancementDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb & 0xFF ); + pApiVqeConf->byAnrVoiceNoiseSegregation = (UINT8)( f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation & 0xFF ); + pApiVqeConf->usToneDisablerVqeActivationDelay = (UINT16)( f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay & 0xFFFF ); + pApiVqeConf->byNonLinearityBehaviorA = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA & 0xFF ); + pApiVqeConf->byNonLinearityBehaviorB = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB & 0xFF ); + pApiVqeConf->byDoubleTalkBehavior = (UINT8)( f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior & 0xFF ); + pApiVqeConf->bySoutAutomaticListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->bySoutNaturalListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->fSoutNaturalListenerEnhancement = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement & 0xFF ); + pApiVqeConf->fRoutNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fRoutNoiseReduction & 0xFF ); + pApiVqeConf->chRoutNoiseReductionLevelGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb & 0xFF ); + pApiVqeConf->fEnableMusicProtection = (UINT8)( f_pChannelOpen->VqeConfig.fEnableMusicProtection & 0xFF ); + pApiVqeConf->fIdleCodeDetection = (UINT8)( f_pChannelOpen->VqeConfig.fIdleCodeDetection & 0xFF ); + } + + /*=======================================================================*/ + /* Copy the channel's CODEC configuration of all the modified fields. */ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + pApiCodecConf->byAdpcmNibblePosition = (UINT8)( f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition & 0xFF ); + pApiCodecConf->byEncoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulEncoderPort & 0xFF ); + pApiCodecConf->byEncodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulEncodingRate & 0xFF ); + pApiCodecConf->byDecoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulDecoderPort & 0xFF ); + pApiCodecConf->byDecodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulDecodingRate & 0xFF ); + pApiCodecConf->fEnableSilenceSuppression = (UINT8)( f_pChannelOpen->CodecConfig.fEnableSilenceSuppression & 0xFF ); + pApiCodecConf->byPhase = (UINT8)( f_pChannelOpen->CodecConfig.ulPhase & 0xFF ); + pApiCodecConf->byPhasingType = (UINT8)( f_pChannelOpen->CodecConfig.ulPhasingType & 0xFF ); + + /* Update the API phasing TSST structure */ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + + /* Release the previous phasing TSST if the channel was already bound to one.*/ + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, pChanEntry->usPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt--; + } + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, f_usNewPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt++; + pChanEntry->usPhasingTsstIndex = f_usNewPhasingTsstIndex; + + } + } + + + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAddSer + +Description: Assign a TSST to one of the port of an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to TSST assign structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddSer +UINT32 Oct6100ChannelBroadcastTsstAddSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ) +{ + UINT16 usChanIndex; + UINT16 usNewTsstIndex; + UINT16 usNewTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiCheckChanTsstAddParams( f_pApiInstance, f_pChannelTsstAdd, &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsstAddResources( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, &usNewTsstIndex, &usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWriteTsstAddStructs( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiUpdateTsstAddChanEntry( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex, usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChanTsstAddParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_ADD + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_pusChanIndex Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChanTsstAddParams +UINT32 Oct6100ApiCheckChanTsstAddParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_ADD_PORT; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_B; + } + + /* Check the validity of the timeslot and stream. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsstAddResources + +Description: Reserve the entry for the new broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index within the API's channel list. +f_pusNewTsstIndex Pointer to the new TSST index within the API's TSST memory. +f_pusNewTsstEntry Pointer to the new TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsstAddResources +UINT32 Oct6100ApiReserveTsstAddResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewTsstIndex, + OUT PUINT16 f_pusNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_C; + } + + /* Reserve the new entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + ulNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewTsstIndex, + f_pusNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteTsstAddStructs + +Description: Configure the TSST control memory for the new TSST entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex Tsst index in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteTsstAddStructs +UINT32 Oct6100ApiWriteTsstAddStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 usTsiMemIndex; + UINT32 ulNumTssts = 1; + + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + usTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + usTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_D; + } + + + /* Write the new entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usNewTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= (UINT16)( pChanEntry->CodecConfig.byAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET ); + WriteParams.usWriteData |= (UINT16)( (ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET ); + WriteParams.usWriteData |= (UINT16)( usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateTsstAddChanEntry + +Description: Update the associated channel API entry to add the new broacast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex TSST index within the TSST control memory. +f_usNewTsstEntry TSST entry within the API TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateTsstAddChanEntry +UINT32 Oct6100ApiUpdateTsstAddChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex, + IN UINT16 f_usNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usNewTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry++; + + } + else /* f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry++; + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemoveSer + +Description: Removes a broadcast TSST from one of the output port of an + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to TSST remove structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveSer +UINT32 Oct6100ChannelBroadcastTsstRemoveSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove) +{ + UINT16 usChanIndex; + UINT16 usTsstIndex; + UINT16 usTsstEntry; + UINT16 usPrevTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiAssertChanTsstRemoveParams( f_pApiInstance, f_pChannelTsstRemove, &usChanIndex, &usTsstIndex, &usTsstEntry, &usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiInvalidateTsstRemoveStructs( f_pApiInstance, usChanIndex, usTsstIndex, f_pChannelTsstRemove->ulPort, f_pChannelTsstRemove->fRemoveAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseTsstRemoveResources( f_pApiInstance, f_pChannelTsstRemove, usChanIndex, usTsstIndex, usTsstEntry, usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChanTsstRemoveParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_pulChanIndex Pointer to a channel index. +f_pulNewTsstIndex Pointer to a TSST index within the TSST control memory. +f_pulNewTsstEntry Pointer to a TSST entry within the API TSST list. +f_pulPrevTsstEntry Pointer to the previous TSST entry. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChanTsstRemoveParams +UINT32 Oct6100ApiAssertChanTsstRemoveParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusTsstIndex, + OUT PUINT16 f_pusTsstEntry, + OUT PUINT16 f_pusPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstValue; + UINT16 usNumEntry; + + /* Check the provided handle. */ + if ( (f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstRemove->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT; + + /* Verify that the requested entry is present in the channel's port broadcast TSST.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + } + + /* Verify if at least one TSST is present on the channel port.*/ + if ( usNumEntry == 0 ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstRemove->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_E; + } + + /* Initialize the TSST entry to invalid.*/ + *f_pusTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusPrevTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusTsstIndex = cOCT6100_INVALID_INDEX; + + if ( f_pChannelTsstRemove->fRemoveAll != TRUE ) + { + /* Check the validity of the timeslot and Stream.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstRemove->ulTimeslot, + f_pChannelTsstRemove->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM; + } + else + { + return ulResult; + } + } + + /* Set the TSST value based on the timeslot and stream value.*/ + usTsstValue = (UINT16)( (f_pChannelTsstRemove->ulTimeslot << 5) | f_pChannelTsstRemove->ulStream ); + + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + if ( usTsstValue == pTsstEntry->usTsstValue ) + { + /* A match was found.*/ + *f_pusTsstEntry = usCurrentEntry; + *f_pusTsstIndex = pTsstEntry->usTsstMemoryIndex; + break; + } + + /* Move on to the next entry.*/ + *f_pusPrevTsstEntry = usCurrentEntry; + usCurrentEntry = pTsstEntry->usNextEntry; + } + + if ( *f_pusTsstEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateTsstRemoveStructs + +Description: Invalidate the entry of the broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_ulPort Channel port where the TSST are removed from. (only used if remove all == TRUE) +f_fRemoveAll Remove all flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateTsstRemoveStructs +UINT32 Oct6100ApiInvalidateTsstRemoveStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulPort, + IN BOOL f_fRemoveAll ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + if ( f_fRemoveAll == FALSE ) + { + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_fRemoveAll == TRUE */ + { + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT16 usTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Clear all entry associated to the selected port.*/ + if ( f_ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usTsstEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usTsstEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usTsstEntry ); + + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( ( pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usTsstEntry = pTsstEntry->usNextEntry; + + } while ( usTsstEntry != cOCT6100_INVALID_INDEX ); + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsstRemoveResources + +Description: Release all API resources associated to the Removed TSST and + update the channel entry accordingly. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_usTsstEntry TSST entry within the API's TSST list. +f_usPrevTsstEntry Previous TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsstRemoveResources +UINT32 Oct6100ApiReleaseTsstRemoveResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsstEntry, + IN UINT16 f_usPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tPOCT6100_API_TSST_ENTRY pPrevTsstEntry; + UINT16 usCurrentEntry; + UINT32 ulResult; + UINT32 ulTimeslot; + UINT32 ulStream; + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + if ( f_pChannelTsstRemove->fRemoveAll == FALSE ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry--; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry--; + } + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + f_usTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_pChannelTsstRemove->fRemoveAll == TRUE */ + { + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); /* Release the entry.*/ + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Clear the previous node.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + + } while ( usCurrentEntry != cOCT6100_INVALID_INDEX ); + + /* Reset the channel status.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + } + else + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + } + } + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelGetStatsSer + +Description: Serialized function that returns all the stats of the specified + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a channel stats structure. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelGetStatsSer +UINT32 Oct6100ApiChannelGetStatsSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS BurstParams; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstCount; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulTempData; + UINT32 ulMask; + UINT16 usChanIndex; + UINT16 ausReadData[ 32 ]; + + BYTE byRinEnergyRaw; + BYTE bySinEnergyRaw; + BYTE bySoutEnergyRaw; + INT32 lSoutEnergyIndB; + BYTE byCnEnergyRaw; + UINT16 usEchoDelayInFrames; + UINT16 usErlRaw; + + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusReadData = ausReadData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Check the reset stats flag.*/ + if ( f_pChannelStats->fResetStats != TRUE && f_pChannelStats->fResetStats != FALSE ) + return cOCT6100_ERR_CHANNEL_STATS_RESET; + + /* Check the provided handle. */ + if ( cOCT6100_HNDL_TAG_CHANNEL != (f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + usChanIndex = (UINT16)( f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelStats->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* Check the value of the max broadcast tsst.*/ + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts > cOCT6100_MAX_TSSTS ) + return cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST; + + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts != 0 ) + { + /* Check if memory was allocated by the user for the stream and timeslot values.*/ + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM; + } + + /* Copy the general configuration.*/ + f_pChannelStats->ulUserChanId = pChanEntry->ulUserChanId; + f_pChannelStats->ulEchoOperationMode = pChanEntry->byEchoOperationMode; + f_pChannelStats->fEnableToneDisabler = pChanEntry->fEnableToneDisabler; + f_pChannelStats->ulMutePortsMask = pChanEntry->usMutedPorts; + f_pChannelStats->fEnableExtToneDetection = pChanEntry->fEnableExtToneDetection; + + + + /* Copy the TDM configuration.*/ + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + + f_pChannelStats->TdmConfig.ulSinNumTssts = pChanEntry->TdmConfig.bySinNumTssts; + f_pChannelStats->TdmConfig.ulSinTimeslot = pChanEntry->TdmConfig.usSinTimeslot; + f_pChannelStats->TdmConfig.ulSinStream = pChanEntry->TdmConfig.usSinStream; + f_pChannelStats->TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw; + + f_pChannelStats->TdmConfig.ulSoutNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + f_pChannelStats->TdmConfig.ulSoutTimeslot = pChanEntry->TdmConfig.usSoutTimeslot; + f_pChannelStats->TdmConfig.ulSoutStream = pChanEntry->TdmConfig.usSoutStream; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw; + + /* Copy the SOUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_F; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Sout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + } + + f_pChannelStats->TdmConfig.ulRinNumTssts = pChanEntry->TdmConfig.byRinNumTssts; + f_pChannelStats->TdmConfig.ulRinTimeslot = pChanEntry->TdmConfig.usRinTimeslot; + f_pChannelStats->TdmConfig.ulRinStream = pChanEntry->TdmConfig.usRinStream; + f_pChannelStats->TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw; + + f_pChannelStats->TdmConfig.ulRoutNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + f_pChannelStats->TdmConfig.ulRoutTimeslot = pChanEntry->TdmConfig.usRoutTimeslot; + f_pChannelStats->TdmConfig.ulRoutStream = pChanEntry->TdmConfig.usRoutStream; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw; + + + /* Copy the ROUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_10; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Rout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + } + + /* Copy the VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = pChanEntry->VqeConfig.fEnableNlp; + f_pChannelStats->VqeConfig.ulComfortNoiseMode = pChanEntry->VqeConfig.byComfortNoiseMode; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = pChanEntry->VqeConfig.fEnableTailDisplacement; + if ( pChanEntry->VqeConfig.usTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailDisplacement = pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChannelStats->VqeConfig.ulTailDisplacement = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + + if ( pChanEntry->VqeConfig.usTailLength != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailLength = pChanEntry->VqeConfig.usTailLength; + else + f_pChannelStats->VqeConfig.ulTailLength = f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + + + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = pChanEntry->VqeConfig.fSinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = pChanEntry->VqeConfig.fRinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinLevelControl = pChanEntry->VqeConfig.fRinLevelControl; + f_pChannelStats->VqeConfig.fSoutLevelControl = pChanEntry->VqeConfig.fSoutLevelControl; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = pChanEntry->VqeConfig.fRinAutomaticLevelControl; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = pChanEntry->VqeConfig.fRinHighLevelCompensation; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = pChanEntry->VqeConfig.fSoutNoiseBleaching; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = pChanEntry->VqeConfig.chRinLevelControlGainDb; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + f_pChannelStats->VqeConfig.fAcousticEcho = pChanEntry->VqeConfig.fAcousticEcho; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = pChanEntry->VqeConfig.fDtmfToneRemoval; + + f_pChannelStats->VqeConfig.lDefaultErlDb = pChanEntry->VqeConfig.chDefaultErlDb; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = pChanEntry->VqeConfig.chAecDefaultErlDb; + f_pChannelStats->VqeConfig.ulAecTailLength = pChanEntry->VqeConfig.usAecTailLength; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = pChanEntry->VqeConfig.byNonLinearityBehaviorA; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = pChanEntry->VqeConfig.byNonLinearityBehaviorB; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = pChanEntry->VqeConfig.byDoubleTalkBehavior; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = pChanEntry->VqeConfig.fRoutNoiseReduction; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + f_pChannelStats->VqeConfig.fEnableMusicProtection = pChanEntry->VqeConfig.fEnableMusicProtection; + f_pChannelStats->VqeConfig.fIdleCodeDetection = pChanEntry->VqeConfig.fIdleCodeDetection; + + /* Copy the CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = pChanEntry->CodecConfig.byAdpcmNibblePosition; + + f_pChannelStats->CodecConfig.ulEncoderPort = pChanEntry->CodecConfig.byEncoderPort; + f_pChannelStats->CodecConfig.ulEncodingRate = pChanEntry->CodecConfig.byEncodingRate; + + f_pChannelStats->CodecConfig.ulDecoderPort = pChanEntry->CodecConfig.byDecoderPort; + f_pChannelStats->CodecConfig.ulDecodingRate = pChanEntry->CodecConfig.byDecodingRate; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = pChanEntry->CodecConfig.fEnableSilenceSuppression; + f_pChannelStats->CodecConfig.ulPhase = pChanEntry->CodecConfig.byPhase; + f_pChannelStats->CodecConfig.ulPhasingType = pChanEntry->CodecConfig.byPhasingType; + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsstEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingTsstEntry, pChanEntry->usPhasingTsstIndex ); + + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsstEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + + + /* Reset the stats and exit if the reset flag is set.*/ + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + } + + /*---------------------------------------------------------------------*/ + /* Update the API internal stats.*/ + + BurstParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + BurstParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsOfst; + BurstParams.ulReadLength = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsSize / 2; /* Length in words.*/ + + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the energy stat are found in the new memory location. */ + if ( ( pSharedInfo->ImageInfo.fRinEnergyStat == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutEnergyStat == TRUE ) ) + { + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 0 ] &= 0x00FF; + ausReadData[ 0 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 1 ] &= 0x00FF; + ausReadData[ 1 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + } + + byRinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 8 ) & 0xFF); + bySinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 0 ) & 0xFF); + bySoutEnergyRaw = (BYTE)(( ausReadData[ 1 ] >> 8 ) & 0xFF); + byCnEnergyRaw = (BYTE)(( ausReadData[ 5 ] >> 8 ) & 0xFF); + + usEchoDelayInFrames = (UINT16)(ausReadData[ 4 ]); + usErlRaw = ausReadData[ 2 ]; + + pChanEntry->byToneDisablerStatus = (UINT8)(( ausReadData[ 5 ] >> 0 ) & 0xFF); + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->usNumEchoPathChangesOfst = (UINT16)(ausReadData[ 3 ]); + pChanEntry->usNumEchoPathChanges = 0; + } + else /* if ( f_pChannelStats->fResetStats == FALSE ) */ + { + pChanEntry->usNumEchoPathChanges = (UINT16)( ausReadData[ 3 ] - pChanEntry->usNumEchoPathChangesOfst ); + } + + pChanEntry->sComfortNoiseLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byCnEnergyRaw ) & 0xFFFF ); + pChanEntry->sComfortNoiseLevel -= 12; + pChanEntry->sRinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byRinEnergyRaw ) & 0xFFFF ); + pChanEntry->sRinLevel -= 12; + pChanEntry->sSinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( bySinEnergyRaw ) & 0xFFFF ); + pChanEntry->sSinLevel -= 12; + lSoutEnergyIndB = Oct6100ApiOctFloatToDbEnergyByte( bySoutEnergyRaw ); + lSoutEnergyIndB -= 12; + + /* Process some stats only if the channel is converged.*/ + if ( ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET ) ) + { + /* Update the current ERL. */ + pChanEntry->sCurrentERL = (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( usErlRaw ) & 0xFFFF ); + pChanEntry->sCurrentERLE = (INT16)( ( lSoutEnergyIndB - pChanEntry->sSinLevel ) & 0xFFFF ); + pChanEntry->usCurrentEchoDelay = (UINT16)( usEchoDelayInFrames / 8 ); /* To convert in msec.*/ + + /* Update the max value if required.*/ + if ( pChanEntry->usCurrentEchoDelay > pChanEntry->usMaxEchoDelay || + pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + { + pChanEntry->usMaxEchoDelay = pChanEntry->usCurrentEchoDelay; + } + + if ( pChanEntry->sCurrentERL > pChanEntry->sMaxERL || + pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERL = pChanEntry->sCurrentERL; + } + + if ( pChanEntry->sCurrentERLE > pChanEntry->sMaxERLE || + pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERLE = pChanEntry->sCurrentERLE; + } + } + else + { + pChanEntry->sCurrentERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sCurrentERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usCurrentEchoDelay = cOCT6100_INVALID_STAT_W; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sRinAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sSoutAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + /*---------------------------------------------------------------------*/ + /* Return the real stats.*/ + + f_pChannelStats->ulNumEchoPathChanges = pChanEntry->usNumEchoPathChanges; + if ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + { + f_pChannelStats->fEchoCancellerConverged = TRUE; + } + else + { + f_pChannelStats->fEchoCancellerConverged = FALSE; + } + if ( pChanEntry->sCurrentERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERL = pChanEntry->sCurrentERL; + + if ( pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERL = pChanEntry->sMaxERL; + + if ( pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulMaxEchoDelay = pChanEntry->usMaxEchoDelay; + + if ( pChanEntry->sRinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lRinLevel = pChanEntry->sRinLevel; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sSinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lSinLevel = pChanEntry->sSinLevel; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + /* SIN level is not supported in this image. */ + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lRinAppliedGain = pChanEntry->VqeConfig.chRinLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + && ( ( pChanEntry->VqeConfig.fRinAutomaticLevelControl == TRUE ) + || ( pChanEntry->VqeConfig.fRinHighLevelCompensation == TRUE ) ) ) + { + f_pChannelStats->lRinAppliedGain = pChanEntry->sRinAppliedGain; + } + + f_pChannelStats->lSoutAppliedGain = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + && ( pChanEntry->VqeConfig.fSoutAutomaticLevelControl == TRUE ) ) + { + f_pChannelStats->lSoutAppliedGain = pChanEntry->sSoutAppliedGain; + } + + if ( pChanEntry->usCurrentEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulCurrentEchoDelay = pChanEntry->usCurrentEchoDelay; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sCurrentERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERLE = pChanEntry->sCurrentERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERLE = pChanEntry->sMaxERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lComfortNoiseLevel = pChanEntry->sComfortNoiseLevel; + f_pChannelStats->ulToneDisablerStatus = pChanEntry->byToneDisablerStatus; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSinVoiceDetectedStat == TRUE ) + { + UINT32 ulVoiceDetectedBytesOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.usDwordOffset * 4; + UINT32 ulVoiceDetectedBitOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byBitOffset; + UINT32 ulVoiceDetectedFieldSize = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byFieldSize; + + /* Set the channel root base address.*/ + UINT32 ulChannelRootBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( usChanIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst; + + ReadParams.ulReadAddress = ulChannelRootBaseAddress + ulVoiceDetectedBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulVoiceDetectedFieldSize, ulVoiceDetectedBitOfst, &ulMask ); + + if ( ( ulTempData & ulMask ) != 0x0 ) + f_pChannelStats->fSinVoiceDetected = TRUE; + else + f_pChannelStats->fSinVoiceDetected = FALSE; + } + + /*---------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveEchoEntry + +Description: Reserves one of the echo channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusEchoIndex Resulting index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveEchoEntry +UINT32 Oct6100ApiReserveEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + UINT32 ulEchoIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocAlloc( pEchoAlloc, &ulEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_11; + } + + *f_pusEchoIndex = (UINT16)( ulEchoIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseEchoEntry + +Description: Releases the specified ECHO channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usEchoIndex Index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseEchoEntry +UINT32 Oct6100ApiReleaseEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocDealloc( pEchoAlloc, f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_12; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBiDirChanEntry + +Description: Reserves one of the bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusBiDirChanIndex Resulting index reserved in the bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBiDirChanEntry +UINT32 Oct6100ApiReserveBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + UINT32 ulBiDirChanIndex; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pChanAlloc, &ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_9F; + } + + *f_pusBiDirChanIndex = (UINT16)( ulBiDirChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChanEntry + +Description: Releases the specified bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulBiDirChanIndex Bidirectional channel index within the API's Bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChanEntry +UINT32 Oct6100ApiReleaseBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pChanAlloc, f_ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_A0; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckTdmConfig + +Description: This function will check the validity of the TDM config parameter + of an Open TDM config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig TDM config of the channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckTdmConfig +UINT32 Oct6100ApiCheckTdmConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig ) +{ + UINT32 ulResult; + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRinNumTssts != 1 && + f_pTdmConfig->ulRinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS; + + /* Check the RIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRinNumTssts, + f_pTdmConfig->ulRinTimeslot, + f_pTdmConfig->ulRinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRoutNumTssts != 1 && + f_pTdmConfig->ulRoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRoutNumTssts, + f_pTdmConfig->ulRoutTimeslot, + f_pTdmConfig->ulRoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSinNumTssts != 1 && + f_pTdmConfig->ulSinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS; + + /* Check the SIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSinNumTssts, + f_pTdmConfig->ulSinTimeslot, + f_pTdmConfig->ulSinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSoutNumTssts != 1 && + f_pTdmConfig->ulSoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSoutNumTssts, + f_pTdmConfig->ulSoutTimeslot, + f_pTdmConfig->ulSoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the PCM law parameters.*/ + if ( f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_RIN_PCM_LAW; + + if ( f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SIN_PCM_LAW; + + if ( f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW; + + if ( f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW; + + /*==============================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckVqeConfig + +Description: This function will check the validity of the VQE config parameter + of an Open VQE config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_fEnableToneDisabler Whether the tone disabler is active or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckVqeConfig +UINT32 Oct6100ApiCheckVqeConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN BOOL f_fEnableToneDisabler ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + if ( f_pVqeConfig->fEnableNlp != TRUE && f_pVqeConfig->fEnableNlp != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_NLP; + + if ( f_pVqeConfig->fEnableNlp == TRUE && pImageInfo->fNlpControl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL; + + + + /* Check the comfort noise mode.*/ + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF && pImageInfo->fComfortNoise == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE; + + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_NORMAL && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_EXTENDED && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_FAST_LATCH && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE; + + /* Check the DC offset removal.*/ + if ( f_pVqeConfig->fSinDcOffsetRemoval != TRUE && f_pVqeConfig->fSinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fSinDcOffsetRemoval == TRUE && pImageInfo->fSinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval != TRUE && f_pVqeConfig->fRinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval == TRUE && pImageInfo->fRinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM; + + /* Check the Level control.*/ + if ( f_pVqeConfig->fRinLevelControl != TRUE && f_pVqeConfig->fRinLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL; + + if ( f_pVqeConfig->fSoutLevelControl != TRUE && f_pVqeConfig->fSoutLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->lRinLevelControlGainDb < -24 ) || ( f_pVqeConfig->lRinLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->lSoutLevelControlGainDb < -24 ) || ( f_pVqeConfig->lSoutLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl != TRUE ) && ( f_pVqeConfig->fRinAutomaticLevelControl != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation != TRUE ) && ( f_pVqeConfig->fRinHighLevelCompensation != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) && ( pImageInfo->fRinAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) && ( pImageInfo->fRinHighLevelCompensation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL; + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lRinAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL; + + if ( ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb < -40 || f_pVqeConfig->lRinHighLevelCompensationThresholdDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD; + } + + if ( f_pVqeConfig->fSoutAutomaticLevelControl != TRUE && f_pVqeConfig->fSoutAutomaticLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC; + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fSoutLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL; + + if ( ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lSoutAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != TRUE && + f_pVqeConfig->fSoutAdaptiveNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && pImageInfo->fAdaptiveNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction != TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE && pImageInfo->fConferencingNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR; + + /* Validate Sout noise bleaching parameter. */ + if ( f_pVqeConfig->fSoutNoiseBleaching != TRUE && + f_pVqeConfig->fSoutNoiseBleaching != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING; + + /* Check if firmware supports Sout noise bleaching. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE && pImageInfo->fSoutNoiseBleaching == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING; + + /* If Sout noise bleaching is requested, no ANR or CNR shall be activated. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE ) + { + /* No xNR! */ + if ( ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + || ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE ) ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR; + } + + /* Cannot activate both ANR and CNR when noise bleaching is present */ + if ( pImageInfo->fSoutNoiseBleaching == TRUE ) + { + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + return cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY; + } + + /* Validate the DTMF tone removal parameter.*/ + if ( f_pVqeConfig->fDtmfToneRemoval != TRUE && f_pVqeConfig->fDtmfToneRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_REMOVAL; + + if ( f_pVqeConfig->fDtmfToneRemoval == TRUE && pImageInfo->fToneRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL; + + + + /* Check the Tail displacement enable.*/ + if ( f_pVqeConfig->fEnableTailDisplacement != TRUE && f_pVqeConfig->fEnableTailDisplacement != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE && pImageInfo->fTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT; + + /* Check the Tail displacement value.*/ + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + if ( f_pVqeConfig->ulTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( pImageInfo->fPerChannelTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL; + + /* Check that this value is not greater then what the image supports. */ + if ( f_pVqeConfig->ulTailDisplacement > pImageInfo->usMaxTailDisplacement ) + return cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID; + } + } + + /* Check the tail length value. */ + if ( f_pVqeConfig->ulTailLength != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( ( pImageInfo->fPerChannelTailLength == FALSE ) + && ( (UINT16)( f_pVqeConfig->ulTailLength & 0xFFFF ) != pImageInfo->usMaxTailLength ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH; + + if ( ( f_pVqeConfig->ulTailLength < 32 ) || ( f_pVqeConfig->ulTailLength > 128 ) + || ( ( f_pVqeConfig->ulTailLength % 4 ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH; + + /* Check if the requested tail length is supported by the chip. */ + if ( f_pVqeConfig->ulTailLength > pImageInfo->usMaxTailLength ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID; + } + + /* Validate the acoustic echo cancellation parameter.*/ + if ( f_pVqeConfig->fAcousticEcho != TRUE && f_pVqeConfig->fAcousticEcho != FALSE ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE && pImageInfo->fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + /* Check if acoustic echo tail length configuration is supported in the image. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) && ( pImageInfo->fAecTailLength == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + /* Check the requested acoustic echo tail length. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) + && ( f_pVqeConfig->ulAecTailLength != 256 ) + && ( f_pVqeConfig->ulAecTailLength != 512 ) + && ( f_pVqeConfig->ulAecTailLength != 1024 ) ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + UINT32 ulTailSum; + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* The tail sum must be smaller then the requested AEC tail length. */ + if ( ulTailSum > f_pVqeConfig->ulAecTailLength ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM; + } + } + + /* Validate the Default ERL parameter.*/ + if ( f_pVqeConfig->lDefaultErlDb != -6 && pImageInfo->fDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL; + + if ( ( f_pVqeConfig->lDefaultErlDb != 0 ) && + ( f_pVqeConfig->lDefaultErlDb != -3 ) && + ( f_pVqeConfig->lDefaultErlDb != -6 ) && + ( f_pVqeConfig->lDefaultErlDb != -9 ) && + ( f_pVqeConfig->lDefaultErlDb != -12 ) ) + return cOCT6100_ERR_CHANNEL_DEFAULT_ERL; + + /* Validate the Default AEC ERL parameter.*/ + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && pImageInfo->fAecDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL; + + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && f_pVqeConfig->lAecDefaultErlDb != -3 && f_pVqeConfig->lAecDefaultErlDb != -6 ) + return cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL; + + /* Validate the non-linearity A parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorA != 1 && pImageInfo->fNonLinearityBehaviorA == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK; + + if ( f_pVqeConfig->ulNonLinearityBehaviorA >= 14 ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK; + + /* Validate the non-linearity B parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorB != 0 && pImageInfo->fNonLinearityBehaviorB == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B; + + if ( f_pVqeConfig->ulNonLinearityBehaviorB >= 9 ) + return cOCT6100_ERR_CHANNEL_NON_LINEARITY_B; + + /* Check if configuring the double talk behavior is supported in the firmware. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && pImageInfo->fDoubleTalkBehavior == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE; + + /* Validate the double talk behavior mode parameter. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE; + + /* Validate the Sout automatic listener enhancement ratio. */ + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE; + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_ALE_RATIO; + + /* Validate the Sout natural listener enhancement ratio. */ + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != TRUE && f_pVqeConfig->fSoutNaturalListenerEnhancement != FALSE ) + return cOCT6100_ERR_CHANNEL_NLE_FLAG; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + { + if ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_NLE_RATIO; + } + + /* Both ALE and NLE cannot be activated simultaneously. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + && ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) ) + return cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY; + + /* Validate Rout noise reduction. */ + if ( f_pVqeConfig->fRoutNoiseReduction != TRUE && f_pVqeConfig->fRoutNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION; + + /* Check if Rout noise reduction is supported. */ + if ( f_pVqeConfig->fRoutNoiseReduction == TRUE && pImageInfo->fRoutNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR; + + /*Check if noise reduction level gain is supported*/ + if ( ( pImageInfo->fRoutNoiseReductionLevel == FALSE ) && ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + if ( ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != 0 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -6 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -12 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + /* Check if ANR SNRE is supported. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) && ( pImageInfo->fAnrSnrEnhancement == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate Sout ANR SNR enhancement. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -9 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -12 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -15 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -21 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -24 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -27 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -30 ) ) + return cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate ANR voice-noise segregation. */ + if ( f_pVqeConfig->ulAnrVoiceNoiseSegregation > 15 ) + return cOCT6100_ERR_CHANNEL_ANR_SEGREGATION; + + /* Check if ANR VN segregation is supported. */ + if ( ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != 6 ) && ( pImageInfo->fAnrVoiceNoiseSegregation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION; + + /* Check if the loaded image supports tone disabler VQE activation delay. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != 300 ) + && ( pImageInfo->fToneDisablerVqeActivationDelay == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check if the specified tone disabler VQE activation delay is correct. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay < 300 ) + || ( ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) % 512 ) != 0 ) ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check the enable music protection flag. */ + if ( ( f_pVqeConfig->fEnableMusicProtection != TRUE ) && ( f_pVqeConfig->fEnableMusicProtection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION; + + /* The music protection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fEnableMusicProtection == TRUE ) && + ( pImageInfo->fMusicProtection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION; + + /* Check the enable idle code detection flag. */ + if ( ( f_pVqeConfig->fIdleCodeDetection != TRUE ) && ( f_pVqeConfig->fIdleCodeDetection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION; + + /* The idle code detection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fIdleCodeDetection == TRUE ) && ( pImageInfo->fIdleCodeDetection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION; + + /* The idle code detection module can be disabled only if idle code detection configuration */ + /* is supported in the image. */ + if ( pImageInfo->fIdleCodeDetection == TRUE ) + { + if ( ( f_pVqeConfig->fIdleCodeDetection == FALSE ) && ( pImageInfo->fIdleCodeDetectionConfiguration == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCodecConfig + +Description: This function will check the validity of the Codec config parameter + of an Open Codec config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCodecConfig Codec config of the channel. +f_ulDecoderNumTssts Number of TSST for the decoder. +f_pusPhasingTsstIndex Pointer to the Phasing TSST index within the API's phasing TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckCodecConfig +UINT32 Oct6100ApiCheckCodecConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_CODEC f_pCodecConfig, + IN UINT32 f_ulDecoderNumTssts, + OUT PUINT16 f_pusPhasingTsstIndex ) +{ + + /* Verify the ADPCM nibble value.*/ + if ( f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE; + + /* Verify the Encoder port.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Verify the Decoder port.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_SIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* The codec cannot be on the same stream.*/ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + /* Verify if the requested functions are supported by the chip.*/ + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + if ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING; + } + + /* Check if encoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING && + f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Check if decoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* Check Encoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + /* Check the Encoder compression rate.*/ + if ( ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + /* Verify phasing information.*/ + if ( f_pCodecConfig->ulPhasingType != cOCT6100_SINGLE_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_DUAL_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TYPE; + + /* Verify the silence suppression parameters.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression != TRUE && + f_pCodecConfig->fEnableSilenceSuppression != FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pApiInstance->pSharedInfo->ImageInfo.fSilenceSuppression == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingType == cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + if ( f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + /* Silence suppression can only be performed if the encoder is using the SOUT port.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT; + + /* Check phasing TSST info if phasing is required.*/ + if ( f_pCodecConfig->ulPhasingTsstHndl != cOCT6100_INVALID_HANDLE ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_PHASING_TSST ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + *f_pusPhasingTsstIndex = (UINT16)( f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusPhasingTsstIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPhasingTssts ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, *f_pusPhasingTsstIndex ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pCodecConfig->ulPhasingTsstHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Verify if the state of the phasing TSST.*/ + if ( pPhasingEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN; + if ( ulEntryOpenCnt != pPhasingEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + /* Check the specified phase value against the phasing length of the phasing TSST.*/ + if ( ( f_pCodecConfig->ulPhase == 0 ) + || ( f_pCodecConfig->ulPhase >= pPhasingEntry->usPhasingLength ) ) + return cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE; + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + + + /* Check Decoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + /* Check the Decoding rate.*/ + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + + /* Make sure that two timeslot are allocated if PCM-ECHO encoded is selected.*/ + if ( (f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_ulDecoderNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_MISSING_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteInputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsstIndex TSST index within the TSST control memory. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulTsstInputLaw PCM law of the input TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteInputTsstControlMemory +UINT32 Oct6100ApiWriteInputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulTsstInputLaw ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_INPUT_TSST; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + /* Set the PCM law.*/ + WriteParams.usWriteData |= f_ulTsstInputLaw << cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteOutputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteOutputTsstControlMemory +UINT32 Oct6100ApiWriteOutputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT32 f_ulNumTssts, + IN UINT16 f_usTsiMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET; + WriteParams.usWriteData |= (f_ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEncoderMemory + +Description: This function configure a Encoded memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulEncoderIndex Index of the encoder block within the ADPCM context memory. +f_ulCompType Compression rate of the encoder. +f_usTsiMemIndex TSI index within the TSI chariot memory used by the encoder. +f_ulEnableSilenceSuppression Silence suppression enable flag. +f_ulAdpcmNibblePosition ADPCM nibble position. +f_usPhasingTsstIndex Phasing TSST index within the API's Phassing TSST list. +f_ulPhasingType Type of the Phasing TSST. +f_ulPhase Phase used with this encoder. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEncoderMemory +UINT32 Oct6100ApiWriteEncoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulEncoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulEnableSilenceSuppression, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT16 f_usPhasingTsstIndex, + IN UINT32 f_ulPhasingType, + IN UINT32 f_ulPhase ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_ulEncoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ENCODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the phasing TSST number.*/ + if ( f_usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + WriteParams.usWriteData = (UINT16)( f_usPhasingTsstIndex << cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET ); + else + WriteParams.usWriteData = 0; + + /* Set the phasing type and the phase value if required.*/ + switch( f_ulPhasingType ) + { + case cOCT6100_NO_PHASING: + WriteParams.usWriteData |= 0x1 << 10; + break; + case cOCT6100_SINGLE_PHASING: + WriteParams.usWriteData |= f_ulPhase; + break; + case cOCT6100_DUAL_PHASING: + WriteParams.usWriteData |= 0x1 << 11; + WriteParams.usWriteData |= f_ulPhase; + break; + default: + /* No problem. */ + break; + } + + /* Set the silence suppression flag.*/ + WriteParams.usWriteData |= f_ulEnableSilenceSuppression << cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET; + + /* Set the nibble position.*/ + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDecoderMemory + +Description: This function configure a Decoder memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usDecoderIndex Index of the decoder block within the ADPCM context memory. +f_ulCompType Decompression rate of the decoder. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulPcmLaw PCM law of the decoded samples. +f_ulAdpcmNibblePosition ADPCM nibble position. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDecoderMemory +UINT32 Oct6100ApiWriteDecoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usDecoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulPcmLaw, + IN UINT32 f_ulAdpcmNibblePosition ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usDecoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_DECODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the nibble position.*/ + WriteParams.usWriteData = (UINT16)( f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET ); + + /* Set the law.*/ + WriteParams.usWriteData |= f_ulPcmLaw << cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearConversionMemory + +Description: This function clears a conversion memory entry in internal + memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usConversionMemIndex Index of the block within the conversion memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearConversionMemory +UINT32 Oct6100ApiClearConversionMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulBaseAddress; + UINT16 usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.usWriteData = 0; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*==============================================================================*/ + /* Clear the entry */ + ulBaseAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usConversionMemIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + /* The "activate" bit at offset +6 must be cleared first. */ + WriteParams.ulWriteAddress = ulBaseAddress + 6; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read at 0x200 to make sure there is no corruption on channel 0. */ + ReadParams.ulReadAddress = 0x200; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Then clear the rest of the structure. */ + WriteParams.ulWriteAddress = ulBaseAddress + 4; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress + 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeMemory + +Description: This function configure an echo memory entry in internal memory and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeMemory +UINT32 Oct6100ApiWriteVqeMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + UINT32 ulResult; + + /* Write the NLP software configuration structure. */ + ulResult = Oct6100ApiWriteVqeNlpMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the AF software configuration structure. */ + ulResult = Oct6100ApiWriteVqeAfMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +UINT32 oct6100_retrieve_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 *f_pulConfigDword) +{ + tOCT6100_READ_PARAMS _ReadParams; + UINT16 _usReadData; + UINT32 ulResult = cOCT6100_ERR_FATAL_8E; + (*f_pulConfigDword) = cOCT6100_INVALID_VALUE; + + _ReadParams.pProcessContext = f_pApiInst->pProcessContext; + mOCT6100_ASSIGN_USER_READ_WRITE_OBJ(f_pApiInst, _ReadParams); + _ReadParams.ulUserChipId = f_pApiInst->pSharedInfo->ChipConfig.ulUserChipId; + _ReadParams.pusReadData = &_usReadData; + + /* Read the first 16 bits.*/ + _ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API(_ReadParams, ulResult); + if (ulResult == cOCT6100_ERR_OK) { + /* Save data.*/ + (*f_pulConfigDword) = _usReadData << 16; + + /* Read the last 16 bits .*/ + _ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API(_ReadParams, ulResult); + if (ulResult == cOCT6100_ERR_OK) { + /* Save data.*/ + (*f_pulConfigDword) |= _usReadData; + ulResult = cOCT6100_ERR_OK; + } + } + return ulResult; +} + +UINT32 oct6100_save_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 f_ulConfigDword) +{ + UINT32 ulResult; + + /* Write the config DWORD. */ + tOCT6100_WRITE_PARAMS _WriteParams; + + _WriteParams.pProcessContext = f_pApiInst->pProcessContext; + mOCT6100_ASSIGN_USER_READ_WRITE_OBJ(f_pApiInst, _WriteParams) + _WriteParams.ulUserChipId = f_pApiInst->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the first 16 bits. */ + _WriteParams.ulWriteAddress = f_ulAddress; + _WriteParams.usWriteData = (UINT16)((f_ulConfigDword >> 16) & 0xFFFF); + mOCT6100_DRIVER_WRITE_API(_WriteParams, ulResult); + + if (ulResult == cOCT6100_ERR_OK) { + /* Write the last word. */ + _WriteParams.ulWriteAddress = f_ulAddress + 2; + _WriteParams.usWriteData = (UINT16)(f_ulConfigDword & 0xFFFF); + mOCT6100_DRIVER_WRITE_API(_WriteParams, ulResult); + } + return ulResult; +} + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeNlpMemory + +Description: This function configures the NLP related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeNlpMemory +UINT32 Oct6100ApiWriteVqeNlpMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + BOOL fEchoOperationModeChanged; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Configure the CPU NLP configuration of the channel feature by feature.*/ + + ulNlpConfigBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /* Configure Adaptive Noise Reduction.*/ + if (pSharedInfo->ImageInfo.fAdaptiveNoiseReduction == TRUE) { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) + ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutAdaptiveNoiseReduction ) << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, ANR must be activated. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutNoiseBleaching ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Rout Noise Reduction. */ + if (pSharedInfo->ImageInfo.fRoutNoiseReduction == TRUE) { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set noise reduction on the Rout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRoutNoiseReduction ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if (pSharedInfo->ImageInfo.fRoutNoiseReductionLevel == TRUE) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( (f_pVqeConfig->lRoutNoiseReductionLevelGainDb != pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb ) + ||( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrValOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrValOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrValOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if (f_pVqeConfig->fRoutNoiseReduction == TRUE) + { + switch( f_pVqeConfig->lRoutNoiseReductionLevelGainDb) + { + case 0: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + case -6: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -18: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + } + } + else + ulTempData |= ( 0 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + } + + /* Configure Sout ANR SNR enhancement. */ + if ( pSharedInfo->ImageInfo.fAnrSnrEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != pChanEntry->VqeConfig.chAnrSnrEnhancementDb ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR SNR enhancement on the Sout port. */ + switch( f_pVqeConfig->lAnrSnrEnhancementDb ) + { + case -9: ulTempData |= ( 7 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 6 << ulFeatureBitOffset ); + break; + case -15: ulTempData |= ( 5 << ulFeatureBitOffset ); + break; + case -21: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + case -24: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -27: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -30: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 4 << ulFeatureBitOffset ); + /* -18 */ + break; + } + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Sout ANR voice-noise segregation. */ + if ( pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR voice-noise segregation on the Sout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->ulAnrVoiceNoiseSegregation ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure the tone disabler VQE activation delay. */ + if ( pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tone disabler VQE activation delay. The VQE activation delay */ + /* is only set if the tone disabler is activated. */ + if ( f_pChannelOpen->fEnableToneDisabler == TRUE ) + ulTempData |= ( ( (UINT32)( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) / 512 ) ) << ulFeatureBitOffset ); + else + ulTempData |= ( 0 ) << ulFeatureBitOffset; + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Conferencing Noise Reduction.*/ + if ( pSharedInfo->ImageInfo.fConferencingNoiseReduction == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutConferencingNoiseReduction != pChanEntry->VqeConfig.fSoutConferencingNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set conferencing noise reduction on the SOUT port. */ + ulTempData |= (f_pVqeConfig->fSoutConferencingNoiseReduction << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, CNR must be activated. */ + ulTempData |= (f_pVqeConfig->fSoutNoiseBleaching << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on RIN ports.*/ + if ( pSharedInfo->ImageInfo.fRinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRinDcOffsetRemoval != pChanEntry->VqeConfig.fRinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* The write the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on SIN ports.*/ + if ( pSharedInfo->ImageInfo.fSinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fSinDcOffsetRemoval != pChanEntry->VqeConfig.fSinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the level control. */ + if ( ( pChanEntry->byEchoOperationMode != f_pChannelOpen->ulEchoOperationMode ) + && ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NORMAL ) ) + fEchoOperationModeChanged = TRUE; + else + fEchoOperationModeChanged = FALSE; + + /* If opening the channel, all level control configuration must be written. */ + if ( f_fModifyOnly == FALSE ) + fEchoOperationModeChanged = TRUE; + ulResult = Oct6100ApiSetChannelLevelControl( f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + fEchoOperationModeChanged ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the background noise freeze.*/ + if ( pSharedInfo->ImageInfo.fComfortNoise == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulComfortNoiseMode != pChanEntry->VqeConfig.byComfortNoiseMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( f_pVqeConfig->ulComfortNoiseMode << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the state of the NLP */ + if ( pSharedInfo->ImageInfo.fNlpControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableNlp != pChanEntry->VqeConfig.fEnableNlp ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpControlFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fEnableNlp == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail configuration. */ + ulResult = Oct6100ApiSetChannelTailConfiguration( + f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == FALSE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format. (In energy) */ + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear the defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic echo control.*/ + if ( pSharedInfo->ImageInfo.fAcousticEcho == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fAcousticEcho ) << ulFeatureBitOffset ); + + /* Then save the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic Echo Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fAecDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lAecDefaultErlDb != pChanEntry->VqeConfig.chAecDefaultErlDb ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + /* Convert the DB value to octasic's float format. (In energy) */ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lAecDefaultErlDb ); + } + else + { + /* Clear the AEC defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DTMF tone removal bit.*/ + if ( pSharedInfo->ImageInfo.fToneRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fDtmfToneRemoval != pChanEntry->VqeConfig.fDtmfToneRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fDtmfToneRemoval ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + + + /* Set the non-linear behavior A.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorA == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulNonLinearityBehaviorA != pChanEntry->VqeConfig.byNonLinearityBehaviorA ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + UINT16 ausLookupTable[ 14 ] = { 0x3663, 0x3906, 0x399C, 0x3A47, 0x3B06, 0x3B99, 0x3C47, 0x3D02, 0x3D99, 0x3E47, 0x3F00, 0x3F99, 0x4042, 0x4100 }; + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /*If we support ANR level the TLV is shared over 2 bits*/ + if (ulFeatureBitOffset == 18) + { + ulFeatureBitOffset -= 2; + ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] &= 0xFFFC; + } + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + else + ulTempData |= ( ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE && f_fClearPlayoutPointers == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = TRUE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Write the 2100 Hz Echo Disabling mode */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* This is a disable bit, so it must be set only if the enable flag is set to false. */ + if ( f_pChannelOpen->fEnableToneDisabler == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the Nlp Trivial enable flag. */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( + + ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + ulTempData |= TRUE << ulFeatureBitOffset; + } + + + /* Then write the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the double talk behavior mode. */ + if ( pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulDoubleTalkBehavior != pChanEntry->VqeConfig.byDoubleTalkBehavior ) ) ) + { + /* The field is located in the CPURO structure. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulDoubleTalkBehavior << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the music protection enable. */ + if ( ( pSharedInfo->ImageInfo.fMusicProtection == TRUE ) + && ( pSharedInfo->ImageInfo.fMusicProtectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableMusicProtection != pChanEntry->VqeConfig.fEnableMusicProtection ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fEnableMusicProtection == TRUE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeAfMemory + +Description: This function configures the AF related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeAfMemory +UINT32 Oct6100ApiWriteVqeAfMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulAfConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Write the AF CPU configuration of the channel feature by feature.*/ + + /* Calculate AF CPU configuration base address. */ + ulAfConfigBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /*==============================================================================*/ + /* Program the Maximum echo point within the Main channel memory.*/ + if ( pSharedInfo->ImageInfo.fMaxEchoPoint == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + /* Write the echo tail length */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format.*/ + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear max echo point. No echo cancellation here. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= usTempData << ulFeatureBitOffset; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the non-linear behavior B.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorB == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulNonLinearityBehaviorB != pChanEntry->VqeConfig.byNonLinearityBehaviorB ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulNonLinearityBehaviorB << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the listener enhancement feature. */ + if ( pSharedInfo->ImageInfo.fListenerEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveAleOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ulGainDb << ulFeatureBitOffset ); + } + else if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ( 0x80 | ulGainDb ) << ulFeatureBitOffset ); + } + + /* Now write the DWORD where the field is located containing the new configuration. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the idle code detection enable. */ + if ( ( pSharedInfo->ImageInfo.fIdleCodeDetection == TRUE ) + && ( pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fIdleCodeDetection != pChanEntry->VqeConfig.fIdleCodeDetection ) ) ) + { + /* Calculate base address in the AF software configuration. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fIdleCodeDetection == FALSE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the AFT control field. */ + if ( pSharedInfo->ImageInfo.fAftControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AftControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AftControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AftControlOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* If the operation mode is no echo, set the field such that echo cancellation is disabled. */ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + ulTempData |= ( 0x1234 << ulFeatureBitOffset ); + } + else if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + { + /* For clarity. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEchoMemory + +Description: This function configure an echo memory entry in internal memory.and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usEchoIndex Echo channel index within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEchoMemory +UINT32 Oct6100ApiWriteEchoMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) + +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulRinPcmLaw; + UINT32 ulRoutPcmLaw; + UINT32 ulSinPcmLaw; + UINT32 ulSoutPcmLaw; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Set immediately the PCM law to be programmed in the SSPX and NLP memory.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + } + + /*==============================================================================*/ + /* Configure the Global Static Configuration of the channel.*/ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulRoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + /* Set the circular buffer size.*/ + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulSinPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst ) & 0x07FFFF00; + ulTempData |= ( ulSoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* ECHO SSPX Memory configuration.*/ + + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( f_usEchoIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + + /* ECHO memory BASE + 2 */ + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + + /* Set the echo control field.*/ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + WriteParams.usWriteData |= cOCT6100_ECHO_OP_MODE_NORMAL << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + else if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL ) + { + WriteParams.usWriteData |= f_pChannelOpen->ulEchoOperationMode << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + + /* Set the SIN/SOUT law.*/ + WriteParams.usWriteData |= ulSinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulSoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usSinSoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ECHO memory BASE */ + WriteParams.ulWriteAddress -= 2; + WriteParams.usWriteData = cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY; + + /* Set the RIN/ROUT law.*/ + WriteParams.usWriteData |= ulRinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulRoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the RIN external echo control bit.*/ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_EXTERNAL ) + WriteParams.usWriteData |= cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usRinRoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateOpenStruct + +Description: This function will copy the new parameter from the modify structure + into a channel open structure to be processed later by the same path + as the channel open function. + If a parameter is set to keep previous, it's current value will be + extracted from the channel entry in the API. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +IN f_pApiInstance Pointer to an API instance structure. +IN f_pChanModify Pointer to a channel modify structure. +IN OUT f_pChanOpen Pointer to a channel open structure. +IN f_pChanEntry Pointer to an API channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateOpenStruct +UINT32 Oct6100ApiUpdateOpenStruct( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChanModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChanOpen, + IN tPOCT6100_API_CHANNEL f_pChanEntry ) +{ + + /* Check the generic Echo parameters.*/ + if ( f_pChanModify->ulEchoOperationMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulEchoOperationMode = f_pChanEntry->byEchoOperationMode; + else + f_pChanOpen->ulEchoOperationMode = f_pChanModify->ulEchoOperationMode; + + + if ( f_pChanModify->fEnableToneDisabler == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->fEnableToneDisabler = f_pChanEntry->fEnableToneDisabler; + else + f_pChanOpen->fEnableToneDisabler = f_pChanModify->fEnableToneDisabler; + + + if ( f_pChanModify->ulUserChanId == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulUserChanId = f_pChanEntry->ulUserChanId; + else + f_pChanOpen->ulUserChanId = f_pChanModify->ulUserChanId; + + + + /*======================================================================*/ + /* Now update the TDM config.*/ + /* Rin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanEntry->TdmConfig.byRinPcmLaw; + else + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanModify->TdmConfig.ulRinPcmLaw; + + /* Sin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanEntry->TdmConfig.bySinPcmLaw; + else + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanModify->TdmConfig.ulSinPcmLaw; + + /* Rout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanEntry->TdmConfig.byRoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanModify->TdmConfig.ulRoutPcmLaw; + + /* Sout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanEntry->TdmConfig.bySoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanModify->TdmConfig.ulSoutPcmLaw; + + + /* Rin Timeslot */ + if ( f_pChanModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanEntry->TdmConfig.usRinTimeslot; + else + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanModify->TdmConfig.ulRinTimeslot; + + /* Rin Stream */ + if ( f_pChanModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinStream = f_pChanEntry->TdmConfig.usRinStream; + else + f_pChanOpen->TdmConfig.ulRinStream = f_pChanModify->TdmConfig.ulRinStream; + + /* Rin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanEntry->TdmConfig.byRinNumTssts; + else + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanModify->TdmConfig.ulRinNumTssts; + + + /* Sin Timeslot */ + if ( f_pChanModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanEntry->TdmConfig.usSinTimeslot; + else + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanModify->TdmConfig.ulSinTimeslot; + + /* Sin Stream */ + if ( f_pChanModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinStream = f_pChanEntry->TdmConfig.usSinStream; + else + f_pChanOpen->TdmConfig.ulSinStream = f_pChanModify->TdmConfig.ulSinStream; + + /* Sin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanEntry->TdmConfig.bySinNumTssts; + else + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanModify->TdmConfig.ulSinNumTssts; + + + /* Rout Timeslot */ + if ( f_pChanModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanEntry->TdmConfig.usRoutTimeslot; + else + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanModify->TdmConfig.ulRoutTimeslot; + + /* Rout Stream */ + if ( f_pChanModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanEntry->TdmConfig.usRoutStream; + else + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanModify->TdmConfig.ulRoutStream; + + /* Rout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanEntry->TdmConfig.byRoutNumTssts; + else + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanModify->TdmConfig.ulRoutNumTssts; + + + /* Sout Timeslot */ + if ( f_pChanModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanEntry->TdmConfig.usSoutTimeslot; + else + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanModify->TdmConfig.ulSoutTimeslot; + + /* Sout Stream */ + if ( f_pChanModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanEntry->TdmConfig.usSoutStream; + else + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanModify->TdmConfig.ulSoutStream; + + /* Sout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanEntry->TdmConfig.bySoutNumTssts; + else + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanModify->TdmConfig.ulSoutNumTssts; + + /*======================================================================*/ + + /*======================================================================*/ + /* Now update the VQE config.*/ + + if ( f_pChanModify->VqeConfig.ulComfortNoiseMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanEntry->VqeConfig.byComfortNoiseMode; + else + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanModify->VqeConfig.ulComfortNoiseMode; + + if ( f_pChanModify->VqeConfig.fEnableNlp == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanEntry->VqeConfig.fEnableNlp; + else + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanModify->VqeConfig.fEnableNlp; + + if ( f_pChanModify->VqeConfig.fEnableTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanEntry->VqeConfig.fEnableTailDisplacement; + else + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanModify->VqeConfig.fEnableTailDisplacement; + + if ( f_pChanModify->VqeConfig.ulTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanModify->VqeConfig.ulTailDisplacement; + + /* Tail length cannot be modifed. */ + f_pChanOpen->VqeConfig.ulTailLength = f_pChanEntry->VqeConfig.usTailLength; + + + + if ( f_pChanModify->VqeConfig.fRinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanEntry->VqeConfig.fRinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanModify->VqeConfig.fRinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fRinLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanEntry->VqeConfig.fRinLevelControl; + else + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanModify->VqeConfig.fRinLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanEntry->VqeConfig.fRinAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanModify->VqeConfig.fRinAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinHighLevelCompensation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanEntry->VqeConfig.fRinHighLevelCompensation; + else + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanModify->VqeConfig.fRinHighLevelCompensation; + + + if ( f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + else + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb; + + + if ( f_pChanModify->VqeConfig.fSinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanEntry->VqeConfig.fSinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanModify->VqeConfig.fSinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutNoiseBleaching == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanEntry->VqeConfig.fSoutNoiseBleaching; + else + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanModify->VqeConfig.fSoutNoiseBleaching; + + + if ( f_pChanModify->VqeConfig.fSoutLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanEntry->VqeConfig.fSoutLevelControl; + else + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanModify->VqeConfig.fSoutLevelControl; + + + if ( f_pChanModify->VqeConfig.fSoutAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanModify->VqeConfig.fSoutAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.lRinLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanEntry->VqeConfig.chRinLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanModify->VqeConfig.lRinLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lSoutLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanEntry->VqeConfig.chSoutLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanModify->VqeConfig.lSoutLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanEntry->VqeConfig.chDefaultErlDb; + else + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanModify->VqeConfig.lDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.lAecDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanEntry->VqeConfig.chAecDefaultErlDb; + else + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanModify->VqeConfig.lAecDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.ulAecTailLength == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanEntry->VqeConfig.usAecTailLength; + else + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanModify->VqeConfig.ulAecTailLength; + + + if ( f_pChanModify->VqeConfig.fAcousticEcho == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanEntry->VqeConfig.fAcousticEcho; + else + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanModify->VqeConfig.fAcousticEcho; + + + if ( f_pChanModify->VqeConfig.fDtmfToneRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanEntry->VqeConfig.fDtmfToneRemoval; + else + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanModify->VqeConfig.fDtmfToneRemoval; + + + + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorA == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanEntry->VqeConfig.byNonLinearityBehaviorA; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanModify->VqeConfig.ulNonLinearityBehaviorA; + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorB == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanEntry->VqeConfig.byNonLinearityBehaviorB; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanModify->VqeConfig.ulNonLinearityBehaviorB; + + + if ( f_pChanModify->VqeConfig.ulDoubleTalkBehavior == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanEntry->VqeConfig.byDoubleTalkBehavior; + else + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanModify->VqeConfig.ulDoubleTalkBehavior; + + + if ( f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + else + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement; + + + if ( f_pChanModify->VqeConfig.fRoutNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanEntry->VqeConfig.fRoutNoiseReduction; + else + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanModify->VqeConfig.fRoutNoiseReduction; + + if ( f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + else + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb; + + + if ( f_pChanModify->VqeConfig.lAnrSnrEnhancementDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + else + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanModify->VqeConfig.lAnrSnrEnhancementDb; + + + if ( f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + else + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation; + + + if ( f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + else + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay; + + + if ( f_pChanModify->VqeConfig.fEnableMusicProtection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanEntry->VqeConfig.fEnableMusicProtection; + else + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanModify->VqeConfig.fEnableMusicProtection; + + + if ( f_pChanModify->VqeConfig.fIdleCodeDetection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanEntry->VqeConfig.fIdleCodeDetection; + else + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanModify->VqeConfig.fIdleCodeDetection; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Finaly the codec config.*/ + + if ( f_pChanModify->CodecConfig.ulDecoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanEntry->CodecConfig.byDecoderPort; + else + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanModify->CodecConfig.ulDecoderPort; + + + if ( f_pChanModify->CodecConfig.ulDecodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanEntry->CodecConfig.byDecodingRate; + else + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanModify->CodecConfig.ulDecodingRate; + + + if ( f_pChanModify->CodecConfig.ulEncoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanEntry->CodecConfig.byEncoderPort; + else + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanModify->CodecConfig.ulEncoderPort; + + + if ( f_pChanModify->CodecConfig.ulEncodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanEntry->CodecConfig.byEncodingRate; + else + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanModify->CodecConfig.ulEncodingRate; + + if ( f_pChanModify->CodecConfig.fEnableSilenceSuppression == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanEntry->CodecConfig.fEnableSilenceSuppression; + else + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanModify->CodecConfig.fEnableSilenceSuppression; + + if ( f_pChanModify->CodecConfig.ulPhasingType == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanEntry->CodecConfig.byPhasingType; + else + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanModify->CodecConfig.ulPhasingType; + + if ( f_pChanModify->CodecConfig.ulPhase == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhase = f_pChanEntry->CodecConfig.byPhase; + else + f_pChanOpen->CodecConfig.ulPhase = f_pChanModify->CodecConfig.ulPhase; + + if ( f_pChanModify->CodecConfig.ulPhasingTsstHndl == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanEntry->usPhasingTsstIndex ); + + /* Now recreate the Phasing TSST handle.*/ + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = f_pChanModify->CodecConfig.ulPhasingTsstHndl; + } + + f_pChanOpen->CodecConfig.ulAdpcmNibblePosition = f_pChanEntry->CodecConfig.byAdpcmNibblePosition; + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRetrieveNlpConfDword + +Description: This function is used by the API to store on a per channel basis + the various confguration DWORD from the device. The API performs + less read to the chip that way since it is always in synch with the + chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword Pointer to the content stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRetrieveNlpConfDword +UINT32 Oct6100ApiRetrieveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulConfigDword ) +{ + UINT32 ulResult; + UINT32 ulFirstEmptyIndex = 0xFFFFFFFF; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + if ( ( ulFirstEmptyIndex == 0xFFFFFFFF ) && ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == 0x0 ) ) + ulFirstEmptyIndex = i; + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + *f_pulConfigDword = f_pChanEntry->aulNlpConfDword[ i ][ 1 ]; + return cOCT6100_ERR_OK; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD && ulFirstEmptyIndex == 0xFFFFFFFF ) + return cOCT6100_ERR_FATAL_8E; + + /* We did not found any entry, let's create a new entry.*/ + f_pChanEntry->aulNlpConfDword[ ulFirstEmptyIndex ][ 0 ] = f_ulAddress; + + + /* Read the DWORD where the field is located.*/ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulAddress, + f_pulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSaveNlpConfDword + +Description: This function stores a configuration Dword within an API channel + structure and then writes it into the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword content to be stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSaveNlpConfDword +UINT32 Oct6100ApiSaveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + IN UINT32 f_ulConfigDword ) +{ + UINT32 ulResult; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + f_pChanEntry->aulNlpConfDword[ i ][ 1 ] = f_ulConfigDword; + break; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD ) + return cOCT6100_ERR_FATAL_8F; + + + /* Write the config DWORD.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + f_ulAddress, + f_ulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDirSer + +Description: Creates a bidirectional echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirSer +UINT32 Oct6100ChannelCreateBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + UINT16 usFirstChanIndex; + UINT16 usFirstChanExtraTsiIndex; + UINT16 usFirstChanSinCopyEventIndex; + UINT16 usFirstChanSoutCopyEventIndex; + UINT16 usSecondChanIndex; + UINT16 usSecondChanExtraTsiIndex; + UINT16 usSecondChanSinCopyEventIndex; + UINT16 usSecondChanSoutCopyEventIndex; + UINT16 usBiDirChanIndex; + UINT32 ulResult; + + + /* Check the user's configuration of the bidir channel for errors. */ + ulResult = Oct6100ApiCheckChannelCreateBiDirParams( f_pApiInstance, + f_pChannelCreateBiDir, + &usFirstChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usSecondChanIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the bidir channel. */ + ulResult = Oct6100ApiReserveChannelCreateBiDirResources(f_pApiInstance, + + &usBiDirChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usFirstChanSoutCopyEventIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex, + &usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelCreateBiDirStructs( f_pApiInstance, + + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateBiDirChannelEntry( f_pApiInstance, + f_pChannelCreateBiDir, + usBiDirChanIndex, + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelCreateBiDirParams + +Description: Checks the user's parameter passed to the create bidirectional channel + function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. +f_pusFirstChanIndex Pointer to the first channel index. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusSecondChanIndex Pointer to the second channel index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelCreateBiDirParams +UINT32 Oct6100ApiCheckChannelCreateBiDirParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + OUT PUINT16 f_pusFirstChanIndex, + OUT PUINT16 f_pusFirstChanExtraTsiIndex, + OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanIndex, + OUT PUINT16 f_pusSecondChanExtraTsiIndex, + OUT PUINT16 f_pusSecondChanSinCopyEventIndex + + ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + UINT32 ulEntryOpenCnt; + BOOL fCheckTssts = TRUE; + + /* Obtain shared resources pointer.*/ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* validate the bidirectional channel handle memory.*/ + if ( f_pChannelCreateBiDir->pulBiDirChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + + + /* Check if bi-dir channels are activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxBiDirChannels == 0 ) + return cOCT6100_ERR_CHANNEL_BIDIR_DISABLED; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + *f_pusFirstChanIndex = (UINT16)( f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusFirstChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, *f_pusFirstChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulFirstChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pFirstChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pFirstChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pFirstChanEntry->fRinRoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fSinSoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( pFirstChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE; + + if ( fCheckTssts == TRUE ) + { + if ( pFirstChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT; + if ( pFirstChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT; + } + + /* Return the desired info.*/ + *f_pusFirstChanExtraTsiIndex = pFirstChanEntry->usExtraSinTsiMemIndex; + *f_pusFirstChanSinCopyEventIndex = pFirstChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + *f_pusSecondChanIndex = (UINT16)( f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSecondChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, *f_pusSecondChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulSecondChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSecondChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSecondChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pSecondChanEntry->fRinRoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pSecondChanEntry->fSinSoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + { + + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + } + + if ( pSecondChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( fCheckTssts == TRUE ) + { + if ( pSecondChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT; + if ( pSecondChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT; + } + + if ( pSecondChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE; + + /* Return the desired info.*/ + *f_pusSecondChanExtraTsiIndex = pSecondChanEntry->usExtraSinTsiMemIndex; + *f_pusSecondChanSinCopyEventIndex = pSecondChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /* Check the law compatibility.*/ + if ( pFirstChanEntry->TdmConfig.bySoutPcmLaw != pSecondChanEntry->TdmConfig.byRinPcmLaw || + pFirstChanEntry->TdmConfig.byRinPcmLaw != pSecondChanEntry->TdmConfig.bySoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelCreateBiDirResources + +Description: Reserves all resources needed for the new bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBiDirChanIndex Pointer to the index of the bidirectionnal channel within the API instance. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_pusSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelCreateBiDirResources +UINT32 Oct6100ApiReserveChannelCreateBiDirResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + OUT PUINT16 f_pusBiDirChanIndex, + IN OUT PUINT16 f_pusFirstChanExtraTsiIndex, + IN OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusFirstChanSoutCopyEventIndex, + IN OUT PUINT16 f_pusSecondChanExtraTsiIndex, + IN OUT PUINT16 f_pusSecondChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + BOOL fBiDirChanIndex = FALSE; + BOOL fFirstExtraTsi = FALSE; + BOOL fSecondExtraTsi = FALSE; + BOOL fFirstSinCopyEvent = FALSE; + BOOL fSecondSinCopyEvent = FALSE; + BOOL fFirstSoutCopyEvent = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already by allocated. */ + + + { + if ( *f_pusFirstChanExtraTsiIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve the first Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusFirstChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstExtraTsi = TRUE; + } + + if ( *f_pusFirstChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstSinCopyEvent = TRUE; + } + } + + if ( *f_pusSecondChanExtraTsiIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the second Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusSecondChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondExtraTsi = TRUE; + } + + if ( *f_pusSecondChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the second channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondSinCopyEvent = TRUE; + } + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Now reserve all the resources specific to bidirectional channels */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReserveBiDirChanEntry( f_pApiInstance, + f_pusBiDirChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fBiDirChanIndex = TRUE; + + + { + + /* Reserve the first channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSoutCopyEventIndex ); + } + + if ( ulResult == cOCT6100_ERR_OK ) + { + fFirstSoutCopyEvent = TRUE; + + /* Reserve the second channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSoutCopyEventIndex ); + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if ( fBiDirChanIndex == TRUE ) + { + ulTempVar = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, + *f_pusBiDirChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusFirstChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusSecondChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusSecondChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( ( fFirstSoutCopyEvent == TRUE ) + + ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSoutCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelCreateBiDirStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usFirstChanIndex Pointer to the first channel index. +f_usFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_usFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_usFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_usFirstChanIndex Pointer to the second channel index. +f_usSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_usSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_usSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelCreateBiDirStructs +UINT32 Oct6100ApiWriteChannelCreateBiDirStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry.*/ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + + + + { + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary. */ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usFirstChanExtraTsiIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pFirstChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + f_usFirstChanExtraTsiIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + + + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary.*/ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usSecondChanExtraTsiIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSecondChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + f_usSecondChanExtraTsiIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Now, let's configure the two Sout copy events.*/ + + + /* First event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pFirstChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pSecondChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + /* Second event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pSecondChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pFirstChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clear + release the silence events if they were created. */ + + if ( pFirstChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pFirstChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pSecondChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + + ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pSecondChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBiDirChannelEntry + +Description: Updates the new bidir channel and the channel used to create that channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBiDirChannelEntry +UINT32 Oct6100ApiUpdateBiDirChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + IN UINT16 f_usBiDirChanIndex, + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + pFirstChanEntry->usExtraSinTsiMemIndex = f_usFirstChanExtraTsiIndex; + pFirstChanEntry->usSinCopyEventIndex = f_usFirstChanSinCopyEventIndex; + pFirstChanEntry->usSoutCopyEventIndex = f_usFirstChanSoutCopyEventIndex; + + pSecondChanEntry->usExtraSinTsiMemIndex = f_usSecondChanExtraTsiIndex; + pSecondChanEntry->usSinCopyEventIndex = f_usSecondChanSinCopyEventIndex; + pSecondChanEntry->usSoutCopyEventIndex = f_usSecondChanSoutCopyEventIndex; + + /* Save the channel info in the bidir channel.*/ + pBiDirChanEntry->usFirstChanIndex = f_usFirstChanIndex; + pBiDirChanEntry->usSecondChanIndex = f_usSecondChanIndex; + + + + /* Increment the extra TSI memory dependency count.*/ + + pFirstChanEntry->usExtraSinTsiDependencyCnt++; + pSecondChanEntry->usExtraSinTsiDependencyCnt++; + + /* Set the bidir flag in the channel structure.*/ + pFirstChanEntry->fBiDirChannel = TRUE; + pSecondChanEntry->fBiDirChannel = TRUE; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelCreateBiDir->pulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBiDirChanIndex; + + /* Finally, mark the channel as open. */ + pBiDirChanEntry->fReserved = TRUE; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDirSer + +Description: Closes a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirSer +UINT32 Oct6100ChannelDestroyBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + UINT16 usBiDirChanIndex; + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertDestroyBiDirChanParams( f_pApiInstance, + f_pChannelDestroyBiDir, + &usBiDirChanIndex, + + &usFirstChanIndex, + &usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateBiDirChannelStructs( f_pApiInstance, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseBiDirChannelResources( f_pApiInstance, + usBiDirChanIndex, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertDestroyBiDirChanParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectional channel structure. +f_pusBiDirChanIndex Pointer to the bidir channel entry within the API's list. +f_pusFirstChanIndex Pointer to the first channel index part of the bidir channel. +f_pusFirstChanIndex Pointer to the second channel index part of the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertDestroyBiDirChanParams +UINT32 Oct6100ApiAssertDestroyBiDirChanParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir, + IN OUT PUINT16 f_pusBiDirChanIndex, + + IN OUT PUINT16 f_pusFirstChanIndex, + IN OUT PUINT16 f_pusSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_BIDIR_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + *f_pusBiDirChanIndex = (UINT16)( f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBiDirChanIndex >= pSharedInfo->ChipConfig.usMaxBiDirChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the bidir channel's list entry. */ + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, *f_pusBiDirChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelDestroyBiDir->ulBiDirChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBiDirChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pBiDirChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the channel used to create this bidirectional channel.*/ + *f_pusFirstChanIndex = pBiDirChanEntry->usFirstChanIndex; + *f_pusSecondChanIndex = pBiDirChanEntry->usSecondChanIndex; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateBiDirChannelStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateBiDirChannelStructs +UINT32 Oct6100ApiInvalidateBiDirChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get pointers to the API entry of the two channel used to create the bidir channel.*/ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + pFirstChanEntry->usSinSoutTsiMemIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + } + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + pSecondChanEntry->usSinSoutTsiMemIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + + /* Now remove the sout copy of the first channel.*/ + + + { + /*=======================================================================*/ + /* Clear the Sout Copy event of the first channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + /* Now remove the sout copy of the second channel.*/ + + /*=======================================================================*/ + /* Clear the Sout Copy event of the second channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChannelResources + +Description: Release and clear the API entry associated to the bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBiDirChanIndex Index of the bidirectionnal channel in the API's bidir channel list. +f_usFirstChanIndex Index of the first channel used to create the bidir channel. +f_usSecondChanIndex Index of the second channel used to create the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChannelResources +UINT32 Oct6100ApiReleaseBiDirChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBiDirChanIndex, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Release the bidir entry.*/ + ulResult = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, f_usBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Release the Extra TSI memory and the SIN copy event if required.*/ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pFirstChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A3; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A4; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSinCopyEventIndex ); + + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + pFirstChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + } + } + + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pSecondChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A5; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A6; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSinCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + pSecondChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + } + + + { + /* Release the SOUT copy event of the first channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A7; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + /* Release the SOUT copy event of the second channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A8; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + + /*=======================================================================*/ + /* Update the first channel's list entry. */ + + /* Mark the channel as closed. */ + pFirstChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the second channel's list entry. */ + + /* Mark the channel as closed. */ + + pSecondChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the bidirectional channel's list entry. */ + + /* Mark the channel as closed. */ + pBiDirChanEntry->fReserved = FALSE; + pBiDirChanEntry->byEntryOpenCnt++; + + pBiDirChanEntry->usFirstChanIndex = cOCT6100_INVALID_INDEX; + pBiDirChanEntry->usSecondChanIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if some of the ports must be muted back. */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usFirstChanIndex, + pFirstChanEntry->usRinTsstIndex, + pFirstChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usSecondChanIndex, + pSecondChanEntry->usRinTsstIndex, + pSecondChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyByte +INT32 Oct6100ApiOctFloatToDbEnergyByte(UINT8 x) +{ + INT32 lResult; + + lResult = Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)(x << 8) ); + return lResult; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyHalf +INT32 Oct6100ApiOctFloatToDbEnergyHalf(UINT16 x) +{ + INT32 y; + UINT16 m; + + y = (((x >> 8) & 0x7F) - 0x41) * 3; + + m = (UINT16)((x & 0x00E0) >> 5); + if (m < 2) y += 0; + else if (m < 5) y += 1; + else y += 2; + + return y; +} +#endif + +#if !SKIP_Oct6100ApiDbAmpHalfToOctFloat +UINT16 Oct6100ApiDbAmpHalfToOctFloat(INT32 x) +{ + INT32 db_div6; + INT32 db_mod6; + UINT16 rval; + INT32 x_unsigned; + + if(x < 0) + { + x_unsigned = -x; + } + else + { + x_unsigned = x; + } + + db_div6 = x_unsigned / 6; + db_mod6 = x_unsigned % 6; + + if(x < 0) + { + if(db_mod6 == 0) + { + /* Change nothing! */ + db_div6 = -db_div6; + } + else + { + /* When we are negative, round down, and then adjust modulo. For example, if + x is -1, then db_div6 is 0 and db_mod6 is 1. We adjust so db_div6 = -1 and + db_mod6 = 5, which gives the correct adjustment. */ + db_div6 = -db_div6-1; + db_mod6 = 6 - db_mod6; + } + } + + rval = (UINT16)(0x4100 + db_div6 * 0x100); + + if(db_mod6 == 0) + { + rval += 0x0000; + } + else if(db_mod6 == 1) + { + rval += 0x0020; + } + else if(db_mod6 == 2) + { + rval += 0x0040; + } + else if(db_mod6 == 3) + { + rval += 0x0070; + } + else if(db_mod6 == 4) + { + rval += 0x0090; + } + else /* if(db_mod6 == 5) */ + { + rval += 0x00D0; + } + + return rval; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDebugChanMemory + +Description: This function configure a debug channel echo memory entry + in internal memory.and external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM configuration structure. +f_pVqeConfig Pointer to a VQE configuration structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory. +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDebugChanMemory +UINT32 Oct6100ApiWriteDebugChanMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) +{ + UINT32 ulResult; + + /*==============================================================================*/ + /* Write the VQE configuration of the debug channel. */ + + ulResult = Oct6100ApiWriteVqeMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + + /* Write the echo memory configuration of the debug channel. */ + ulResult = Oct6100ApiWriteEchoMemory( + f_pApiInstance, + f_pTdmConfig, + f_pChannelOpen, + f_usEchoMemIndex, + f_usRinRoutTsiIndex, + f_usSinSoutTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDebugChannelOpen + +Description: Internal function used to open a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDebugChannelOpen +UINT32 Oct6100ApiDebugChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_CHANNEL_OPEN TempChanOpen; + + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usDummyEchoIndex; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Let's program the channel memory.*/ + Oct6100ChannelOpenDef( &TempChanOpen ); + + TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel in reset.*/ + TempChanOpen.VqeConfig.fEnableNlp = FALSE; + TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.lDefaultErlDb = 0; + + /* Loop to reserve the proper entry for the debug channel */ + for( usChanIndex = 0; usChanIndex < ( pSharedInfo->DebugInfo.usRecordChanIndex + 1 ); usChanIndex ++ ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, &usDummyEchoIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Loop to free all entries except the one for the debug channel */ + for( usChanIndex = pSharedInfo->DebugInfo.usRecordChanIndex; usChanIndex > 0; ) + { + usChanIndex--; + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, usChanIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + &TempChanOpen.TdmConfig, + &TempChanOpen.VqeConfig, + &TempChanOpen, + pSharedInfo->DebugInfo.usRecordChanIndex, + pSharedInfo->DebugInfo.usRecordMemIndex, + pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex, + pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPort + +Description: This function will verify if a input TSST is bound to the RIN and + SIN port. If not, the port will be muted. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMutePorts +UINT32 Oct6100ApiMutePorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinTsstIndex, + IN UINT16 f_usSinTsstIndex, + IN BOOL f_fCheckBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usEchoIndex ); + + /* Mute the Rin port. */ + if ( ( f_fCheckBridgeIndex == FALSE ) + || ( ( f_fCheckBridgeIndex == TRUE ) && ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) ) ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( ( f_usRinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the silence channel + into the RIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usRinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Mute the Sin port. */ + if ( ( ( f_usSinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the SIN signal of the silence channel + into the SIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Unmute the Rin port if it was muted. */ + if ( ( ( f_usRinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E1; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( ( ( f_usSinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E2; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelLevelControl + +Description: This function will configure the level control on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearAlcHlcStatusBit If this is set, the ALC-HLC status bit must be + incremented. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelLevelControl +UINT32 Oct6100ApiSetChannelLevelControl( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearAlcHlcStatusBit ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 i; + UINT16 usTempData; + UINT8 byLastStatus; + BOOL fDisableAlcFirst; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Before doing anything, check if the configuration has changed. */ + if ( ( f_fClearAlcHlcStatusBit == TRUE ) + || ( f_pVqeConfig->fRinLevelControl != pChanEntry->VqeConfig.fRinLevelControl ) + || ( f_pVqeConfig->lRinLevelControlGainDb != pChanEntry->VqeConfig.chRinLevelControlGainDb ) + || ( f_pVqeConfig->fRinAutomaticLevelControl != pChanEntry->VqeConfig.fRinAutomaticLevelControl ) + || ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fRinHighLevelCompensation != pChanEntry->VqeConfig.fRinHighLevelCompensation ) + || ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb != pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb ) + || ( f_pVqeConfig->fSoutLevelControl != pChanEntry->VqeConfig.fSoutLevelControl ) + || ( f_pVqeConfig->lSoutLevelControlGainDb != pChanEntry->VqeConfig.chSoutLevelControlGainDb ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl != pChanEntry->VqeConfig.fSoutAutomaticLevelControl ) + || ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) + { + /* Calculate base address for manual level control configuration. */ + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set the Level control on RIN port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fRinLevelControl == TRUE ) + || ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lRinLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else /* ( ( f_pVqeConfig->fRinLevelControl == FALSE ) && ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) && ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) ) */ + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Level control on SOUT port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fSoutLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lSoutLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Check which one is to be disabled first. */ + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + fDisableAlcFirst = FALSE; + else + fDisableAlcFirst = TRUE; + + for ( i = 0; i < 2; i ++ ) + { + /* Set the auto level control target Db for the Rin port. */ + if ( ( ( i == 0 ) && ( fDisableAlcFirst == TRUE ) ) || ( ( i == 1 ) && ( fDisableAlcFirst == FALSE ) ) ) + { + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* Set the high level compensation threshold Db for the Rin port. */ + if ( pSharedInfo->ImageInfo.fRinHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinHighLevelCompensationThresholdDb ); + + /* Set high level compensation threshold on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) */ + { + /* Disable high level compensation. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Set the auto level control target Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lSoutAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Sout port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fSoutAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the high level compensation threshold Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fSoutHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Disable high level compensation on Sout for now. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if have to clear the ALC-HLC status. */ + if ( ( pSharedInfo->ImageInfo.fAlcHlcStatus == TRUE ) + && ( ( f_fClearAlcHlcStatusBit == TRUE ) + + ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Retrieve last status. */ + byLastStatus = (UINT8)( ( ( ulTempData & ulMask ) >> ulFeatureBitOffset ) & 0xFF ); + + /* Increment to reset context. */ + byLastStatus ++; + + /* Just in case, not to overwrite some context in external memory. */ + byLastStatus &= ( 0x1 << ulFeatureFieldLength ) - 1; + + /* Clear last status. */ + ulTempData &= (~ulMask); + + /* Set new status. */ + ulTempData |= ( byLastStatus << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelTailConfiguration + +Description: This function will configure the tail displacement and length + on a given channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fModifyOnly Function called from a modify or open? + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelTailConfiguration +UINT32 Oct6100ApiSetChannelTailConfiguration( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfBaseAddress; + UINT32 ulAfConfBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 ulTailSum; + BOOL fTailDisplacementModified = FALSE; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Calculate base addresses of NLP + AF configuration structure for the specified channel. */ + ulNlpConfBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + ulAfConfBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set the tail displacement.*/ + if ( pSharedInfo->ImageInfo.fTailDisplacement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fEnableTailDisplacement != pChanEntry->VqeConfig.fEnableTailDisplacement ) + || ( f_pVqeConfig->ulTailDisplacement != pChanEntry->VqeConfig.usTailDisplacement ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + /* Remember that the tail displacement parameters were changed. */ + fTailDisplacementModified = TRUE; + + /* Check if we must set the tail displacement value. */ + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( pSharedInfo->ImageInfo.fPerChannelTailDisplacement == TRUE ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( f_pVqeConfig->ulTailDisplacement != 0x0 ) ) + { + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + } + else /* if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) */ + { + /* If AEC is not activated, this must be set to the requested tail displacement. */ + if ( f_pVqeConfig->fAcousticEcho == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + if ( ulTailSum == 0 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 384 ) + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 896 ) */ + { + ulTempData |= ( ( 7 ) << ulFeatureBitOffset ); + } + } + else /* if ( f_pVqeConfig->fAcousticEcho == FALSE ) */ + { + /* Otherwise, the tail displacement is configured differently. This field stays to 0. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + } + } + + /* Then save the new DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) + { + /* Set the tail displacement offset in the AF. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.TailDisplEnableOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fEnableTailDisplacement ) << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail length. */ + if ( pSharedInfo->ImageInfo.fPerChannelTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulTailLength != pChanEntry->VqeConfig.usTailLength ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + /* Check if must automatically select maximum or if must use user specific value. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ImageInfo.usMaxTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure AEC tail length. */ + if ( pSharedInfo->ImageInfo.fAecTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( fTailDisplacementModified == TRUE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulAecTailLength != pChanEntry->VqeConfig.usAecTailLength ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set acoustic echo tail length. */ + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + switch( f_pVqeConfig->ulAecTailLength ) + { + case 1024: + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + break; + case 512: + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + break; + case 256: + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + break; + case 128: + default: + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + break; + } + } + else if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + /* No acoustic echo case. */ + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* Round this value up. */ + if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 256 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 512 ) + { + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 1024 ) */ + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + } + else + { + /* Keep this to zero. */ + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMuteSer + +Description: This function will mute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteSer +UINT32 Oct6100ChannelMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelMuteParams( f_pApiInstance, + f_pChannelMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelMuteParams + +Description: Check the user parameters passed to the channel mute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelMuteParams +UINT32 Oct6100ApiAssertChannelMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Sin + Sin with features cannot be muted simultaneously. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN; + + /* Check if Sin mute with features is supported by the firmware. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( pSharedInfo->ImageInfo.fSinMute == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMuteSer + +Description: This function will unmute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to unmute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteSer +UINT32 Oct6100ChannelUnMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelUnMuteParams( f_pApiInstance, + f_pChannelUnMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelUnMuteParams + +Description: Check the user parameters passed to the channel unmute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to Unmute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelUnMuteParams +UINT32 Oct6100ApiAssertChannelUnMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelUnMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelUnMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelUnMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteSinWithFeatures + +Description: Mute or Unmute the sin with features port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_fEnableSinWithFeatures Whether to enable the feature or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteSinWithFeatures +UINT32 Oct6100ApiMuteSinWithFeatures( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN BOOL f_fEnableSinWithFeatures ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + if ( pSharedInfo->ImageInfo.fSinMute == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinMuteOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinMuteOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinMuteOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear the mute flag. */ + ulTempData &= (~ulMask); + + /* Set the mute flag on the Sin port.*/ + if ( f_fEnableSinWithFeatures == TRUE ) + ulTempData |= ( 0x1 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPorts + +Description: Mute or Unmute the specified ports, according to the mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_usPortMask Port mask on which to apply the muting/unmuting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteChannelPorts +UINT32 Oct6100ApiMuteChannelPorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usPortMask, + IN BOOL f_fMute ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + BOOL fDisableSinWithFeatures = FALSE; + BOOL fEnableSinWithFeatures = FALSE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Rin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + return ulResult; + } + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Rout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + + /* Sin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + return ulResult; + } + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Sout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + + /* Sin with features port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + fEnableSinWithFeatures = TRUE; + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + + fDisableSinWithFeatures = TRUE; + } + + /* Check if must enable or disable SIN mute with features. */ + if ( fDisableSinWithFeatures == TRUE || fEnableSinWithFeatures == TRUE ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, fEnableSinWithFeatures ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c new file mode 100644 index 0000000..0303688 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c @@ -0,0 +1,6899 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to power-up the chip according to the + user's configuration. Also, the API instance is initialized to reflect the + desired configuration. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 347 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#if defined(__FreeBSD__) +#include +#include +#else +#ifndef __KERNEL__ +#include +#define kmalloc(size, type) malloc(size) +#define kfree(ptr) free(ptr) +#define GFP_ATOMIC 0 /*Dummy */ +#else +#include +#include +#endif +#endif + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_chip_stats_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_interrupts_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "octrpc/rpc_protocol.h" +#include "oct6100_remote_debug_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_playout_buf_priv.h" + +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tlv_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetInstanceSizeDef + +Description: Retrieves the size of the required API instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetSize Structure containing API instance size. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetInstanceSizeDef +UINT32 Oct6100GetInstanceSizeDef( + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100GetInstanceSize +UINT32 Oct6100GetInstanceSize( + tPOCT6100_CHIP_OPEN f_pChipOpen, + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + tOCT6100_API_INSTANCE_SIZES InstanceSizes; + UINT32 ulResult; + + /* Check user configuration for errors and conflicts. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate the instance size required for user's configuration. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Return required size to user. */ + f_pGetSize->ulApiInstanceSize = InstanceSizes.ulApiInstTotal; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpenDef + +Description: Inserts default chip configuration parameters into the + structure pointed to by f_pChipOpen. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpenDef +UINT32 Oct6100ChipOpenDef( + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 i; + + f_pChipOpen->ulUserChipId = 0; + f_pChipOpen->fMultiProcessSystem = FALSE; + f_pChipOpen->pProcessContext = NULL; + + f_pChipOpen->ulMaxRwAccesses = 8; + + f_pChipOpen->pbyImageFile = NULL; + f_pChipOpen->ulImageSize = 0; + + f_pChipOpen->ulMemClkFreq = 133000000; /* 133 Mhz */ + f_pChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; /* 33.33 Mhz */ + f_pChipOpen->fEnableMemClkOut = TRUE; + + f_pChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pChipOpen->ulNumMemoryChips = 1; + f_pChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_64MB; + + /* Set the tail displacement to zero. */ + f_pChipOpen->ulTailDisplacement = 0; + + /* Disable acoustic echo by default. */ + f_pChipOpen->fEnableAcousticEcho = FALSE; + + /* Resource allocation parameters. */ + f_pChipOpen->ulMaxChannels = 256; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxFlexibleConfParticipants = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + f_pChipOpen->ulMaxTdmStreams = 32; + f_pChipOpen->fUseSynchTimestamp = FALSE; + for ( i = 0; i < 4; i++ ) + { + f_pChipOpen->aulTimestampTimeslots[ i ] = cOCT6100_INVALID_TIMESLOT; + f_pChipOpen->aulTimestampStreams[ i ] = cOCT6100_INVALID_STREAM; + } + f_pChipOpen->fEnableFastH100Mode = FALSE; + + /* Configure the soft tone event buffer. */ + f_pChipOpen->ulSoftToneEventsBufSize = 128; + f_pChipOpen->fEnableExtToneDetection = FALSE; + f_pChipOpen->fEnable2100StopEvent = FALSE; + + /* Configure the soft playout event buffer. */ + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + + /* Interrupt configuration. */ + f_pChipOpen->ulInterruptPolarity = cOCT6100_ACTIVE_LOW_POLARITY; + + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulErrorH100Timeout = 100; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout = 100; + f_pChipOpen->ulMaxRemoteDebugSessions = 0; + f_pChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_3_QUARTERS; + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + f_pChipOpen->aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_8MHZ; + + + + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->fEnableProductionBist = FALSE; + f_pChipOpen->ulProductionBistMode = cOCT6100_PRODUCTION_BIST_STANDARD; + f_pChipOpen->ulNumProductionBistLoops = 1; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpen + +Description: Configures the chip according to the user specified + configuration f_pChipOpen. This function will perform all I/O + accesses necessary and initialize the API instance to reflect + the configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpen +UINT32 Oct6100ChipOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tOCT6100_API_INSTANCE_SIZES *InstanceSizes; + UINT32 ulStructSize; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Check user chip configuration parameters for errors. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the host system is multi-process or not and adjust instance accordingly. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE ) + { + /* Set pointer to tOCT6100_SHARED_INFO structure within instance. */ + ulStructSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulStructSize, ulTempVar ) + + f_pApiInstance->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pApiInstance + ulStructSize); + + /* Save the process context specified by the user. */ + f_pApiInstance->pProcessContext = f_pChipOpen->pProcessContext; + + /* Create serialization object handles. */ + ulResult = Oct6100ApiCreateSerializeObjects( f_pApiInstance, f_pChipOpen->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Copy the configuration structure. */ + ulResult = Oct6100ApiCopyChipConfiguration( f_pApiInstance, f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Perform various calculations based on user chip configuration. */ + ulResult = Oct6100ApiInitializeMiscellaneousVariables( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + InstanceSizes = kmalloc(sizeof(tOCT6100_API_INSTANCE_SIZES), GFP_ATOMIC); + if (!InstanceSizes) + return cOCT6100_ERR_FATAL_0; + + /* Calculate the amount of memory needed for the API instance structure. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) { + kfree(InstanceSizes); + return ulResult; + } + + /* Allocate the memory for the API instance structure internal pointers. */ + ulResult = Oct6100ApiAllocateInstanceMemory( f_pApiInstance, InstanceSizes ); + kfree(InstanceSizes); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the allocated instance structure memory. */ + ulResult = Oct6100ApiInitializeInstanceMemory( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the tone information structure. */ + ulResult = Oct6100ApiInitToneInfo( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Decode the key and bist internal memories. */ + ulResult = Oct6100ApiDecodeKeyAndBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC1 PLL. */ + ulResult = Oct6100ApiBootFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the SDRAM. */ + ulResult = Oct6100ApiBootSdram( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Bist the external memory. */ + ulResult = Oct6100ApiExternalMemoryBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the external memory. */ + ulResult = Oct6100ApiExternalMemoryInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Load the image into the chip. */ + ulResult = Oct6100ApiLoadImage( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the clock distribution registers. */ + ulResult = Oct6100ApiEnableClocks( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the NLP processor. */ + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_OPEN_EGO_TIMEOUT ) + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Read all TLV fields present in external memory. */ + ulResult = Oct6100ApiProcessTlvRegion( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the H.100 interface. */ + ulResult = Oct6100ApiSetH100Register( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write miscellaneous registers. */ + ulResult = Oct6100ApiWriteMiscellaneousRegisters( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Proceed with the rest only if the production BIST has not been requested. */ + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Initialize the errors counters. */ + ulResult = Oct6100ApiChipStatsSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get revision number of chip. */ + ulResult = Oct6100ApiGetChipRevisionNum( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + + /* Initialize the channels. */ + ulResult = Oct6100ApiInitChannels( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitMixer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitRecordResources( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize free external memory for buffer playout. */ + ulResult = Oct6100ApiBufferPlayoutMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + /*Clear all interrupts that could have occured during startup*/ + ulResult = Oct6100ApiClearInterrupts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrHwInit( f_pApiInstance, &f_pChipOpen->InterruptConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipCloseDef + +Description: Puts the chip into soft reset. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipClose Pointer to a tOCT6100_CHIP_CLOSE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipCloseDef +UINT32 Oct6100ChipCloseDef( + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + f_pChipClose->ulDummyVariable = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChipClose +UINT32 Oct6100ChipClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100CreateLocalInstance + +Description: Creates a local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreateLocal Structure used to create process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100CreateLocalInstanceDef +UINT32 Oct6100CreateLocalInstanceDef( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + f_pCreateLocal->pApiInstShared = NULL; + f_pCreateLocal->pApiInstLocal = NULL; + f_pCreateLocal->pProcessContext = NULL; + f_pCreateLocal->ulUserChipId = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100CreateLocalInstance +UINT32 Oct6100CreateLocalInstance( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + tPOCT6100_INSTANCE_API pApiInstLocal; + UINT32 ulApiInstSize; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Check user's structure for errors. */ + if ( f_pCreateLocal->pApiInstShared == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_SHARED; + + if ( f_pCreateLocal->pApiInstLocal == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_LOCAL; + + /* Get local pointer to local instance. */ + pApiInstLocal = f_pCreateLocal->pApiInstLocal; + + /* Assign pointers to local structure. */ + ulApiInstSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstSize, ulTempVar ) + + pApiInstLocal->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pCreateLocal->pApiInstShared + ulApiInstSize); + pApiInstLocal->pProcessContext = f_pCreateLocal->pProcessContext; + + /* Create serialization object handles needed. */ + ulResult = Oct6100ApiCreateSerializeObjects( pApiInstLocal, f_pCreateLocal->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DestroyLocalInstance + +Description: Release local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pDestroyLocal Structure used to destroy the process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DestroyLocalInstanceDef +UINT32 Oct6100DestroyLocalInstanceDef( + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + f_pDestroyLocal->ulDummy = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DestroyLocalInstance +UINT32 Oct6100DestroyLocalInstance( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + UINT32 ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetHwRevision + +Description: Gets the hardware revision number of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pGetHwRev Pointer to user structure in which to return revision + number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetHwRevisionDef +UINT32 Oct6100GetHwRevisionDef( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + f_pGetHwRev->ulUserChipId = cOCT6100_INVALID_CHIP_ID; + f_pGetHwRev->pProcessContext = NULL; + f_pGetHwRev->ulRevisionNum = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100GetHwRevision +UINT32 Oct6100GetHwRevision( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Read the hardware revision register. */ + ReadParams.pProcessContext = f_pGetHwRev->pProcessContext; + + ReadParams.ulUserChipId = f_pGetHwRev->ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x17E; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pGetHwRev->ulRevisionNum = ( usReadData >> 8 ) & 0xFF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResources + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesDef +UINT32 Oct6100FreeResourcesDef( + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + f_pFreeResources->fFreeTsiConnections = FALSE; + f_pFreeResources->fFreeConferenceBridges = FALSE; + f_pFreeResources->fFreePlayoutBuffers = FALSE; + f_pFreeResources->fFreePhasingTssts = FALSE; + f_pFreeResources->fFreeAdpcmChannels = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100FreeResources +UINT32 Oct6100FreeResources( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100FreeResourcesSer( f_pApiInstance, f_pFreeResources ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBist + +Description: This function retrieves the current BIST status of the + firmware. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure where the bist information + will be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistDef +UINT32 Oct6100ProductionBistDef( + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ProductionBist +UINT32 Oct6100ProductionBist( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ProductionBistSer( f_pApiInstance, f_pProductionBist ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetVersion + +Description: Retrieves the API version. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pApiGetVersion Pointer to structure that will receive version information. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetVersionDef +UINT32 Oct6100ApiGetVersionDef( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + UINT32 i; + + /* Initialize the string. */ + for ( i = 0; i < cOCT6100_API_VERSION_STRING_LENGTH; i++ ) + f_pApiGetVersion->achApiVersion[ i ] = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetVersion +UINT32 Oct6100ApiGetVersion( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + /* Copy API version information to user. */ + Oct6100UserMemCopy( f_pApiGetVersion->achApiVersion, cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetCapacityPins + +Description: Retrieves the Capcity Pins value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pGetCapacityPins Pointer to the parameters structure needed + by GetCapacityPins(). + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetCapacityPinsDef +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + + f_pGetCapacityPins->pProcessContext = NULL; + f_pGetCapacityPins->ulUserChipId = 0; + f_pGetCapacityPins->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pGetCapacityPins->ulCapacityValue = cOCT6100_INVALID_VALUE; + f_pGetCapacityPins->fEnableMemClkOut = TRUE; + f_pGetCapacityPins->ulMemClkFreq = 133000000; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetCapacityPins +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ) +{ + + UINT32 ulResult; + + tOCT6100_INSTANCE_API ApiInstance; + + Oct6100UserMemSet(&ApiInstance,0,sizeof(tOCT6100_INSTANCE_API)); + + /*Check parameters*/ + if ( f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_125_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_117_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_108_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_100_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_92_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_83_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pGetCapacityPins->fEnableMemClkOut != TRUE && + f_pGetCapacityPins->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + if ( f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + + + ApiInstance.pProcessContext = f_pGetCapacityPins->pProcessContext; + + + + ulResult = Oct6100ApiReadCapacity(&ApiInstance, f_pGetCapacityPins); + + + + return ulResult; +} +#endif + +/*************************** PRIVATE FUNCTIONS *****************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadCapacity + +Description: Read the capacity pins using modified functions from the openchip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OCT6100ApiReadCapacity +UINT32 Oct6100ApiReadCapacity( IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + UINT32 ulResult; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + /*Read capacity Pins*/ + + + ReadParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*Check the Reset register*/ + ReadParams.ulReadAddress = 0x100; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ((usReadData & 0xFFFF) != 0x0000) + return cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBistReadCap( f_pApiInstance, f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || + (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + ReadParams.ulReadAddress = 0x168; + } + else + ReadParams.ulReadAddress = 0x166; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + switch (usReadData & 0xF) + { + case 0x9: + f_pGetCapacityPins->ulCapacityValue = 16; + break; + case 0x8: + f_pGetCapacityPins->ulCapacityValue = 32; + break; + case 0xE: + f_pGetCapacityPins->ulCapacityValue = 64; + break; + case 0x0: + f_pGetCapacityPins->ulCapacityValue = 128; + break; + case 0x2: + f_pGetCapacityPins->ulCapacityValue = 256; + break; + case 0x5: + f_pGetCapacityPins->ulCapacityValue = 512; + break; + case 0x6: + f_pGetCapacityPins->ulCapacityValue = 672; + break; + default: + f_pGetCapacityPins->ulCapacityValue = (usReadData & 0xF); + return cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChipConfiguration + +Description: Checks the user chip configuration structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChipConfiguration +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 ulTempVar; + UINT32 i; + + /*-----------------------------------------------------------------------------*/ + /* Check general parameters. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE && + f_pChipOpen->fMultiProcessSystem != FALSE ) + return cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM; + + if ( f_pChipOpen->ulMaxRwAccesses < 1 || + f_pChipOpen->ulMaxRwAccesses > 1024) + return cOCT6100_ERR_OPEN_MAX_RW_ACCESSES; + + /* Check the clocks. */ + if ( f_pChipOpen->ulUpclkFreq != cOCT6100_UPCLK_FREQ_33_33_MHZ ) + return cOCT6100_ERR_OPEN_UP_CLK_FREQ; + + if ( f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pChipOpen->fEnableMemClkOut != TRUE && + f_pChipOpen->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + /* Check the image file. */ + if ( f_pChipOpen->ulImageSize < cOCT6100_MIN_IMAGE_SIZE || + f_pChipOpen->ulImageSize > cOCT6100_MAX_IMAGE_SIZE ) + return cOCT6100_ERR_OPEN_IMAGE_SIZE; + + if ( f_pChipOpen->pbyImageFile == NULL ) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + ulTempVar = Oct6100ApiCheckImageFileHeader(f_pChipOpen); + if (ulTempVar != cOCT6100_ERR_OK) + return ulTempVar; + + /* Check the acoustic echo activation flag. */ + if ( f_pChipOpen->fEnableAcousticEcho != TRUE && + f_pChipOpen->fEnableAcousticEcho != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO; + + /* Check the tail displacement parameter. */ + if ( f_pChipOpen->ulTailDisplacement > cOCT6100_MAX_TAIL_DISPLACEMENT ) + return cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT; + + /*-----------------------------------------------------------------------------*/ + /* Check TDM bus configuration parameters. */ + for ( i = 0; i < 8; i++ ) + { + if ( f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_2MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_4MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_8MHZ) + return cOCT6100_ERR_OPEN_TDM_STREAM_FREQS; + } + + if ( f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_3_QUARTERS && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_RISING_EDGE && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + return cOCT6100_ERR_OPEN_TDM_SAMPLING; + + if ( f_pChipOpen->fEnableFastH100Mode != TRUE && + f_pChipOpen->fEnableFastH100Mode != FALSE ) + return cOCT6100_ERR_OPEN_FAST_H100_MODE; + + /*-----------------------------------------------------------------------------*/ + /* Check external memory configuration parameters. */ + if ( f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + if ( f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_16MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_32MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_64MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulMemoryChipSize == cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryType == cOCT6100_MEM_TYPE_DDR ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulNumMemoryChips < 1 || + f_pChipOpen->ulNumMemoryChips > cOCT6100_MAX_NUM_MEMORY_CHIP ) + return cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER; + + /* Check the total memory size. */ + ulTempVar = f_pChipOpen->ulMemoryChipSize * f_pChipOpen->ulNumMemoryChips; + if ( ulTempVar < cOCT6100_MEMORY_CHIP_SIZE_16MB || + ulTempVar > cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE; + + if ( f_pChipOpen->ulMaxTdmStreams != 4 && + f_pChipOpen->ulMaxTdmStreams != 8 && + f_pChipOpen->ulMaxTdmStreams != 16 && + f_pChipOpen->ulMaxTdmStreams != 32 ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->ulMaxTdmStreams > 8 && + f_pChipOpen->ulMemClkFreq == cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->fUseSynchTimestamp != TRUE && + f_pChipOpen->fUseSynchTimestamp != FALSE ) + return cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP; + + if ( f_pChipOpen->fUseSynchTimestamp == TRUE ) + { + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP; + } + + /*-----------------------------------------------------------------------------*/ + /* Check soft buffer for tone events size. */ + if (f_pChipOpen->ulSoftToneEventsBufSize < 64 || + f_pChipOpen->ulSoftToneEventsBufSize > cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT ) + return cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE; + + if ( f_pChipOpen->fEnableExtToneDetection != TRUE && + f_pChipOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION; + + if ( f_pChipOpen->fEnable2100StopEvent != TRUE && + f_pChipOpen->fEnable2100StopEvent != FALSE) + return cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT; + + /* Check soft buffer for playout events size. */ + if ( ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + && ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize < cOCT6100_MIN_BUFFER_PLAYOUT_EVENT || + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize > cOCT6100_MAX_BUFFER_PLAYOUT_EVENT ) ) + return cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE; + + /*-----------------------------------------------------------------------------*/ + /* Check interrupt configuration parameters. */ + if ( f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_LOW_POLARITY && + f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_HIGH_POLARITY ) + return cOCT6100_ERR_OPEN_INTERRUPT_POLARITY; + + if ( f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_H100_CONFIG; + + /* Check the timeout value. */ + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Timeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT; + + /*-----------------------------------------------------------------------------*/ + /* Check maximum resources. */ + + switch ( f_pChipOpen->ulMemClkFreq ) + { + case 133000000: + ulTempVar = 672; + break; + case 125000000: + ulTempVar = 624; + break; + case 117000000: + ulTempVar = 576; + break; + case 108000000: + ulTempVar = 528; + break; + case 100000000: + ulTempVar = 480; + break; + case 92000000: + ulTempVar = 432; + break; + case 83000000: + ulTempVar = 384; + break; + case 75000000: + ulTempVar = 336; + break; + default: + return cOCT6100_ERR_FATAL_DA; + } + + if ( f_pChipOpen->ulMaxChannels > ulTempVar ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + if ( f_pChipOpen->ulMaxTsiCncts > cOCT6100_MAX_TSI_CNCTS ) + return cOCT6100_ERR_OPEN_MAX_TSI_CNCTS; + + + if ( f_pChipOpen->ulMaxBiDirChannels > 255 ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxBiDirChannels > (f_pChipOpen->ulMaxChannels / 2) ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxConfBridges > cOCT6100_MAX_CONF_BRIDGE ) + return cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES; + + if ( f_pChipOpen->ulMaxFlexibleConfParticipants > cOCT6100_MAX_FLEX_CONF_PARTICIPANTS ) + return cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS; + + if ( f_pChipOpen->ulMaxPlayoutBuffers > cOCT6100_MAX_PLAYOUT_BUFFERS ) + return cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS; + + + + if ( f_pChipOpen->ulMaxPhasingTssts > cOCT6100_MAX_PHASING_TSST ) + return cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS; + + if ( f_pChipOpen->ulMaxAdpcmChannels > cOCT6100_MAX_ADPCM_CHANNELS ) + return cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS; + + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 256 ) + return cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS; + + + + + + /* Check the channel recording flag. */ + if ( f_pChipOpen->fEnableChannelRecording != TRUE && + f_pChipOpen->fEnableChannelRecording != FALSE ) + return cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING; + + /* Check the enable production BIST flag. */ + if ( ( f_pChipOpen->fEnableProductionBist != TRUE ) + && ( f_pChipOpen->fEnableProductionBist != FALSE ) ) + return cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST; + + /* Check number of loops for the production BIST. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + if ( f_pChipOpen->ulNumProductionBistLoops == 0 ) + return cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS; + + if ( (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_STANDARD) && + (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_SHORT) ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE; + } + + /* If the production BIST has been requested, make sure all */ + /* other resources are disabled. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + /* All must be disabled. */ + f_pChipOpen->ulMaxChannels = 0; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + + + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCopyChipConfiguration + +Description: Copies the chip configuration from the user supplied config + structure to the instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCopyChipConfiguration +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->ChipConfig.ulUserChipId = f_pChipOpen->ulUserChipId; + pSharedInfo->ChipConfig.fMultiProcessSystem = (UINT8)( f_pChipOpen->fMultiProcessSystem & 0xFF ); + + pSharedInfo->ChipConfig.usMaxRwAccesses = (UINT16)( f_pChipOpen->ulMaxRwAccesses & 0xFFFF ); + + pSharedInfo->ChipConfig.pbyImageFile = f_pChipOpen->pbyImageFile; + pSharedInfo->ChipConfig.ulImageSize = f_pChipOpen->ulImageSize; + + pSharedInfo->ChipConfig.ulMemClkFreq = f_pChipOpen->ulMemClkFreq; + pSharedInfo->ChipConfig.ulUpclkFreq = f_pChipOpen->ulUpclkFreq; + + pSharedInfo->ChipConfig.byMemoryType = (UINT8)( f_pChipOpen->ulMemoryType & 0xFF ); + pSharedInfo->ChipConfig.byNumMemoryChips = (UINT8)( f_pChipOpen->ulNumMemoryChips & 0xFF ); + pSharedInfo->ChipConfig.ulMemoryChipSize = f_pChipOpen->ulMemoryChipSize; + + pSharedInfo->ChipConfig.usTailDisplacement = (UINT16)( f_pChipOpen->ulTailDisplacement & 0xFFFF ); + pSharedInfo->ChipConfig.fEnableAcousticEcho = (UINT8)( f_pChipOpen->fEnableAcousticEcho & 0xFF ); + /* Resource allocation parameters. */ + if ( f_pChipOpen->fEnableChannelRecording == TRUE && f_pChipOpen->ulMaxChannels == 672 ) + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( ( f_pChipOpen->ulMaxChannels - 1 ) & 0xFFFF ); + else + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( f_pChipOpen->ulMaxChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxTsiCncts = (UINT16)( f_pChipOpen->ulMaxTsiCncts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxBiDirChannels = (UINT16)( f_pChipOpen->ulMaxBiDirChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxConfBridges = (UINT16)( f_pChipOpen->ulMaxConfBridges & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants = (UINT16)( f_pChipOpen->ulMaxFlexibleConfParticipants & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxPlayoutBuffers = (UINT16)( f_pChipOpen->ulMaxPlayoutBuffers & 0xFFFF ); + + pSharedInfo->ChipConfig.usMaxPhasingTssts = (UINT16)( f_pChipOpen->ulMaxPhasingTssts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxAdpcmChannels = (UINT16)( f_pChipOpen->ulMaxAdpcmChannels & 0xFFFF ); + pSharedInfo->ChipConfig.byMaxTdmStreams = (UINT8)( f_pChipOpen->ulMaxTdmStreams & 0xFF ); + pSharedInfo->ChipConfig.fUseSynchTimestamp = (UINT8)( f_pChipOpen->fUseSynchTimestamp & 0xFF ); + for ( i = 0; i < 4; i++ ) + { + pSharedInfo->ChipConfig.ausTimestampTimeslots[ i ] = (UINT16)( f_pChipOpen->aulTimestampTimeslots[ i ] & 0xFFFF ); + pSharedInfo->ChipConfig.ausTimestampStreams[ i ] = (UINT16)( f_pChipOpen->aulTimestampStreams[ i ] & 0xFFFF ); + } + pSharedInfo->ChipConfig.byInterruptPolarity = (UINT8)( f_pChipOpen->ulInterruptPolarity & 0xFF ); + + pSharedInfo->ChipConfig.byTdmSampling = (UINT8)( f_pChipOpen->ulTdmSampling & 0xFF ); + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + { + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_16MHZ; + else + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = f_pChipOpen->aulTdmStreamFreqs[ i ]; + } + + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + pSharedInfo->ChipConfig.fEnableMemClkOut = (UINT8)( f_pChipOpen->fEnableMemClkOut & 0xFF ); + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + pSharedInfo->ChipConfig.ulSoftToneEventsBufSize = f_pChipOpen->ulSoftToneEventsBufSize + 1; + pSharedInfo->ChipConfig.fEnableExtToneDetection = (UINT8)( f_pChipOpen->fEnableExtToneDetection & 0xFF ); + pSharedInfo->ChipConfig.fEnable2100StopEvent = (UINT8)( f_pChipOpen->fEnable2100StopEvent & 0xFF ); + + if ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = f_pChipOpen->ulSoftBufferPlayoutEventsBufSize + 1; + else + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = 0; + pSharedInfo->ChipConfig.usMaxRemoteDebugSessions = (UINT16)( f_pChipOpen->ulMaxRemoteDebugSessions & 0xFFFF ); + + pSharedInfo->ChipConfig.fEnableChannelRecording = (UINT8)( f_pChipOpen->fEnableChannelRecording & 0xFF ); + + + + pSharedInfo->ChipConfig.fEnableProductionBist = (UINT8)( f_pChipOpen->fEnableProductionBist & 0xFF ); + pSharedInfo->ChipConfig.ulProductionBistMode = f_pChipOpen->ulProductionBistMode; + pSharedInfo->ChipConfig.ulNumProductionBistLoops = f_pChipOpen->ulNumProductionBistLoops; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeMiscellaneousVariables + +Description: Function where all the various parameters from the API instance + are set to their defaults value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeMiscellaneousVariables +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Obtain pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Calculate the total memory available. */ + pSharedInfo->MiscVars.ulTotalMemSize = pSharedInfo->ChipConfig.ulMemoryChipSize * pSharedInfo->ChipConfig.byNumMemoryChips; + + /* Software buffers initialization. */ + + /* Tones */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferSize = pSharedInfo->ChipConfig.ulSoftToneEventsBufSize; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + + /* Playout */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize = pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + /* Set the number of conference bridges opened to zero. */ + pSharedInfo->MiscVars.usNumBridgesOpened = 0; + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + + /* Set the H.100 slave mode. */ + pSharedInfo->MiscVars.ulH100SlaveMode = cOCT6100_H100_TRACKA; + + /* Save the Mclk value.*/ + pSharedInfo->MiscVars.ulMclkFreq = pSharedInfo->ChipConfig.ulMemClkFreq; + + /* Init the NLP params. */ + pSharedInfo->MiscVars.usCodepoint = 0; + pSharedInfo->MiscVars.usCpuLsuWritePtr = 0; + + /* Pouch counter not present until TLVs are read. */ + pSharedInfo->DebugInfo.fPouchCounter = FALSE; + pSharedInfo->DebugInfo.fIsIsrCalledField = FALSE; + + /* Initialize the image info parameters */ + pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + pSharedInfo->ImageInfo.fComfortNoise = FALSE; + pSharedInfo->ImageInfo.fBufferPlayout = TRUE; + pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fNlpControl = FALSE; + pSharedInfo->ImageInfo.fRinAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fSoutAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fRinHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fSoutHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fAlcHlcStatus = FALSE; + pSharedInfo->ImageInfo.fRinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fSilenceSuppression = FALSE; + pSharedInfo->ImageInfo.fSinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fToneDisabler = FALSE; + pSharedInfo->ImageInfo.fAdpcm = FALSE; + pSharedInfo->ImageInfo.fTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fConferencing = FALSE; + pSharedInfo->ImageInfo.fConferencingNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fDominantSpeakerEnabled = FALSE; + pSharedInfo->ImageInfo.fAecEnabled = FALSE; + pSharedInfo->ImageInfo.fAcousticEcho = FALSE; + pSharedInfo->ImageInfo.fToneRemoval = FALSE; + + pSharedInfo->ImageInfo.fDefaultErl = FALSE; + pSharedInfo->ImageInfo.fMaxEchoPoint = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorA = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorB = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailLength = FALSE; + pSharedInfo->ImageInfo.fAfTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fMusicProtection = FALSE; + pSharedInfo->ImageInfo.fAftControl = FALSE; + pSharedInfo->ImageInfo.fSinVoiceDetectedStat = FALSE; + pSharedInfo->ImageInfo.fRinAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fSoutAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fListenerEnhancement = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReductionLevel = FALSE; + pSharedInfo->ImageInfo.fAnrSnrEnhancement = FALSE; + pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = FALSE; + pSharedInfo->ImageInfo.fRinMute = FALSE; + pSharedInfo->ImageInfo.fSinMute = FALSE; + pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = FALSE; + pSharedInfo->ImageInfo.fAecTailLength = FALSE; + pSharedInfo->ImageInfo.fMusicProtectionConfiguration= FALSE; + pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = FALSE; + pSharedInfo->ImageInfo.fRinEnergyStat = FALSE; + pSharedInfo->ImageInfo.fSoutEnergyStat = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = FALSE; + pSharedInfo->ImageInfo.fIdleCodeDetection = TRUE; + pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = FALSE; + pSharedInfo->ImageInfo.fSinLevel = TRUE; + + pSharedInfo->ImageInfo.usMaxNumberOfChannels = 0; + pSharedInfo->ImageInfo.ulToneProfileNumber = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.ulBuildId = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.byImageType = cOCT6100_IMAGE_TYPE_WIRELINE; + pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + pSharedInfo->ImageInfo.usMaxTailLength = cOCT6100_TAIL_LENGTH_128MS; + pSharedInfo->DebugInfo.ulDebugEventSize = 0x100; + pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = 32; + pSharedInfo->DebugInfo.ulMatrixBaseAddress = cOCT6100_MATRIX_DWORD_BASE; + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress= cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress = cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixWpBaseAddress = cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD; + pSharedInfo->DebugInfo.ulAfWritePtrByteOffset = 206; + pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize = 4096; + pSharedInfo->DebugInfo.ulAfEventCbByteSize = 0x100000; + + /* Set all tones to invalid. */ + pSharedInfo->ImageInfo.byNumToneDetectors = 0; + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + Oct6100UserMemSet( pSharedInfo->ImageInfo.aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + } + /* Initialize the channel recording info. */ + pSharedInfo->DebugInfo.usRecordChanIndex = pSharedInfo->ChipConfig.usMaxChannels; + pSharedInfo->DebugInfo.usRecordMemIndex = cOCT6100_INVALID_INDEX; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = cOCT6100_INVALID_INDEX; + /* Initialize the mixer information. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usRecordSinEventIndex = cOCT6100_INVALID_INDEX; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateInstanceSizes + +Description: Calculates the amount of memory needed for the instance + structure memory block based on the user's configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to user chip configuration structure. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCalculateInstanceSizes +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulApiInstProcessSpecific; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Start with all instance sizes set to 0. */ + Oct6100UserMemSet( f_pInstSizes, 0x00, sizeof( tOCT6100_API_INSTANCE_SIZES ) ); + + /* All memory sizes are rounded up to the next multiple of 64 bytes. */ + + /*-----------------------------------------------------------------------------*/ + /* Obtain size of static members of API instance. */ + f_pInstSizes->ulApiInstStatic = sizeof( tOCT6100_SHARED_INFO ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulApiInstStatic, ulTempVar ) + + /* Calculate memory needed by pointers internal to the API instance. */ + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the EC channels. */ + ulResult = Oct6100ApiGetChannelsEchoSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the TSI structures. */ + ulResult = Oct6100ApiGetTsiCnctSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the conference bridges. */ + ulResult = Oct6100ApiGetConfBridgeSwSizes( f_pChipOpen, f_pInstSizes ); + /* Calculate memory needed for list and allocation software serialization. */ + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the buffer playout structures. */ + ulResult = Oct6100ApiGetPlayoutBufferSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by soft Rx Event buffers. */ + ulResult = Oct6100ApiGetEventsSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for phasing tssts. */ + ulResult = Oct6100ApiGetPhasingTsstSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the ADPCM channels. */ + ulResult = Oct6100ApiGetAdpcmChanSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of TSSTs. */ + ulResult = Oct6100ApiGetTsstSwSizes( f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of the mixer. */ + ulResult = Oct6100ApiGetMixerSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Determine amount of memory needed for memory allocation softwares. These + pieces of software will be responsible for the allocation of the chip's + external memory and API memory. */ + ulResult = Oct6100ApiGetMemorySwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed for remote debugging sessions. */ + ulResult = Oct6100ApiGetRemoteDebugSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate total memory needed by pointers internal to API instance. The + total contains both the process specific portion of the instance + (tOCT6100_INSTANCE_API) and the shared portion (tOCT6100_SHARED_INFO). The + process specific portion will be used only in the case where the host system + is a single-process one. */ + + ulApiInstProcessSpecific = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstProcessSpecific, ulTempVar ) + f_pInstSizes->ulApiInstTotal = + f_pInstSizes->ulChannelList + + f_pInstSizes->ulChannelAlloc + + f_pInstSizes->ulTsiCnctList + + f_pInstSizes->ulTsiCnctAlloc + + f_pInstSizes->ulSoftToneEventsBuffer + + f_pInstSizes->ulSoftBufPlayoutEventsBuffer + + f_pInstSizes->ulBiDirChannelList + + f_pInstSizes->ulBiDirChannelAlloc + + f_pInstSizes->ulConfBridgeList + + f_pInstSizes->ulConfBridgeAlloc + + f_pInstSizes->ulFlexConfParticipantsList + + f_pInstSizes->ulFlexConfParticipantsAlloc + + f_pInstSizes->ulPlayoutBufList + + f_pInstSizes->ulPlayoutBufAlloc + + f_pInstSizes->ulPlayoutBufMemoryNodeList + + + f_pInstSizes->ulCopyEventList + + f_pInstSizes->ulCopyEventAlloc + + f_pInstSizes->ulMixerEventList + + f_pInstSizes->ulMixerEventAlloc + + f_pInstSizes->ulPhasingTsstList + + f_pInstSizes->ulPhasingTsstAlloc + + f_pInstSizes->ulAdpcmChannelList + + f_pInstSizes->ulAdpcmChannelAlloc + + f_pInstSizes->ulConversionMemoryAlloc + + f_pInstSizes->ulTsiMemoryAlloc + + f_pInstSizes->ulRemoteDebugList + + f_pInstSizes->ulRemoteDebugTree + + f_pInstSizes->ulRemoteDebugPktCache + + f_pInstSizes->ulRemoteDebugDataBuf + + f_pInstSizes->ulTsstEntryList + + f_pInstSizes->ulTsstEntryAlloc + + f_pInstSizes->ulTsstAlloc + + f_pInstSizes->ulApiInstStatic + + ulApiInstProcessSpecific; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAllocateInstanceMemory + +Description: Allocates the API instance memory to the various members of + the structure f_pApiInstance according to the sizes contained + in f_pInstSizes. No initialization of this memory is + performed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAllocateInstanceMemory +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulOffset; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get address of first UINT32 of memory in API instance structure following */ + /* the static members of the API instance structure. */ + ulOffset = f_pInstSizes->ulApiInstStatic; + + /*===================================================================*/ + /* Allocate memory for the echo channels.*/ + pSharedInfo->ulChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelList; + pSharedInfo->ulChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI connections */ + pSharedInfo->ulTsiCnctListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctList; + pSharedInfo->ulTsiCnctAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctAlloc; + pSharedInfo->ulMixerEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventList; + pSharedInfo->ulMixerEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventAlloc; + + pSharedInfo->ulBiDirChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelList; + pSharedInfo->ulBiDirChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelAlloc; + pSharedInfo->ulCopyEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventList; + pSharedInfo->ulCopyEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventAlloc; + + /*===================================================================*/ + /* Allocate memory for the conference bridges */ + pSharedInfo->ulConfBridgeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeList; + pSharedInfo->ulConfBridgeAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeAlloc; + + /*===================================================================*/ + /* Allocate memory for the flexible conferencing participants. */ + pSharedInfo->ulFlexConfParticipantListOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsList; + pSharedInfo->ulFlexConfParticipantAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsAlloc; + + /*===================================================================*/ + /* Allocate memory for the play-out buffers */ + pSharedInfo->ulPlayoutBufListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufList; + pSharedInfo->ulPlayoutBufAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufAlloc; + pSharedInfo->ulPlayoutBufMemoryNodeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufMemoryNodeList; + + + + /*===================================================================*/ + /* Allocate memory for the phasing TSSTs */ + pSharedInfo->ulPhasingTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstList; + pSharedInfo->ulPhasingTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstAlloc; + + /*===================================================================*/ + /* Allocate memory for the ADPCM channel */ + pSharedInfo->ulAdpcmChanAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelAlloc; + pSharedInfo->ulAdpcmChanListOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelList; + + /*===================================================================*/ + /* Allocate memory for the conversion memory */ + pSharedInfo->ulConversionMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConversionMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI chariot memory */ + pSharedInfo->ulTsiMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSST management */ + pSharedInfo->ulTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstAlloc; + pSharedInfo->ulTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryList; + pSharedInfo->ulTsstListAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryAlloc; + + /*===================================================================*/ + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftToneEventsBuffer; + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftBufPlayoutEventsBuffer; + /*===================================================================*/ + pSharedInfo->RemoteDebugInfo.ulSessionListOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugList; + + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugTree; + + pSharedInfo->RemoteDebugInfo.ulDataBufOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugDataBuf; + + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugPktCache; + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeInstanceMemory + +Description: Initializes the various members of the structure f_pApiInstance + to reflect the current state of the chip and its resources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeInstanceMemory +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize API EC channels. */ + ulResult = Oct6100ApiChannelsEchoSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API TSI connection structures. */ + ulResult = Oct6100ApiTsiCnctSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API conference bridges. */ + ulResult = Oct6100ApiConfBridgeSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API buffer playout structures. */ + ulResult = Oct6100ApiPlayoutBufferSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API phasing tssts. */ + ulResult = Oct6100ApiPhasingTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API ADPCM channels. */ + ulResult = Oct6100ApiAdpcmChanSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the external memory management structures. */ + ulResult = Oct6100ApiMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize TSST management stuctures. */ + ulResult = Oct6100ApiTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the mixer management stuctures. */ + ulResult = Oct6100ApiMixerSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the remote debugging session management variables. */ + ulResult = Oct6100ApiRemoteDebuggingSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChipRevisionNum + +Description: Reads the chip's revision number register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChipRevisionNum +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the chip revision number. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = cOCT6100_CHIP_ID_REVISION_REG; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save the info in the API miscellaneous structure. */ + pSharedInfo->MiscVars.usChipId = (UINT16)( usReadData & 0xFF ); + pSharedInfo->MiscVars.usChipRevision = (UINT16)( usReadData >> 8 ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckImageFileHeader + +Description: This function check if the image loaded is valid + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckImageFileHeader +UINT32 Oct6100ApiCheckImageFileHeader( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + + PUINT8 pszImageInfoStart = NULL; + UINT32 ulStrLen; + + ulStrLen = Oct6100ApiStrLen( (PUINT8)cOCT6100_IMAGE_START_STRING ); + pszImageInfoStart = (PUINT8) Oct6100ApiStrStr(f_pChipOpen->pbyImageFile,(PUINT8)cOCT6100_IMAGE_START_STRING, + f_pChipOpen->pbyImageFile + ulStrLen); + if (pszImageInfoStart == NULL) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDecodeKeyAndBist + +Description: This function decodes the key and runs the automatic BIST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDecodeKeyAndBist +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 ausBistData[ 3 ]; + UINT16 usReadData; + UINT32 ulResult; + BOOL fBitEqual; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the chip config structure */ + /* contained in the instance structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Set the process context and user chip ID parameters once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Write key in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + if (( i % 2 ) == 0) + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 2]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 3]) << 0; + } + else + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 0]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 1]) << 0; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write one in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + if (i == 0) + { + WriteParams.usWriteData = 0x0001; + } + else + { + WriteParams.usWriteData = 0x0000; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | ( i + 8 )); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear memory access registers: */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Run BISTs and key decode. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0081; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for the key decode PC to clear. */ + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x160, 0, 0, 100000, &fBitEqual ); + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_13; + + /* Read the key valid bit to make sure everything is ok. */ + ReadParams.ulReadAddress = 0x160; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Either the firmware image was not loaded correctly (from pointer given by user) */ + /* or the channel capacity pins of the chip do not match what the firmware is expecting. */ + if ( ( usReadData & 0x4 ) == 0 ) + return cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS; + + /* Read the result of the internal memory bist. */ + ReadParams.ulReadAddress = 0x110; + ReadParams.pusReadData = &ausBistData[ 0 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x114; + ReadParams.pusReadData = &ausBistData[ 1 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x118; + ReadParams.pusReadData = &ausBistData[ 2 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error was reported. */ + if (ausBistData[0] != 0x0000 || ausBistData[1] != 0x0000 || ausBistData[2] != 0x0000) + return cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST; + + /* Put key decoder in powerdown. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x008A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2PllReadCap + +Description: Configures the chip's FC2 PLL. Special version for GetcapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootFc2PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + + /* Setup delay chains. */ + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == f_pGetCapacityPins->fEnableMemClkOut ) + { + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_DDR || f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2Pll + +Description: Configures the chip's FC2 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc2Pll +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select register configuration based on the memory frequency. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.ulMemClkFreq ) + { + case 133000000: + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 672; + pSharedInfo->MiscVars.usMaxH100Speed = 124; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x050B; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0516; + + break; + case 125000000: + ulFc2PllDivisor = 0x0F50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 624; + pSharedInfo->MiscVars.usMaxH100Speed = 116; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04CA; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04D4; + + break; + case 117000000: + ulFc2PllDivisor = 0x0E50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 576; + pSharedInfo->MiscVars.usMaxH100Speed = 108; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0489; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0492; + + break; + case 108000000: + ulFc2PllDivisor = 0x0D50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 528; + pSharedInfo->MiscVars.usMaxH100Speed = 99; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0408; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0410; + + break; + case 100000000: + ulFc2PllDivisor = 0x0C50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 480; + pSharedInfo->MiscVars.usMaxH100Speed = 91; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03C8; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03D0; + + break; + case 92000000: + ulFc2PllDivisor = 0x0B50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 432; + pSharedInfo->MiscVars.usMaxH100Speed = 83; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0387; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x038E; + + break; + case 83000000: + ulFc2PllDivisor = 0x0A50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 384; + pSharedInfo->MiscVars.usMaxH100Speed = 74; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0346; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x034C; + + break; + case 75000000: + ulFc2PllDivisor = 0x0950; + ulMtDivisor = 0x4200; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 336; + pSharedInfo->MiscVars.usMaxH100Speed = 64; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0306; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x030C; + + break; + default: + return cOCT6100_ERR_FATAL_DB; + } + + /* Verify that the max channel is not too big based on the chip frequency. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->MiscVars.usMaxNumberOfChannels ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + /* Setup delay chains. */ + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == pChipConfig->fEnableMemClkOut ) + { + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_DDR || pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1PllReadCap + +Description: Configures the chip's FC1 PLL. Special version for getCapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProgramFc1PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( f_pGetCapacityPins->ulMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1Pll + +Description: Configures the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramFc1Pll +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( pChipConfig->byMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc1Pll + +Description: Boot the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc1Pll +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Force bist_clk also (it too is used on resetable flops). */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0188; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Force all cpu clocks on chariot controllers. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0202; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 1000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the reset on the entire chip and disable CPU access caching. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x2003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the bist_clk. It is no longer needed.*/ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0088; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable all clks to prepare for bist clock switchover. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0101; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Deassert bist_active */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Change CPU interface to normal mode (from boot mode). */ + WriteParams.ulWriteAddress = 0x154; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give a couple of BIST clock cycles to turn off the BIST permanently. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0108; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Turn BIST clock off for the last time. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset procedure done! */ + + /* Enable mclk for cpu interface and external memory controller. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiLoadImage + +Description: This function writes the firmware image in the external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiLoadImage +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempPtr; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + unsigned char const *pbyImageFile; + UINT32 ulByteCount = 0; + UINT16 usReadData; + UINT32 ulAddressOfst; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Breakdown image into subcomponents. */ + ulTempPtr = cOCT6100_IMAGE_FILE_BASE + cOCT6100_IMAGE_AF_CST_OFFSET; + + for(i=0;iImageRegion[ i ].ulPart1Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 0 ]; + pSharedInfo->ImageRegion[ i ].ulPart2Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 1 ]; + pSharedInfo->ImageRegion[ i ].ulClockInfo = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 2 ]; + pSharedInfo->ImageRegion[ i ].ulReserved = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 3 ]; + + if (i == 0) /* AF constant. */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 612 ); + } + else if (i == 1) /* NLP image */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2056 ); + } + else /* Others */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2064 ); + + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart2Size * 2448 ); + } + } + + /* Write the image in external memory. */ + ulNumWrites = pSharedInfo->ChipConfig.ulImageSize / 2; + + BurstParams.ulWriteAddress = cOCT6100_IMAGE_FILE_BASE; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyImageFile = pSharedInfo->ChipConfig.pbyImageFile; + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyImageFile [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyImageFile [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + } + + /* Perform a serie of reads to make sure the image was correclty written into memory. */ + ulAddressOfst = ( pSharedInfo->ChipConfig.ulImageSize / 2 ) & 0xFFFFFFFE; + while ( ulAddressOfst != 0 ) + { + ReadParams.ulReadAddress = cOCT6100_IMAGE_FILE_BASE + ulAddressOfst; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData >> 8) != pbyImageFile[ ulAddressOfst ] ) + return cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED; + + ulAddressOfst = (ulAddressOfst / 2) & 0xFFFFFFFE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBistReadCap + +Description: Tests the operation of the CPU registers. Special Version for + GetCapacityPins + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCpuRegisterBistReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins + ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBist + +Description: Tests the operation of the CPU registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCpuRegisterBist +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootSdram + +Description: Configure and test the SDRAM. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootSdram +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT16 usWriteData23E; + UINT16 usWriteData230; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + usWriteData23E = 0x0000; + usWriteData230 = 0x0000; + + if ( (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_16; + } + + usWriteData230 |= 0x0002; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program the mode register. */ + usWriteData23E = 0x0030; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* DDR: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_17; + } + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program DDR mode register. */ + usWriteData23E = 0x4000; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0161; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Precharge all banks. */ + usWriteData23E = 0xFFFF; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0061; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the refresh frequency. */ + WriteParams.ulWriteAddress = 0x242; + WriteParams.usWriteData = 0x0400; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x244; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x248; + WriteParams.usWriteData = 0x800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0012; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the SDRAM and refreshes. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0001; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0013; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiEnableClocks + +Description: This function will disable clock masking for all the modules + of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiEnableClocks +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Enable tdmie / adpcm mclk clocks. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the DQS register for the DDR memory */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xFF00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable pgsp chariot clocks */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable af/mt chariot clocks */ + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramNLP + +Description: This function will write image values to configure the NLP. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramNLP +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usReadHighData; + BOOL fBitEqual; + UINT32 ulEgoEntry[4]; + UINT32 ulTempAddress; + UINT32 ulAfCpuUp = FALSE; + UINT32 i; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Initialize the process context and user chip ID once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulReadData; + UINT32 ulBitPattern; + UINT32 j, k; + + /* Since the pouch section (256 bytes) will not be tested by the firmware, */ + /* the API has to make sure this section is working correctly. */ + for ( k = 0; k < 2; k ++ ) + { + if ( k == 0 ) + ulBitPattern = 0x1; + else + ulBitPattern = 0xFFFFFFFE; + + for ( j = 0; j < 32; j ++ ) + { + /* Write the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, ulBitPattern << j ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Read the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, &ulReadData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the value matches. */ + if ( ( ulBitPattern << j ) != ulReadData ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR; + } + } + } + } + + /* Write the image info in the chip. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE; + WriteParams.usWriteData = (UINT16)( ( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( i = 0; i < 8; i++ ) + { + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ); + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 4; + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 8; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulClockInfo << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulReserved; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Put NLP in config mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x160E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Upload the up to 8 NLP pages + 1 AF page (for timing reasons). */ + for ( i = 0; i < pSharedInfo->ImageRegion[ 1 ].ulPart1Size; i++ ) + { + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * ( i * 2 ), 0x1280, 1024, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * (( i * 2 ) + 1 ), 0x1680, 1024, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Shift mt chariot memories. This process will complete by the time */ + /* the next LSU transfer is done. */ + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010B; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x692, 0, 0, 100000, &fBitEqual ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_1A; + } + + /* 1 AF page (for timing reasons). */ + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 0), 0x1280, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 1), 0x1480, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 2), 0x1680, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 3), 0x1880, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write constant memory init context position in channel "672" for pgsp. */ + WriteParams.ulWriteAddress = 0x71A; + WriteParams.usWriteData = 0x8000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_in base address to 800 on a 2k boundary */ + WriteParams.ulWriteAddress = 0x716; + WriteParams.usWriteData = 0x800 >> 11; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_out to 0x2C0000h on a 16k boundary */ + WriteParams.ulWriteAddress = 0x71C; + WriteParams.usWriteData = 0x2C0000 >> 14; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give chariot control of the chip. */ + WriteParams.ulWriteAddress = 0x712; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xC; + ulTempAddress = 0x300000 + 0x0800; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 16 ) & 0x07FF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xE; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 0 ) & 0xFF00 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the init PGSP event in place. */ + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x800; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x802; + WriteParams.usWriteData = 0x02A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Also write the register 710, which tells PGSP how many tones are supported. */ + WriteParams.ulWriteAddress = 0x710; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FA ] << 8; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FB ] << 0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start both processors in the NLP. */ + WriteParams.ulWriteAddress = 0x373FE; + WriteParams.usWriteData = 0x00FF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37BFE; + WriteParams.usWriteData = 0x00FE; /* Tell processor 1 to just go to sleep. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FC6; + WriteParams.usWriteData = 0x8004; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD2; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start processor in the AF. */ + for ( i = 0; i < 16; i ++ ) + { + WriteParams.ulWriteAddress = cOCT6100_POUCH_BASE + ( i * 2 ); + if ( i == 9 ) + { + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + if (pSharedInfo->ChipConfig.ulProductionBistMode == cOCT6100_PRODUCTION_BIST_SHORT) + WriteParams.usWriteData = cOCT6100_PRODUCTION_SHORT_BOOT_TYPE; + else + WriteParams.usWriteData = cOCT6100_PRODUCTION_BOOT_TYPE; + } + else + { + WriteParams.usWriteData = cOCT6100_AF_BOOT_TYPE; + } + } + else + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if the production BIST mode was requested. */ + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulTotalElements = 3; + UINT32 ulCrcKey; + UINT32 aulMessage[ 4 ]; + UINT32 ulWriteAddress = 0x20 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + /* Magic key. */ + aulMessage[ 0 ] = 0xCAFECAFE; + /* Memory size. */ + aulMessage[ 1 ] = pSharedInfo->MiscVars.ulTotalMemSize; + /* Loop count. */ + aulMessage[ 2 ] = pSharedInfo->ChipConfig.ulNumProductionBistLoops; + /* CRC initialized. */ + aulMessage[ 3 ] = 0; + + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCrcKey ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulMessage[ 3 ] = ulCrcKey; + + /* Write the message to the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulWriteAddress + i * 4, aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + WriteParams.ulWriteAddress = 0xFFFC6; + WriteParams.usWriteData = 0x1284; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0xFFFD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( ulAfCpuUp == FALSE ) + { + if ( ulAfCpuUp == FALSE ) + { + ReadParams.ulReadAddress = cOCT6100_POUCH_BASE; + ReadParams.pusReadData = &usReadHighData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress += 2; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + /* Should read 0x0007 when bisting. */ + if ( (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_BOOT_TYPE) || + (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_SHORT_BOOT_TYPE) ) + { + /* Verify if the bist has started successfully. */ + if ( ( usReadData & 0xFFFF ) == 0x0002 ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED; + else if ( ( usReadData & 0xFFFF ) != 0xEEEE ) + return cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED; + + ulAfCpuUp = TRUE; + } + } + else /* if ( pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) */ + { + if ( ( usReadHighData & 0xFFFF ) == cOCT6100_AF_BOOT_TYPE ) + { + /* Verify if the bist succeeded. */ + if ( ( usReadData & 0xFFFF ) != 0x0000 ) + return cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED; + + ulAfCpuUp = TRUE; + } + } + } + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT; + } + + /* Return NLP in operationnal mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x060E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetH100Register + +Description: This function will configure the H.100 registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetH100Register +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 i; + UINT32 ulOffset; + BOOL fAllStreamAt2Mhz = TRUE; + const UINT16 ausAdpcmResetContext[32] = { 0x1100, 0x0220, 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0100, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0040, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Set the Global OE bit. */ + WriteParams.ulWriteAddress = 0x300; + WriteParams.usWriteData = 0x0004; + + /* Set the number of streams. */ + switch( pChipConfig->byMaxTdmStreams ) + { + case 32: + WriteParams.usWriteData |= ( 0 << 3 ); + break; + case 16: + WriteParams.usWriteData |= ( 1 << 3 ); + break; + case 8: + WriteParams.usWriteData |= ( 2 << 3 ); + break; + case 4: + WriteParams.usWriteData |= ( 3 << 3 ); + break; + default: + break; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the stream frequency. */ + WriteParams.ulWriteAddress = 0x330; + WriteParams.usWriteData = 0x0000; + for ( i = 0; i < (UINT32)(pChipConfig->byMaxTdmStreams / 4); i++) + { + ulOffset = i*2; + switch( pChipConfig->aulTdmStreamFreqs[ i ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + WriteParams.usWriteData |= ( 0x0 << ulOffset ); + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + WriteParams.usWriteData |= ( 0x1 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + WriteParams.usWriteData |= ( 0x2 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + default: + break; + } + } + + /* Set the stream to 16 MHz if the fast H.100 mode is selected. */ + if ( pChipConfig->fEnableFastH100Mode == TRUE ) + { + fAllStreamAt2Mhz = FALSE; + WriteParams.usWriteData = 0xFFFF; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + /* Make the chip track both clock A and B to perform fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x322; + WriteParams.usWriteData = 0x0004; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x332; + WriteParams.usWriteData = 0x0003; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x376; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usTdmClkBoundary ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select delay for early clock (90 and 110). */ + WriteParams.ulWriteAddress = 0x378; + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData = 0x000A; + else + { + /* Set the TDM sampling. */ + if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_RISING_EDGE ) + { + WriteParams.usWriteData = 0x0AF0; + } + else if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + { + WriteParams.usWriteData = 0x0A0F; + } + else /* pSharedInfo->ChipConfig.ulTdmSampling == cOCT6100_TDM_SAMPLE_AT_3_QUARTERS */ + { + WriteParams.usWriteData = 0x0A08; + } + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Protect chip by preventing too rapid timeslot arrival (mclk == 133 MHz). */ + WriteParams.ulWriteAddress = 0x37A; + WriteParams.usWriteData = (UINT16)pSharedInfo->MiscVars.usMaxH100Speed; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Allow H.100 TS to progress. */ + WriteParams.ulWriteAddress = 0x382; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set by-pass mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* TDMIE bits. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write normal ADPCM reset values in ADPCM context 1344. */ + for(i=0;i<32;i++) + { + WriteParams.ulWriteAddress = 0x140000 + ( 0x40 * 1344 ) + ( i * 2 ); + WriteParams.usWriteData = ausAdpcmResetContext[i]; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Make sure delay flops are configured correctly if all streams are at 2 MHz. */ + if ( fAllStreamAt2Mhz == TRUE ) + { + /* Setup H.100 sampling to lowest value. */ + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = 0x4041; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x378; + WriteParams.usWriteData = 0x0A00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteMiscellaneousRegisters + +Description: This function will write to various registers to activate the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteMiscellaneousRegisters +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( f_pApiInstance->pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write MT chariot interval */ + WriteParams.ulWriteAddress = 0x2C2; + if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 640 ) + WriteParams.usWriteData = 0x05EA; + else if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 513 ) + WriteParams.usWriteData = 0x0672; + else /* if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels <= 513 ) */ + WriteParams.usWriteData = 0x0750; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write set second part5 time. */ + WriteParams.ulWriteAddress = 0x2C4; + WriteParams.usWriteData = 0x04A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write CPU bucket timer to guarantee 200 cycles between each CPU access. */ + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x236; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateSerializeObjects + +Description: Creates a handle to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulUserChipId User chip ID for this serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateSerializeObjects +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ) +{ + tOCT6100_CREATE_SERIALIZE_OBJECT CreateSerObj; + UINT32 ulResult; + CHAR szSerObjName[ 64 ] = "Oct6100ApiXXXXXXXXApiSerObj"; + + + /* Set some parameters of the create structure once and for all. */ + CreateSerObj.pProcessContext = f_pApiInstance->pProcessContext; + CreateSerObj.pszSerialObjName = szSerObjName; + + /*----------------------------------------------------------------------*/ + /* Set the chip ID in the semaphore name. */ + szSerObjName[ 10 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 28 ) & 0xFF ); + szSerObjName[ 11 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 24 ) & 0xFF ); + szSerObjName[ 12 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 20 ) & 0xFF ); + szSerObjName[ 13 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 16 ) & 0xFF ); + szSerObjName[ 14 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 12 ) & 0xFF ); + szSerObjName[ 15 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 8 ) & 0xFF ); + szSerObjName[ 16 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 4 ) & 0xFF ); + szSerObjName[ 17 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 0 ) & 0xFF ); + + ulResult = Oct6100UserCreateSerializeObject( &CreateSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + f_pApiInstance->ulApiSerObj = CreateSerObj.ulSerialObjHndl; + /*----------------------------------------------------------------------*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDestroySerializeObjects + +Description: Destroy handles to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDestroySerializeObjects +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_DESTROY_SERIALIZE_OBJECT DestroySerObj; + UINT32 ulResult; + + /* Set some parameters of the create structure once and for all. */ + DestroySerObj.pProcessContext = f_pApiInstance->pProcessContext; + DestroySerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + + ulResult = Oct6100UserDestroySerializeObject( &DestroySerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRunEgo + +Description: Private function used to communicate with the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_fStoreFlag Type of access performed. (Load or Store) +f_ulNumEntry Number of access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRunEgo +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 aulCpuLsuCmd[ 2 ]; + UINT16 usReadData; + UINT32 i; + BOOL fConditionFlag = TRUE; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* No more than 2 entries may be requested. */ + if ( f_ulNumEntry > 2 ) + return cOCT6100_ERR_FATAL_1B; + + /* Write the requested entries at address reserved for CPU. */ + for( i = 0; i < f_ulNumEntry; i++ ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_API_SCRATCH_PAD + ( 0x8 * i ); + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ i * 2 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ i * 2 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ (i * 2) + 1] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ (i * 2) + 1] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Preincrement code point. */ + pSharedInfo->MiscVars.usCodepoint++; + + /* Create DWORD 0 of command. */ + aulCpuLsuCmd[0] = 0x00000000; + if ( f_fStoreFlag == FALSE ) + aulCpuLsuCmd[0] |= 0xC0000000; /* EGO load. */ + else + aulCpuLsuCmd[0] |= 0xE0000000; /* EGO store. */ + + aulCpuLsuCmd[0] |= (f_ulNumEntry - 1) << 19; + aulCpuLsuCmd[0] |= cOCT6100_PART1_API_SCRATCH_PAD; + + /* Create DWORD 1 of command. */ + aulCpuLsuCmd[1] = 0x00000000; + aulCpuLsuCmd[1] |= ( ( cOCT6100_PART1_API_SCRATCH_PAD + 0x10 ) & 0xFFFF ) << 16; + aulCpuLsuCmd[1] |= pSharedInfo->MiscVars.usCodepoint; + + /* Write the EGO command in the LSU CB. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_CPU_LSU_CB_BASE + ((pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7) * 0x8 ); + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 0 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 0 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 1 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 1 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Post increment the write pointer. */ + pSharedInfo->MiscVars.usCpuLsuWritePtr++; + + /* Indicate new write pointer position to HW. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_EGO_REG + 0x5A; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for codepoint to be updated before returning. */ + while( fConditionFlag ) + { + ReadParams.ulReadAddress = cOCT6100_PART1_API_SCRATCH_PAD + 0x12; + usReadData = (UINT16)( pSharedInfo->MiscVars.usCodepoint ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == pSharedInfo->MiscVars.usCodepoint ) + fConditionFlag = FALSE; + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_OPEN_EGO_TIMEOUT; + } + + /* CRC error bit must be zero. */ + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & 0x0400 ) != 0 ) + return cOCT6100_ERR_OPEN_CORRUPTED_IMAGE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateEgoEntry + +Description: Private function used to create an access structure to be sent + to the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulExternalAddress External memory address for the access. +f_ulInternalAddress Which process should receive the command. +f_ulNumBytes Number of bytes associated to the access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateEgoEntry +UINT32 Oct6100ApiCreateEgoEntry( + IN UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + OUT UINT32 f_aulEntry[ 2 ] ) +{ + f_aulEntry[0] = 0x80000000; + f_aulEntry[0] |= f_ulExternalAddress & 0x07FFFFFC; + + f_aulEntry[1] = 0x0011C000; + f_aulEntry[1] |= (f_ulNumBytes / 8) << 23; + f_aulEntry[1] |= (f_ulInternalAddress >> 2) & 0x3FFF; + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitChannels + +Description: This function will initialize all the channels to power down. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitChannels +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + UINT32 ulResult; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usLoopCount = 0; + UINT16 usWriteData = 0; + UINT16 usMclkRead; + UINT16 usLastMclkRead; + UINT16 usMclkDiff; + UINT32 ulNumberOfCycleToWait; + UINT32 ulTimeoutCounter; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Verify that the image has enough memory to work correctly. */ + if ( ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) < pSharedInfo->MemoryMap.ulFreeMemBaseAddress ) + return cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY; + + /* Verify that the tail length is supported by the device.*/ + if ( pSharedInfo->ChipConfig.usTailDisplacement > pSharedInfo->ImageInfo.usMaxTailDisplacement ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE; + + /* Verify that acoustic echo is supported by the device. */ + if ( pSharedInfo->ChipConfig.fEnableAcousticEcho == TRUE && pSharedInfo->ImageInfo.fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO; + + /* Verify that the image supports all the requested channels. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->ImageInfo.usMaxNumberOfChannels ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Max number of channels the image supports + 1 for channel recording, if requested */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < cOCT6100_MAX_ECHO_CHANNELS ) + && ( pSharedInfo->ChipConfig.usMaxChannels == pSharedInfo->ImageInfo.usMaxNumberOfChannels ) ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Initialize the memory for all required channels. */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + /*==============================================================================*/ + /* Configure the Global Static Configuration memory of the channel. */ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( i * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst; + + /* Set the circular buffer size. */ + ulTempData &= 0xFFFFFF00; + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst;; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + /* Put all channel in powerdown mode "3". */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 0; + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the maximum number of channels. */ + WriteParams.ulWriteAddress = 0x690; + if ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < 384 ) + WriteParams.usWriteData = 384; + else + WriteParams.usWriteData = (UINT16)pSharedInfo->ImageInfo.usMaxNumberOfChannels; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set power-dowm TSI chariot memory to silence. */ + for( i = 0; i < 6; i++ ) + { + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1534 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1535 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove chariot hold. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( usLoopCount = 0; usLoopCount < 4096; usLoopCount++ ) + { + if ( (usLoopCount % 16) < 8 ) + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + } + else + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + usWriteData |= 0x78; + } + + /* Set timeslot pointer. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0003; + WriteParams.usWriteData |= usWriteData << 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read the mclk counter. */ + ReadParams.ulReadAddress = 0x30A; + ReadParams.pusReadData = &usLastMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset loop timeout counter. */ + ulTimeoutCounter = 0x0; + + do { + ReadParams.pusReadData = &usMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usLoopCount % 16 ) != 15 ) + { + ulNumberOfCycleToWait = 133; + } + else + { + ulNumberOfCycleToWait = 20000; + } + + /* Evaluate the difference. */ + usMclkDiff = (UINT16)(( usMclkRead - usLastMclkRead ) & 0xFFFF); + + /* Check for loop timeout. Bad mclk? */ + ulTimeoutCounter++; + if ( ulTimeoutCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_FATAL_EA; + + } while( usMclkDiff <= ulNumberOfCycleToWait ); + } + + /* Back to normal mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for CRC errors. */ + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData & 0x400) != 0x0000 ) + return cOCT6100_ERR_OPEN_CRC_ERROR; + + /* Clear the error rol raised by manually moving the clocks. */ + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + /* Write the tail displacement value in external memory. */ + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchTailDisplOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tail displacement. */ + ulTempData |= (pSharedInfo->ChipConfig.usTailDisplacement << ulFeatureBitOffset ); + + /* Write the DWORD where the field is located. */ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Clear the pouch counter, if present. */ + + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear counter! */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* The ISR has not yet been called. Set the appropriate bit in external memory. */ + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Toggle the bit to '1'. */ + ulTempData |= 1 << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitToneInfo + +Description: This function will parse the software image and retrieve + the information about the tones that it supports. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitToneInfo +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + unsigned char const *pszToneInfoStart = NULL; + unsigned char const *pszToneInfoEnd = NULL; + + unsigned char const *pszCurrentInfo; + unsigned char const *pszNextInfo; + + UINT32 ulToneEventNumber; + UINT32 ulTempValue; + UINT32 ulNumCharForValue; + UINT32 ulUniqueToneId; + UINT32 ulToneNameSize; + UINT32 ulOffset = 0; + + UINT32 i; + + /* Init the tone detector parameter. */ + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors = 0; + + /* Find the start and the end of the tone info section. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize > 4096 ) + { + /* For performance reasons, and since the tone detector information */ + /* is always located at the end of the image file, try to start from the end */ + /* of the buffer. */ + + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 2048; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + /* Check if the information was found. */ + if ( pszToneInfoStart == NULL ) + { + /* Try again, but giving a larger string to search. */ + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 4096; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + } + } + + if ( pszToneInfoStart == NULL ) + { + /* Travel through the whole file buffer. */ + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + } + /* We have to return immediatly if no tones are found. */ + if ( pszToneInfoStart == NULL ) + return cOCT6100_ERR_OK; + + /* The end of the tone detector information is after the beginning of the tone information. */ + pszToneInfoEnd = Oct6100ApiStrStr( pszToneInfoStart, + (PUINT8)cOCT6100_TONE_INFO_STOP_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + if ( pszToneInfoEnd == NULL ) + return cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND; + + /* Find and process all tone events within the region. */ + pszCurrentInfo = Oct6100ApiStrStr( pszToneInfoStart, (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + + while ( pszCurrentInfo != NULL ) + { + /* Skip the string. */ + pszCurrentInfo += ( Oct6100ApiStrLen( (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING ) ); + + /* Extract the number of char used to represent the tone event number ( 1 or 2 ). */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo, (PUINT8)",", pszToneInfoEnd ); + ulNumCharForValue = (UINT32)( pszNextInfo - pszCurrentInfo ); + + /* Retreive the event number */ + ulToneEventNumber = 0; + for ( i = ulNumCharForValue; i > 0; i-- ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulToneEventNumber |= ( ulTempValue << (( i - 1) * 4 ) ); + pszCurrentInfo++; + } + + if ( ulToneEventNumber >= cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_OPEN_INVALID_TONE_EVENT; + + /* Skip the comma and the 0x. */ + pszCurrentInfo += 3; + + /*======================================================================*/ + /* Retreive the unique tone id. */ + ulUniqueToneId = 0; + for ( i = 0; i < 8; i++ ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulOffset = 28 - ( i * 4 ); + ulUniqueToneId |= ( ulTempValue << ulOffset ); + pszCurrentInfo++; + } + + /*======================================================================*/ + + /* Skip the comma. */ + pszCurrentInfo++; + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + if ( pszNextInfo == NULL ) + pszNextInfo = pszToneInfoEnd; + + /* Extract the name size. */ + ulToneNameSize = (UINT32)( pszNextInfo - pszCurrentInfo - 2 ); /* - 2 for 0x0D and 0x0A.*/ + + if ( ulToneNameSize > cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + return cOCT6100_ERR_OPEN_INVALID_TONE_NAME; + + /* Copy the tone name into the image info structure. */ + ulResult = Oct6100UserMemCopy( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].aszToneName, + pszCurrentInfo, + ulToneNameSize ); + + + + /* Update the tone info into the image info structure. */ + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID = ulUniqueToneId; + /* Find out the port on which this tone detector is associated. */ + switch( (ulUniqueToneId >> 28) & 0xF ) + { + case 1: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT; + break; + + case 2: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + break; + + case 4: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SOUT; + break; + + case 5: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT_SOUT; + break; + + default: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_INVALID_PORT; + break; + } + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + /* Update the current info pointer. */ + pszCurrentInfo = pszNextInfo; + + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors++; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryBist + +Description: Tests the functionality of the external memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryBist +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMemSize = 0; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Test the external memory. */ + switch ( pSharedInfo->ChipConfig.ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + ulMemSize = cOCT6100_SIZE_8M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + ulMemSize = cOCT6100_SIZE_16M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + ulMemSize = cOCT6100_SIZE_32M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + ulMemSize = cOCT6100_SIZE_64M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + ulMemSize = cOCT6100_SIZE_128M; + break; + default: + return cOCT6100_ERR_FATAL_D9; + } + + ulMemSize *= pSharedInfo->ChipConfig.byNumMemoryChips; + + ulResult = Oct6100ApiRandomMemoryWrite( f_pApiInstance, cOCT6100_EXTERNAL_MEM_BASE_ADDRESS, ulMemSize, 16, 1000, cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the user I/O functions are working as required. */ + ulResult = Oct6100ApiUserIoTest( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGenerateNumber + +Description: Generate a number using an index. Passing the same + index generates the same number. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulIndex Index used to generate the random number. +f_ulDataMask Data mask to apply to generated number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGenerateNumber +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ) +{ + UINT16 usGeneratedNumber; + + usGeneratedNumber = (UINT16)( ( ( ~( f_ulIndex - 1 ) ) & 0xFF00 ) | ( ( f_ulIndex + 1 ) & 0xFF ) ); + + return (UINT16)( usGeneratedNumber & f_ulDataMask ); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRandomMemoryWrite + +Description: Writes to f_ulNumAccesses random locations in the indicated + memory and read back to test the operation of that memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulMemBase Base address of the memory access. +f_ulMemSize Size of the memory to be tested. +f_ulNumDataBits Number of data bits. +f_ulNumAccesses Number of random access to be perform. +f_ulErrorCode Error code to be returned if the bist fails. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRandomMemoryWrite +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulDataMask; + UINT32 ulResult, i, j; + UINT32 ulBistAddress; + UINT16 usReadData; + UINT32 aulBistAddress[20]={0x00000000, 0x00000002, 0x00000004, 0x007FFFFE, + 0x00900000, 0x00900006, 0x00900008, 0x009FFFFE, + 0x01000000, 0x0100000A, 0x0200000C, 0x01FFFFFE, + 0x03000000, 0x03000002, 0x04000004, 0x03FFFFFE, + 0x04000000, 0x05000006, 0x06000008, 0x07FFFFFE}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Determine mask for number of data bits. */ + ulDataMask = (1 << f_ulNumDataBits) - 1; + + /* Write specific data to specific address */ + WriteParams.ulWriteAddress = f_ulMemBase | 0x00001000; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for(j=0; j<20; j++) + { + /* Change address to test lower and higher part of the 32 bit bus */ + ulBistAddress = aulBistAddress[j]; + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + /* Bist 16 data pins of this address */ + for ( i = 0; i < 16; i ++) + { + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = (UINT16)(0x1 << i); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back the specific data to flush the data bus.*/ + ReadParams.ulReadAddress = f_ulMemBase | 0x00001000; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return f_ulErrorCode; + + /* Read back the data written.*/ + ReadParams.ulReadAddress = WriteParams.ulWriteAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != (UINT16)(0x1 << i) ) + return f_ulErrorCode; + } + } + + /* Perform the first write at address 0 + mem base */ + j = 0; + WriteParams.ulWriteAddress = f_ulMemBase; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Try each address line of the memory. */ + for ( i = 2, j = 1; i < f_ulMemSize; i <<= 1, j++ ) + { + WriteParams.ulWriteAddress = ( f_ulMemBase + i ); + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < j; i++ ) + { + if ( i > 0 ) + ReadParams.ulReadAddress = ( f_ulMemBase + ( 0x1 << i ) ); + else + ReadParams.ulReadAddress = f_ulMemBase; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != Oct6100ApiGenerateNumber( f_pApiInstance, i, ulDataMask ) ) + return f_ulErrorCode; + } + + /* Write to random addresses of the memory. */ + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + ReadParams.ulReadAddress = ulBistAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & ulDataMask ) != ( Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) & ulDataMask ) ) + return f_ulErrorCode; + } + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUserIoTest + +Description: This function will verify the correct functionality of + the following user functions: + + - Oct6100UserDriverWriteBurstApi + - Oct6100UserDriverWriteSmearApi + - Oct6100UserDriverReadBurstApi + + The Oct6100UserDriverWriteApi and Oct6100UserDriverReadApi + functions do not need to be tested here as this has be done in + the external memory bisting function above. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUserIoTest +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + tOCT6100_WRITE_SMEAR_PARAMS WriteSmearParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + UINT32 ulResult, i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + WriteBurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + WriteBurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + WriteSmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteSmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a smear. */ + WriteSmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + + /*======================================================================*/ + /* Write burst check. */ + + WriteBurstParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + /* Set the random data to be written. */ + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + WriteBurstParams.pusWriteData[ i ] = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + } + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteBurstParams.pusWriteData[ i ] ) + { + /* The values do not match. Something seems to be wrong with the WriteBurst user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Write smear check. */ + + WriteSmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + ( WriteBurstParams.ulWriteLength * 2 ); + /* Set the random data to be written. */ + WriteSmearParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, Oct6100ApiRand( 0xFFFF ), 0xFFFF ); + mOCT6100_DRIVER_WRITE_SMEAR_API( WriteSmearParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + for ( i = 0; i < WriteSmearParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the WriteSmear user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read burst check. */ + + /* First check with what the WriteBurst function wrote. */ + ReadBurstParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /* Then check with what the WriteSmear function wrote. */ + ReadBurstParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryInit + +Description: Initialize the external memory before uploading the image. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryInit +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulTotalWordToWrite; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Clear the first part of the memory. */ + ulTotalWordToWrite = 0x400; + SmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + while ( ulTotalWordToWrite != 0 ) + { + if ( ulTotalWordToWrite >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + SmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + SmearParams.ulWriteLength = ulTotalWordToWrite; + + SmearParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the number of words to write. */ + ulTotalWordToWrite -= SmearParams.ulWriteLength; + /* Update the address. */ + SmearParams.ulWriteAddress += ( SmearParams.ulWriteLength * 2 ); + } + + /* Clear the TLV flag.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_TLV_BASE, 0x0 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitMixer + +Description: This function will initialize the mixer memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitMixer +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 ausWriteData[ 4 ]; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + /*======================================================================*/ + /* Initialize the mixer memory if required. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Modify the mixer pointer by adding the record event into the link list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node.*/ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the Sout copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordSinEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordCopyEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Init the mixer pointer */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + } + else + { + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the tail node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + 0x10; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_HEAD_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitRecordResources + +Description: This function will initialize the resources required to + perform recording on a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitRecordResources +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_OK; + + if ( pSharedInfo->DebugInfo.usRecordMemIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD; + + /* Check the provided recording memory index within the SSPX. */ + if ( pSharedInfo->DebugInfo.usRecordMemIndex != ( pSharedInfo->ImageInfo.usMaxNumberOfChannels - 1 ) ) + return cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX; + + /* Reserve the TSI entries for the channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Open the debug channel. */ + ulResult = Oct6100ApiDebugChannelOpen( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResourcesSer + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesSer +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Close all bidirectional channels. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxBiDirChannels; i ++ ) + { + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, i ); + + if ( pBiDirChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_DESTROY_BIDIR DestroyBidir; + + Oct6100ChannelDestroyBiDirDef( &DestroyBidir ); + + DestroyBidir.ulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, &DestroyBidir ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all bridge participants. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + if ( pChanEntry->fReserved == TRUE && pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* This channel is on a bridge. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pChanEntry->usBridgeIndex ); + + BridgeChanRemove.fRemoveAll = TRUE; + BridgeChanRemove.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usBridgeIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all opened channels. This will bring the broadcast TSSTs with it. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + + if ( pChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_CLOSE ChannelClose; + + /* Generate handle. */ + ChannelClose.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + /* Call serialized close channel function. */ + ulResult = Oct6100ChannelCloseSer( f_pApiInstance, &ChannelClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /* Close all TSI connections. */ + if ( f_pFreeResources->fFreeTsiConnections == TRUE ) + { + tPOCT6100_API_TSI_CNCT pTsiCnct; + tOCT6100_TSI_CNCT_CLOSE TsiCnctClose; + + Oct6100TsiCnctCloseDef( &TsiCnctClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxTsiCncts; i ++ ) + { + /* Obtain a pointer to the TSI connection list entry. */ + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnct, i ); + + if ( pTsiCnct->fReserved == TRUE ) + { + TsiCnctClose.ulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnct->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100TsiCnctCloseSer( f_pApiInstance, &TsiCnctClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all conference bridges. */ + if ( f_pFreeResources->fFreeConferenceBridges == TRUE ) + { + tPOCT6100_API_CONF_BRIDGE pConfBridge; + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxConfBridges; i ++ ) + { + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pConfBridge, i ); + + if ( pConfBridge->fReserved == TRUE ) + { + ConfBridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pConfBridge->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &ConfBridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Free all playout buffers loaded in external memory. */ + if ( f_pFreeResources->fFreePlayoutBuffers == TRUE ) + { + tPOCT6100_API_BUFFER pBuffer; + tOCT6100_BUFFER_UNLOAD BufferUnload; + + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPlayoutBuffers; i ++ ) + { + + + /* Obtain a pointer to the buffer list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBuffer, i ); + + if ( pBuffer->fReserved == TRUE ) + { + BufferUnload.ulBufferIndex = i; + ulResult = Oct6100BufferUnloadSer( f_pApiInstance, &BufferUnload, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Close all phasing TSSTs. */ + if ( f_pFreeResources->fFreePhasingTssts == TRUE ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + tOCT6100_PHASING_TSST_CLOSE PhasingTsstClose; + + Oct6100PhasingTsstCloseDef( &PhasingTsstClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPhasingTssts; i ++ ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, i ); + + if ( pPhasingTsst->fReserved == TRUE ) + { + PhasingTsstClose.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsst->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100PhasingTsstCloseSer( f_pApiInstance, &PhasingTsstClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all ADPCM channels. */ + if ( f_pFreeResources->fFreeAdpcmChannels == TRUE ) + { + tPOCT6100_API_ADPCM_CHAN pAdpcmChannel; + tOCT6100_ADPCM_CHAN_CLOSE AdpcmChanClose; + + Oct6100AdpcmChanCloseDef( &AdpcmChanClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxAdpcmChannels; i ++ ) + { + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChannel, i ); + if ( pAdpcmChannel->fReserved == TRUE ) + { + AdpcmChanClose.ulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100AdpcmChanCloseSer( f_pApiInstance, &AdpcmChanClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBistSer + +Description: This function returns the instantaneous production BIST status. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure in which BIST status will + be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistSer +UINT32 Oct6100ProductionBistSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + UINT32 ulCalculatedCrc = cOCT6100_INVALID_VALUE; + UINT32 ulResult; + UINT32 ulLoopCnt = 0x0; + UINT32 i = 1; + UINT32 ulTotalElements = 4; + UINT32 ulReadAddress = cOCT6100_POUCH_BASE; + UINT32 aulMessage[ 5 ]; + + /* Check if the production bist has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) + return cOCT6100_ERR_PRODUCTION_BIST_DISABLED; + + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + + /* The API knows that the firmware might be writing a status event. */ + /* The firmware does write a status event every 200ms (approximately). */ + /* So the status is read a couple of times to make sure an event was not read while */ + /* it was written. */ + while ( ulLoopCnt != 2 ) + { + /* Read the BIST status in the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulReadAddress + i * 4, &aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Calculate the CRC of this message. */ + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCalculatedCrc ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the CRCs do match, break off the while. We have a valid status event. */ + if ( aulMessage[ i - 1 ] == ulCalculatedCrc ) + break; + + ulLoopCnt++; + } + + /* Check if the CRC matches */ + if ( aulMessage[ i - 1 ] != ulCalculatedCrc ) + { + /* Well, the exchange memory at the base of the external memory is corrupted. */ + /* Something very basic is not working correctly with this chip! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_STATUS_CRC_FAILED; + } + else + { + /* Check for problems. */ + switch ( aulMessage[ 0 ] & 0xFFFF ) + { + case ( 0x2 ): + + /* The initial configuration failed. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_CONFIGURATION_FAILED; + break; + + case ( 0x1 ): + + /* A memory location failed. Return useful information to the user. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_MEMORY_FAILED; + + f_pProductionBist->ulFailedAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulReadValue = aulMessage[ 2 ]; + f_pProductionBist->ulExpectedValue = aulMessage[ 3 ]; + break; + + case ( 0xFFFF ): + + /* Bist is completed! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_SUCCESS; + break; + + default: + /* Bist is in progress. All seems to be working fine up to now. */ + + /* Return progress status. */ + f_pProductionBist->ulCurrentAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulCurrentTest = aulMessage[ 2 ]; + f_pProductionBist->ulCurrentLoop = aulMessage[ 3 ]; + break; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProductionCrc + +Description: This function calculates the crc for a production BIST + message. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulMessage Message to be exchanged with the firmware. The CRC + will be calculated on this. +f_ulMessageLength Length of the message to be exchanged. This value + does not include the CRC value at the end +f_pulCrcResult Resulting calculated CRC value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProductionCrc +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ) +{ + UINT32 ulWidth = 32; + UINT32 ulKey, i, j; + UINT32 ulRemainder = 0; + + /* CRC the message. */ + ulRemainder = f_pulMessage[ f_ulMessageLength - 1 ]; + for ( j = f_ulMessageLength - 1; j != 0xFFFFFFFF ; j-- ) + { + for ( i = 0; i < ulWidth; i++ ) + { + if ( ( ( ulRemainder >> 0x1F ) & 0x1 ) == 0x1 ) + { + /* Division is by something meaningful */ + ulKey = 0x8765DCBA; + } + else + { + /* Remainder is less than our divisor */ + ulKey = 0; + } + ulRemainder = ulRemainder ^ ulKey; + + ulRemainder = ulRemainder << 1; + if ( j != 0 ) + { + ulRemainder = ulRemainder | ( ( f_pulMessage[ j - 1 ] ) >> ( 0x1F - i ) ); + } + } + } + + *f_pulCrcResult = ulRemainder; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearInterrupts + +Description: Called only by the Oct6100OpenChip function, this function + writes to all register ROLs to clear them. This is necessary + because some ROLs are set during the startup. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +IN f_pApiInst Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearInterrupts +UINT32 Oct6100ApiClearInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_102H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_202H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_302H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_502H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_702H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; + +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c new file mode 100644 index 0000000..162c43e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c @@ -0,0 +1,441 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to retreive the OCT6100 chip stats. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 89 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_stats_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_chip_stats_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStats + +Description: Retreives the chip statistics and configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to a tOCT6100_CHIP_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsDef +UINT32 Oct6100ChipGetStatsDef( + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + f_pChipStats->fResetChipStats = FALSE; + + f_pChipStats->ulNumberChannels = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberTsiCncts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberConfBridges = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberPlayoutBuffers = cOCT6100_INVALID_STAT; + f_pChipStats->ulPlayoutFreeMemSize = cOCT6100_INVALID_STAT; + + f_pChipStats->ulNumberPhasingTssts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberAdpcmChannels = cOCT6100_INVALID_STAT; + + f_pChipStats->ulH100OutOfSynchCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100FrameABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockBBadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulInternalReadTimeoutCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSdramRefreshTooLateCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulPllJitterErrorCount = cOCT6100_INVALID_STAT; + + f_pChipStats->ulOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = cOCT6100_INVALID_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetStats +UINT32 Oct6100ChipGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChipGetStatsSer( f_pApiInstance, f_pChipStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetImageInfo + +Description: Retrieves the chip image information indicating the supported + features and tones. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipImageInfo Pointer to a tPOCT6100_CHIP_IMAGE_INFO structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetImageInfoDef +UINT32 Oct6100ChipGetImageInfoDef( + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + UINT32 i; + + Oct6100UserMemSet( f_pChipImageInfo->szVersionNumber, 0x0, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + f_pChipImageInfo->fBufferPlayout = FALSE; + f_pChipImageInfo->fAdaptiveNoiseReduction = FALSE; + f_pChipImageInfo->fSoutNoiseBleaching = FALSE; + f_pChipImageInfo->fConferencingNoiseReduction = FALSE; + f_pChipImageInfo->fAutoLevelControl = FALSE; + f_pChipImageInfo->fHighLevelCompensation = FALSE; + f_pChipImageInfo->fSilenceSuppression = FALSE; + + f_pChipImageInfo->fAdpcm = FALSE; + f_pChipImageInfo->fConferencing = FALSE; + f_pChipImageInfo->fDominantSpeaker = FALSE; + f_pChipImageInfo->ulMaxChannels = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulNumTonesAvailable = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulToneProfileNumber = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailDisplacement = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulBuildId = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailLength = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulDebugEventSize = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxPlayoutEvents = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulImageType = cOCT6100_INVALID_VALUE; + + f_pChipImageInfo->fAcousticEcho = FALSE; + f_pChipImageInfo->fAecTailLength = FALSE; + f_pChipImageInfo->fToneRemoval = FALSE; + + f_pChipImageInfo->fDefaultErl = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorA = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorB = FALSE; + f_pChipImageInfo->fPerChannelTailDisplacement = FALSE; + f_pChipImageInfo->fPerChannelTailLength = FALSE; + f_pChipImageInfo->fListenerEnhancement = FALSE; + f_pChipImageInfo->fRoutNoiseReduction = FALSE; + f_pChipImageInfo->fRoutNoiseReductionLevel = FALSE; + f_pChipImageInfo->fAnrSnrEnhancement = FALSE; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = FALSE; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = FALSE; + f_pChipImageInfo->fMusicProtection = FALSE; + f_pChipImageInfo->fDoubleTalkBehavior = FALSE; + f_pChipImageInfo->fIdleCodeDetection = TRUE; + f_pChipImageInfo->fSinLevel = TRUE; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemSet( f_pChipImageInfo->aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetImageInfo +UINT32 Oct6100ChipGetImageInfo( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + UINT32 i; + + /* Get local pointer(s). */ + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + Oct6100UserMemCopy( f_pChipImageInfo->szVersionNumber, pImageInfo->szVersionNumber, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + /* Copy the customer info. */ + f_pChipImageInfo->ulBuildId = pImageInfo->ulBuildId; + + /* Copy the features list. */ + f_pChipImageInfo->fBufferPlayout = pImageInfo->fBufferPlayout; + f_pChipImageInfo->fAdaptiveNoiseReduction = pImageInfo->fAdaptiveNoiseReduction; + f_pChipImageInfo->fSoutNoiseBleaching = pImageInfo->fSoutNoiseBleaching; + f_pChipImageInfo->fSilenceSuppression = pImageInfo->fSilenceSuppression; + + f_pChipImageInfo->fAdpcm = pImageInfo->fAdpcm; + f_pChipImageInfo->fConferencing = pImageInfo->fConferencing; + f_pChipImageInfo->fDominantSpeaker = pImageInfo->fDominantSpeakerEnabled; + f_pChipImageInfo->fConferencingNoiseReduction = pImageInfo->fConferencingNoiseReduction; + f_pChipImageInfo->fAcousticEcho = pImageInfo->fAcousticEcho; + f_pChipImageInfo->fAecTailLength = pImageInfo->fAecTailLength; + f_pChipImageInfo->fDefaultErl = pImageInfo->fDefaultErl; + f_pChipImageInfo->fToneRemoval = pImageInfo->fToneRemoval; + + f_pChipImageInfo->fNonLinearityBehaviorA = pImageInfo->fNonLinearityBehaviorA; + f_pChipImageInfo->fNonLinearityBehaviorB = pImageInfo->fNonLinearityBehaviorB; + f_pChipImageInfo->fPerChannelTailDisplacement = pImageInfo->fPerChannelTailDisplacement; + f_pChipImageInfo->fListenerEnhancement = pImageInfo->fListenerEnhancement; + f_pChipImageInfo->fRoutNoiseReduction = pImageInfo->fRoutNoiseReduction; + f_pChipImageInfo->fRoutNoiseReductionLevel = pImageInfo->fRoutNoiseReductionLevel; + f_pChipImageInfo->fAnrSnrEnhancement = pImageInfo->fAnrSnrEnhancement; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = pImageInfo->fAnrVoiceNoiseSegregation; + f_pChipImageInfo->fMusicProtection = pImageInfo->fMusicProtection; + f_pChipImageInfo->fIdleCodeDetection = pImageInfo->fIdleCodeDetection; + f_pChipImageInfo->fSinLevel = pImageInfo->fSinLevel; + f_pChipImageInfo->fDoubleTalkBehavior = pImageInfo->fDoubleTalkBehavior; + f_pChipImageInfo->fHighLevelCompensation = pImageInfo->fRinHighLevelCompensation; + + if ( ( pImageInfo->fRinAutoLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == TRUE ) ) + f_pChipImageInfo->fAutoLevelControl = TRUE; + else + f_pChipImageInfo->fAutoLevelControl = FALSE; + + f_pChipImageInfo->ulMaxChannels = pImageInfo->usMaxNumberOfChannels; + f_pChipImageInfo->ulNumTonesAvailable = pImageInfo->byNumToneDetectors; + f_pChipImageInfo->ulToneProfileNumber = pImageInfo->ulToneProfileNumber; + f_pChipImageInfo->ulMaxTailDisplacement = pImageInfo->usMaxTailDisplacement; + f_pChipImageInfo->ulMaxTailLength = pImageInfo->usMaxTailLength; + f_pChipImageInfo->fPerChannelTailLength = pImageInfo->fPerChannelTailLength; + f_pChipImageInfo->ulDebugEventSize = f_pApiInstance->pSharedInfo->DebugInfo.ulDebugEventSize; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = pImageInfo->fToneDisablerVqeActivationDelay; + f_pChipImageInfo->ulMaxPlayoutEvents = pImageInfo->byMaxNumberPlayoutEvents - 1; /* 127 or 31 */ + f_pChipImageInfo->ulImageType = pImageInfo->byImageType; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemCopy( f_pChipImageInfo->aToneInfo[ i ].aszToneName, pImageInfo->aToneInfo[ i ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = pImageInfo->aToneInfo[ i ].ulDetectionPort; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = pImageInfo->aToneInfo[ i ].ulToneID; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChipStatsSwInit + +Description: Initializes portions of API instance associated to chip stats. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChipStatsSwInit +UINT32 Oct6100ApiChipStatsSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer to shared portion of API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize chip stats. */ + pSharedInfo->ErrorStats.fFatalChipError = FALSE; + + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + + + + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt = 0; + + /* Init the chip stats. */ + pSharedInfo->ChipStats.usNumberChannels = 0; + pSharedInfo->ChipStats.usNumberBiDirChannels = 0; + pSharedInfo->ChipStats.usNumberTsiCncts = 0; + pSharedInfo->ChipStats.usNumberConfBridges = 0; + pSharedInfo->ChipStats.usNumberPlayoutBuffers = 0; + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts = 0; + pSharedInfo->ChipStats.ulPlayoutMemUsed = 0; + pSharedInfo->ChipStats.usNumEcChanUsingMixer = 0; + + pSharedInfo->ChipStats.usNumberPhasingTssts = 0; + pSharedInfo->ChipStats.usNumberAdpcmChans = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStatsSer + +Description: Serialized function retreiving the chip statistics. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to master mode configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsSer +UINT32 Oct6100ChipGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + f_pChipStats->ulNumberChannels = pSharedInfo->ChipStats.usNumberChannels; + f_pChipStats->ulNumberTsiCncts = pSharedInfo->ChipStats.usNumberTsiCncts; + f_pChipStats->ulNumberConfBridges = pSharedInfo->ChipStats.usNumberConfBridges; + f_pChipStats->ulNumberPlayoutBuffers = pSharedInfo->ChipStats.usNumberPlayoutBuffers; + f_pChipStats->ulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( pSharedInfo->ChipStats.ulPlayoutMemUsed ); + + f_pChipStats->ulNumberPhasingTssts = pSharedInfo->ChipStats.usNumberPhasingTssts; + f_pChipStats->ulNumberAdpcmChannels = pSharedInfo->ChipStats.usNumberAdpcmChans; + + /* Check the input parameters. */ + if ( f_pChipStats->fResetChipStats != TRUE && + f_pChipStats->fResetChipStats != FALSE ) + return cOCT6100_ERR_CHIP_STATS_RESET; + + if ( f_pChipStats->fResetChipStats == TRUE ) + { + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + + } + + f_pChipStats->ulH100OutOfSynchCount = pSharedInfo->ErrorStats.ulH100OutOfSyncCnt; + f_pChipStats->ulH100ClockABadCount = pSharedInfo->ErrorStats.ulH100ClkABadCnt; + f_pChipStats->ulH100FrameABadCount = pSharedInfo->ErrorStats.ulH100FrameABadCnt; + f_pChipStats->ulH100ClockBBadCount = pSharedInfo->ErrorStats.ulH100ClkBBadCnt; + + f_pChipStats->ulInternalReadTimeoutCount = pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt; + f_pChipStats->ulPllJitterErrorCount = pSharedInfo->ErrorStats.ulPllJitterErrorCnt; + f_pChipStats->ulSdramRefreshTooLateCount = pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt; + + f_pChipStats->ulOverflowToneEventsCount = pSharedInfo->ErrorStats.ulOverflowToneEventsCnt; + f_pChipStats->ulSoftOverflowToneEventsCount = pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt; + + + + return cOCT6100_ERR_OK; +} +#endif + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c new file mode 100644 index 0000000..1b279d6 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c @@ -0,0 +1,7664 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains all functions related to a conference bridge. Procedures + needed to open/close a bridge, add/remove a participant to a conference + bridge, mute/unmute a participant, etc.. are all present in this source + file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 146 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_conf_bridge_priv.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpen + +Description: This function opens a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenDef +UINT32 Oct6100ConfBridgeOpenDef( + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + f_pConfBridgeOpen->pulConfBridgeHndl = NULL; + f_pConfBridgeOpen->fFlexibleConferencing = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeOpen +UINT32 Oct6100ConfBridgeOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeOpenSer( f_pApiInstance, f_pConfBridgeOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeClose + +Description: This function closes a conference bridge. A conference + bridge can only be closed if no participants are present on + the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseDef +UINT32 Oct6100ConfBridgeCloseDef( + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeClose +UINT32 Oct6100ConfBridgeClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeCloseSer( f_pApiInstance, f_pConfBridgeClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanAdd + +Description: This function adds an echo channel (participant) to a + conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeAdd Pointer to conference bridge channel addition structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanAddDef +UINT32 Oct6100ConfBridgeChanAddDef( + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + f_pConfBridgeAdd->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulInputPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pConfBridgeAdd->ulListenerMaskIndex = cOCT6100_INVALID_VALUE; + f_pConfBridgeAdd->ulListenerMask = 0; + f_pConfBridgeAdd->fMute = FALSE; + f_pConfBridgeAdd->ulTappedChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanAdd +UINT32 Oct6100ConfBridgeChanAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanAddSer( f_pApiInstance, f_pConfBridgeAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanRemove + +Description: This function removes an echo channel (participant) from a + conference bridge. All participants can be removed from + the bridge if a special flag (fRemoveAll) is set to TRUE. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeRemove Pointer to conference bridge channel removal structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanRemoveDef +UINT32 Oct6100ConfBridgeChanRemoveDef( + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + f_pConfBridgeRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanRemove +UINT32 Oct6100ConfBridgeChanRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, f_pConfBridgeRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanMute + +Description: This function mutes a participant present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge channel mute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanMuteDef +UINT32 Oct6100ConfBridgeChanMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + f_pConfBridgeMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanMute +UINT32 Oct6100ConfBridgeChanMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanMuteSer( f_pApiInstance, f_pConfBridgeMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanUnMute + +Description: This function unmutes a channel on a bridge. The other member + of the conference will start to hear this participant again. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanUnMuteDef +UINT32 Oct6100ConfBridgeChanUnMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + f_pConfBridgeUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ConfBridgeChanUnMute +UINT32 Oct6100ConfBridgeChanUnMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanUnMuteSer( f_pApiInstance, f_pConfBridgeUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeDominantSpeakerSet + +Description: This function sets a participant present on a conference + bridge as the dominant speaker. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeDominant Pointer to conference bridge dominant speaker + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSetDef +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + f_pConfBridgeDominantSpeaker->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeDominantSpeaker->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSet +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeDominantSpeakerSetSer( f_pApiInstance, f_pConfBridgeDominantSpeaker ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeMaskChange + +Description: This function changes the mask of a flexible bridge participant. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeMaskChange Pointer to conference bridge change of mask + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeMaskChangeDef +UINT32 Oct6100ConfBridgeMaskChangeDef( + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + f_pConfBridgeMaskChange->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeMaskChange->ulNewListenerMask = 0x0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeMaskChange +UINT32 Oct6100ConfBridgeMaskChange( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeMaskChangeSer( f_pApiInstance, f_pConfBridgeMaskChange ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeGetStats + +Description: This function returns the stats for a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeStats Pointer to conference bridge channel stats structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeGetStatsDef +UINT32 Oct6100ConfBridgeGetStatsDef( + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + f_pConfBridgeStats->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeStats->ulNumChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->ulNumTappedChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->fFlexibleConferencing = cOCT6100_INVALID_STAT; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeGetStats +UINT32 Oct6100ConfBridgeGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeGetStatsSer( f_pApiInstance, f_pConfBridgeStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetConfBridgeSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetConfBridgeSwSizes +UINT32 Oct6100ApiGetConfBridgeSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate memory needed for conference bridge list. */ + if ( f_pOpenChip->ulMaxConfBridges == 0 && f_pOpenChip->fEnableChannelRecording == TRUE ) + f_pOpenChip->ulMaxConfBridges = 1; + f_pInstSizes->ulConfBridgeList = f_pOpenChip->ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE ); + + /* Calculate memory needed for conference bridge allocation software. */ + if ( f_pOpenChip->ulMaxConfBridges > 0 ) + { + /* Get size of bridge allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxConfBridges, &f_pInstSizes->ulConfBridgeAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + + /* Check if the user wants to build flexible conference bridges. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants > 0 ) + { + /* Allocate the lowest quantity according to what the user requested. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants < ( f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) ) + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxFlexibleConfParticipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + else + { + f_pOpenChip->ulMaxFlexibleConfParticipants = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + } + + /* Get size of flexible conferencing participants allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxFlexibleConfParticipants, &f_pInstSizes->ulFlexConfParticipantsAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + } + else + { + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + } + else + { + f_pInstSizes->ulMixerEventList = 0; + f_pInstSizes->ulMixerEventAlloc = 0; + f_pInstSizes->ulConfBridgeAlloc = 0; + + /* Make sure flexible conferencing is not used. */ + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + + /* Calculate memory needed for list and allocation software serialization. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeAlloc, ulTempVar ) + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiConfBridgeSwInit + +Description: Initializes all elements of the instance structure associated + to conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiConfBridgeSwInit +UINT32 Oct6100ApiConfBridgeSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pConfBridgeList; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pFlexConfParticipantList; + PVOID pFlexConfPartipantsAlloc; + UINT32 ulMaxFlexConfParicipants; + PVOID pConfBridgeAlloc; + UINT32 ulMaxConfBridges; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the maximum number of conference bridges. */ + ulMaxConfBridges = pSharedInfo->ChipConfig.usMaxConfBridges; + + /*===================================================================*/ + /* Set all entries in the conference bridge list to unused. */ + + mOCT6100_GET_CONF_BRIDGE_LIST_PNT( pSharedInfo, pConfBridgeList ); + + /* Initialize the conference bridge allocation software to "all free". */ + if ( ulMaxConfBridges > 0 ) + { + /* Clear the bridge memory */ + Oct6100UserMemSet( pConfBridgeList, 0x00, ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE )); + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( pSharedInfo, pConfBridgeAlloc ) + + ulResult = OctapiLlmAllocInit( &pConfBridgeAlloc, ulMaxConfBridges ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + } + /*===================================================================*/ + + + /*===================================================================*/ + /* Set all entries in the flexible conferencing participant list to unused. */ + + /* Get the maximum number of flexible conferencing participants. */ + ulMaxFlexConfParicipants = pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_LIST_PNT( pSharedInfo, pFlexConfParticipantList ); + + /* Initialize the flexible conferencing allocation software. */ + if ( ulMaxFlexConfParicipants > 0 ) + { + UINT32 i, ulEventIndex; + + /* Clear the participants memory */ + Oct6100UserMemSet( pFlexConfParticipantList, 0x00, ulMaxFlexConfParicipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT )); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( pSharedInfo, pFlexConfPartipantsAlloc ) + + ulResult = OctapiLlmAllocInit( &pFlexConfPartipantsAlloc, ulMaxFlexConfParicipants ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + + /* Initialize the conferencing indexes. */ + for ( i = 0; i < ulMaxFlexConfParicipants; i ++ ) + { + for ( ulEventIndex = 0; ulEventIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulEventIndex ++ ) + pFlexConfParticipantList[ i ].ausLoadOrAccumulateEventIndex[ ulEventIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpenSer + +Description: Open a conference bridge. Note that no chip resources are + allocated until a channel is added to the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + The handle identifying the conference bridge in all + future function calls is returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenSer +UINT32 Oct6100ConfBridgeOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Check the user's configuration of the conference bridge for errors. */ + ulResult = Oct6100ApiCheckBridgeParams( f_pApiInstance, f_pConfBridgeOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiReserveBridgeResources( f_pApiInstance, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new conference bridge's entry in the conference bridge list. */ + ulResult = Oct6100ApiUpdateBridgeEntry( f_pApiInstance, f_pConfBridgeOpen, usBridgeIndex); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeParams + +Description: Checks the user's conference bridge open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeParams +UINT32 Oct6100ApiCheckBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeOpen->pulConfBridgeHndl == NULL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fConferencing == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE; + + if ( f_pConfBridgeOpen->fFlexibleConferencing != FALSE + && f_pConfBridgeOpen->fFlexibleConferencing != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeResources + +Description: Reserves all resources needed for the new conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBridgeIndex Allocated entry in the API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeResources +UINT32 Oct6100ApiReserveBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the conference bridge list. */ + ulResult = Oct6100ApiReserveBridgeEntry( f_pApiInstance, f_pusBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeEntry + +Description: Updates the new conference bridge's entry in the conference + bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. +f_usBridgeIndex Allocated entry in API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeEntry +UINT32 Oct6100ApiUpdateBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new conference bridge's list entry. */ + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ) + + /* No clients are currently connected to the bridge. */ + pBridgeEntry->usNumClients = 0; + /* Nobody is tapped for now. */ + pBridgeEntry->usNumTappedClients = 0; + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + /* Now update the bridge pointer. */ + if ( f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened == 0 ) + { + pBridgeEntry->usNextBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + + /* Set the global first bridge to this bridge. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + else /* Insert this bridge at the head of the bridge list.*/ + { + if ( f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_22; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge ) + + if ( pTempBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_FATAL_23; + + /* Modify the old first entry. */ + pTempBridgeEntry->usPrevBridgePtr = f_usBridgeIndex; + + /* Modify current pointer. */ + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usNextBridgePtr = f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge; + + /* Set the new first bridge of the list. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + + /* Form handle returned to user. */ + *f_pConfBridgeOpen->pulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBridgeIndex; + + /* Remember whether or not we are a flexible conference bridge. */ + pBridgeEntry->fFlexibleConferencing = (UINT8)( f_pConfBridgeOpen->fFlexibleConferencing & 0xFF ); + + /* Finally, mark the conference bridge as opened. */ + pBridgeEntry->fReserved = TRUE; + + /* Increment the number of conference bridge opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberConfBridges++; + f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeCloseSer + +Description: Closes a conference bridge. Note that no client must be present + on the bridge for the bridge to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseSer +UINT32 Oct6100ConfBridgeCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertBridgeParams( f_pApiInstance, f_pConfBridgeClose, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the conference bridge. */ + ulResult = Oct6100ApiReleaseBridgeResources( f_pApiInstance, usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertBridgeParams + +Description: Checks the user's conference bridge close configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. +f_pusBridgeIndex Pointer to API instance conference bridge index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertBridgeParams +UINT32 Oct6100ApiAssertBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeClose->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( pBridgeEntry->usNumClients != 0 ) + return cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBridgeResources + +Description: Release all resources reserved for the conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex Allocated external memory block for the conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBridgeResources +UINT32 Oct6100ApiReleaseBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Release the entry from the conference bridge list. */ + ulResult = Oct6100ApiReleaseBridgeEntry( f_pApiInstance, f_usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_24; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + /* Remove the bridge entry from the bridge list. */ + if ( pSharedInfo->MiscVars.usNumBridgesOpened == 1 ) + { + /* This bridge was the only one opened. */ + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MiscVars.usNumBridgesOpened > 1 ) + { + /* There are more then one bridge open, must update the list. */ + if ( pBridgeEntry->usPrevBridgePtr != cOCT6100_INVALID_INDEX ) + { + /* There is a valid entry before this bridge, let's update this entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, pBridgeEntry->usPrevBridgePtr ); + + pTempBridgeEntry->usNextBridgePtr = pBridgeEntry->usNextBridgePtr; + } + + if ( pBridgeEntry->usNextBridgePtr != cOCT6100_INVALID_INDEX ) + { + /* There is a valid entry after this bridge, let's update this entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, pBridgeEntry->usNextBridgePtr ); + + pTempBridgeEntry->usPrevBridgePtr = pBridgeEntry->usPrevBridgePtr; + } + + if ( pSharedInfo->MiscVars.usFirstBridge == f_usBridgeIndex ) + { + /* This entry was the first of the list, make the next one be the first now. */ + pSharedInfo->MiscVars.usFirstBridge = pBridgeEntry->usNextBridgePtr; + } + } + else + { + /* Variable has become out of sync. */ + return cOCT6100_ERR_FATAL_25; + } + + /*=============================================================*/ + /* Update the conference bridge's list entry. */ + + /* Mark the bridge as closed. */ + pBridgeEntry->fFlexibleConferencing = FALSE; + pBridgeEntry->fReserved = FALSE; + pBridgeEntry->byEntryOpenCnt++; + + /* Decrement the number of conference bridges opened. */ + pSharedInfo->MiscVars.usNumBridgesOpened--; + pSharedInfo->ChipStats.usNumberConfBridges--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanAddSer + +Description: Adds an echo channel (participant) to a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeAdd Pointer to conference bridge channel add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanAddSer +UINT32 Oct6100ConfBridgeChanAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + UINT16 usBridgeIndex; + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT16 usCopyEventIndex; + UINT32 ulInputPort; + UINT8 fFlexibleConfBridge; + UINT32 ulListenerMaskIndex; + UINT32 ulListenerMask; + UINT16 usTapChanIndex; + UINT16 usTapBridgeIndex; + UINT8 fMute; + UINT8 fTap; + UINT32 ulResult; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeAddParams( + f_pApiInstance, + f_pConfBridgeAdd, + &usBridgeIndex, + &usChanIndex, + &fMute, + &ulInputPort, + &fFlexibleConfBridge, + &ulListenerMaskIndex, + &ulListenerMask, + &fTap, + &usTapChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiReserveBridgeAddResources( + f_pApiInstance, + usBridgeIndex, + usChanIndex, + ulInputPort, + fFlexibleConfBridge, + ulListenerMaskIndex, + ulListenerMask, + fTap, + &usLoadEventIndex, + &usSubStoreEventIndex, + &usCopyEventIndex, + &usTapBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiBridgeEventAdd( + f_pApiInstance, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex, + ulInputPort, + fMute, + ulListenerMaskIndex, + ulListenerMask, + fTap, + usTapBridgeIndex, + usTapChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeAddParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeAdd Pointer to conference bridge channenl add structure. +f_pusBridgeIndex Extracted bridge index where this channel should be + added. +f_pusChannelIndex Extracted channel index related to the channel handle + to be added to the bridge. +f_pfMute Whether to mute this channel in the bridge or not. +f_pulInputPort Input port where the channel signal should be + copied from. +f_pfFlexibleConfBridge If this is a flexible conference bridge. +f_pulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_pulListenerMask Mask of listeners in this flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeAddParams +UINT32 Oct6100ApiCheckBridgeAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfMute, + OUT PUINT32 f_pulInputPort, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT32 f_pulListenerMaskIndex, + OUT PUINT32 f_pulListenerMask, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusTapChannelIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + UINT8 byTapChannelLaw; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 1 && + f_pApiInstance->pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeAdd->ulConfBridgeHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + if ( f_pConfBridgeAdd->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + if( f_pConfBridgeAdd->ulInputPort != cOCT6100_CHANNEL_PORT_SOUT + && f_pConfBridgeAdd->ulInputPort != cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_INPUT_PORT; + + if ( f_pConfBridgeAdd->fMute != TRUE && f_pConfBridgeAdd->fMute != FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MUTE; + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( (f_pConfBridgeAdd->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeAdd->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* When we a flexible conference bridge, more things need to be checked. */ + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + { + /* Check if flexible conferencing has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_DISABLED; + + /* Check the number of clients on the bridge. */ + if ( pBridgeEntry->usNumClients >= cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_PARTICIPANT_CNT; + + /* Check if the listener index in a flexible bridge is valid. */ + if ( f_pConfBridgeAdd->ulListenerMaskIndex == cOCT6100_INVALID_VALUE + || f_pConfBridgeAdd->ulListenerMaskIndex >= cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_MASK_INDEX; + } + + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_TAP_NOT_SUPPORTED; + } + + /*=====================================================================*/ + + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pConfBridgeAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + if ( pEchoChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ALREADY_ON_BRIDGE; + if ( pEchoChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_BIDIR; + /* Law conversion is not allowed on a conference bridge. */ + if ( ( pEchoChanEntry->TdmConfig.usRinTimeslot != cOCT6100_UNASSIGNED ) + && ( pEchoChanEntry->TdmConfig.usRoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + if ( pEchoChanEntry->TdmConfig.byRinPcmLaw != pEchoChanEntry->TdmConfig.byRoutPcmLaw ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION; + } + if ( ( pEchoChanEntry->TdmConfig.usSinTimeslot != cOCT6100_UNASSIGNED ) + && ( pEchoChanEntry->TdmConfig.usSoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + if ( pEchoChanEntry->TdmConfig.bySinPcmLaw != pEchoChanEntry->TdmConfig.bySoutPcmLaw ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION; + } + if ( pEchoChanEntry->fRinRoutCodecActive == TRUE || pEchoChanEntry->fSinSoutCodecActive == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_CODEC_ACTIVE; + if ( pEchoChanEntry->fEnableExtToneDetection == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_EXT_TONE_ENABLED; + if ( pEchoChanEntry->usCopyEventCnt != 0x0 ) + return cOCT6100_ERR_CONF_BRIDGE_COPY_EVENTS; + + /* If the bridge is flexible, few more things need to be checked. */ + if ( pBridgeEntry->fFlexibleConferencing == TRUE ) + { + tPOCT6100_SHARED_INFO pSharedInfo; + UINT16 usChannelIndex; + UINT32 ulResult = cOCT6100_ERR_OK; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if the listener index has been used by another channel in the specified bridge. */ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != ( *f_pusChannelIndex ) ) && ( pEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pEchoChanEntry->usBridgeIndex == ( *f_pusBridgeIndex ) ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant has the same listener index. */ + if ( f_pConfBridgeAdd->ulListenerMaskIndex == pCurrentParticipant->ulListenerMaskIndex ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_INDEX_USED; + } + } + } + } + + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + /* For internal logic, make sure the mute flag is set to false. */ + f_pConfBridgeAdd->fMute = FALSE; + + /* Force input port to Sout for logic below. */ + f_pConfBridgeAdd->ulInputPort = cOCT6100_CHANNEL_PORT_SOUT; + + /* Keep law to check for conversion. */ + /* Check if the same law. */ + byTapChannelLaw = pEchoChanEntry->TdmConfig.bySoutPcmLaw; + + /* Check the tap handle. */ + if ( (f_pConfBridgeAdd->ulTappedChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + + *f_pusTapChannelIndex = (UINT16)( f_pConfBridgeAdd->ulTappedChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusTapChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusTapChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeAdd->ulTappedChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE; + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_BRIDGE; + if ( pEchoChanEntry->usBridgeIndex != *f_pusBridgeIndex ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_SAME_BRIDGE; + + /* We can only tap a channel added on the Sout port. */ + if ( pEchoChanEntry->usSinCopyEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_TAP_SOUT_ONLY; + + /* Check if already tapped. */ + if ( pEchoChanEntry->fBeingTapped == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_ALREADY_TAPPED; + } + + /*=====================================================================*/ + + /* Return the tap flag. */ + if ( f_pConfBridgeAdd->ulTappedChannelHndl != cOCT6100_INVALID_HANDLE ) + { + *f_pfTap = TRUE; + } + else + { + *f_pfTap = FALSE; + } + + /* Return the mute config specified. */ + *f_pfMute = (UINT8)( f_pConfBridgeAdd->fMute & 0xFF ); + + /* Return the input port specified. */ + *f_pulInputPort = f_pConfBridgeAdd->ulInputPort; + + /* Return whether we are in the flexible conference bridge case. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + /* Return the listener mask index as specified. */ + *f_pulListenerMaskIndex = f_pConfBridgeAdd->ulListenerMaskIndex; + + /* Return the listener mask as specified. */ + *f_pulListenerMask = f_pConfBridgeAdd->ulListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeAddResources + +Description: Reserves all resources needed for the addition of a channel to + the conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index of the bridge where this channel is added. +f_usChanIndex Channel index of the channel to be added to the bridge. +f_ulInputPort Input port where to copy samples from. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_ulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_ulListenerMask Mask of listeners in this flexible conference bridge. +f_pusLoadEventIndex Load event index within the API's list of mixer event. +f_pusSubStoreEventIndex Sub-Store event index within the API's list of mixer event. +f_pusCopyEventIndex Copy event index within the API's list of mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeAddResources +UINT32 Oct6100ApiReserveBridgeAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fFlexibleConfBridge, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex, + OUT PUINT16 f_pusTapBridgeIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT32 ulResult; + UINT32 ulTempVar; + UINT16 usChannelIndex; + BOOL fLoadEventReserved = FALSE; + BOOL fStoreEventReserved = FALSE; + BOOL fCopyEventReserved = FALSE; + BOOL fExtraSinTsiReserved = FALSE; + BOOL fExtraRinTsiReserved = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Resources must be reserved according to the type of bridge we are adding to. */ + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pNewParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + /*========================================================================*/ + /* If we are in the flexible conferencing case, things are a little */ + /* different. We create a mixer for every participant instead of the */ + /* usual same mixer for everyone. For example, if we have 3 participants */ + /* of type client - agent - coach, we build the mixers as follows: */ + /* */ + /* Client: - Load Agent */ + /* - Store */ + /* */ + /* Agent: - Load Client */ + /* - Accumulate Coach */ + /* - Store */ + /* */ + /* Coach: - Load Client */ + /* - Accumulate Agent */ + /* - Store */ + /* */ + /*========================================================================*/ + + /* First reserve a flexible conferencing participant entry. */ + ulResult = Oct6100ApiReserveFlexConfParticipantEntry( f_pApiInstance, &pChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pNewParticipant, pChanEntry->usFlexConfParticipantIndex ); + + /* Reserve an entry for the store event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusSubStoreEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* If using the SOUT port, we must copy this entry */ + if( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + /* Reserve an entry for the copy event in the Mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fCopyEventReserved = TRUE; + + /* Reserve a SIN copy entry if none were reserved before.*/ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtraSinTsiReserved = TRUE; + } + } + } + else /* if( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + /* Reserve a RIN copy entry if none were reserved before.*/ + if ( pChanEntry->usExtraRinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtraRinTsiReserved = TRUE; + } + } + + /* Must travel all clients of this conference and reserve a load or accumulate event for */ + /* all participants which can hear us. */ + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + + /* Check if this participant can hear us. */ + if ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + } + } + } + + /* If an error is returned, make sure everything is cleaned up properly. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the flexible conferencing participant entry. */ + ulTempVar = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pChanEntry->usFlexConfParticipantIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + + /* Release the substore event in the mixer memory. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusSubStoreEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + if ( fCopyEventReserved == TRUE ) + { + /* Release the copy event in the mixer memory. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fExtraSinTsiReserved == TRUE ) + { + /* Release the extra Sin TSI in TSI memory. */ + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraSinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( fExtraRinTsiReserved == TRUE ) + { + /* Release the extra Rin TSI in TSI memory. */ + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraRinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /* Check this participant can hear us. */ + if ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + return ulResult; + } + } + else /* if ( ulResult != cOCT6100_ERR_OK ) */ + { + ulTempVar = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pChanEntry->usFlexConfParticipantIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + + /* Return the error code to the user. The mixer event allocation failed. */ + return ulResult; + } + + /*=======================================================================*/ + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + /*=======================================================================*/ + /* Normal conferencing. */ + + /* Reserve an entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusLoadEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fLoadEventReserved = TRUE; + /* Reserve an entry for the substract and store event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusSubStoreEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fStoreEventReserved = TRUE; + + /* If using the SOUT port, we must copy this entry */ + if( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + /* Reserve an entry for the copy event in the mixer memory. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, f_pusCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fCopyEventReserved = TRUE; + + /* Reserve a SIN copy entry if none were reserved before. */ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve an entry for the extra tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &pChanEntry->usExtraSinTsiMemIndex ); + + if ( ulResult == cOCT6100_ERR_OK ) + fExtraSinTsiReserved = TRUE; + } + } + } + } + } + + if ( ( ulResult == cOCT6100_ERR_OK ) && ( f_fTap == TRUE ) ) + { + /* Reserve a "tap" bridge. */ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulTapBridgeHndl = 0; + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + + ConfBridgeOpen.pulConfBridgeHndl = &ulTapBridgeHndl; + + ulResult = Oct6100ConfBridgeOpenSer( f_pApiInstance, &ConfBridgeOpen ); + + *f_pusTapBridgeIndex = (UINT16)( ulTapBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( fLoadEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusLoadEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fStoreEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusSubStoreEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fCopyEventReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, *f_pusCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fExtraSinTsiReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtraSinTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + return ulResult; + } + + /*=======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeEventAdd + +Description: Add the event into the global event list of the chip and update + the bridge and channel structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. +f_usBridgeIndex Index of the current bridge in the API list. +f_usChanIndex Index of the current channel in the API list. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Allocated entry for the Load event of the + channel. +f_usSubStoreEventIndex Allocated entry for the substract and store + event of the channel. +f_usCopyEventIndex Allocated entry for the copy event of the + channel. +f_ulInputPort Input port where to copy samples from. +f_fMute Mute flag indicating if the channel is added in + a mute state. +f_ulListenerMaskIndex Index of the listener in this flexible conference bridge. +f_ulListenerMask Mask of listeners in this flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeEventAdd +UINT32 Oct6100ApiBridgeEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fMute, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + IN UINT16 f_usTapBridgeIndex, + IN UINT16 f_usTapChanIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CHANNEL pTapEchoChanEntry = NULL; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT16 usChannelIndex; + UINT16 usLastSubStoreEventIndex; + UINT16 usLastLoadEventIndex; + + BOOL fAddSinCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get the bridge and channel entries of interest. */ + if ( f_fTap == FALSE ) + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + } + else + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usTapBridgeIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTapEchoChanEntry, f_usTapChanIndex ); + } + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pNewParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pCurrentParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pNewParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pCurrentParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( pTempEchoChanEntry->fMute == FALSE ) && ( ( f_ulListenerMask & ( 0x1 << pCurrentParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* First create/update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + pNewParticipant->ausLoadOrAccumulateEventIndex[ pCurrentParticipant->ulListenerMaskIndex ], + f_usSubStoreEventIndex, + f_usCopyEventIndex, + pCurrentParticipant->ulInputPort, + f_ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( f_fMute == FALSE ) && ( ( pCurrentParticipant->ulListenerMask & ( 0x1 << f_ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* Then create/update this channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + f_usChanIndex, + usChannelIndex, + pCurrentParticipant->ausLoadOrAccumulateEventIndex[ f_ulListenerMaskIndex ], + pTempEchoChanEntry->usSubStoreEventIndex, + pTempEchoChanEntry->usSinCopyEventIndex, + f_ulInputPort, + pCurrentParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( ( pCurrentParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pTempEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pTempEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + /* Check if the mixer for the destination channel has been created. */ + if ( pNewParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Save store event index that might be used for next channel added. */ + pEchoChanEntry->usSubStoreEventIndex = f_usSubStoreEventIndex; + } + else + { + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( pEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + + pNewParticipant->ulListenerMaskIndex = f_ulListenerMaskIndex; + pNewParticipant->ulListenerMask = f_ulListenerMask; + + /* Remember this channel's input port. */ + pNewParticipant->ulInputPort = f_ulInputPort; + + /*=======================================================================*/ + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( f_fTap == FALSE ) ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usExtraSinTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + if ( ( f_fMute == FALSE ) || ( f_fTap == TRUE ) ) + { + if ( pBridgeEntry->usLoadIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + if ( f_fTap == TRUE ) + return cOCT6100_ERR_FATAL_D1; + } + else /* pBridgeEntry->usLoadIndex == cOCT6100_INVALID_INDEX */ + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Modify the bridge entry to show store the new load index.*/ + pBridgeEntry->usLoadIndex = f_usLoadEventIndex; + + /* Set the event type.*/ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + } + + /* Select the TSI memory index according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( f_fTap == FALSE ) + { + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + UINT16 usTempWriteData; + UINT32 ulTempWriteAddress; + + /* Save temp write data before trying to clear the Rin TSST. */ + usTempWriteData = WriteParams.usWriteData; + ulTempWriteAddress = WriteParams.ulWriteAddress; + + /* Clear the Rin TSST if used. */ + if ( pTapEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pTapEchoChanEntry->usRinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Reassign write data that might have been cleared by write above. */ + WriteParams.usWriteData = usTempWriteData; + WriteParams.ulWriteAddress = ulTempWriteAddress; + WriteParams.usWriteData |= pTapEchoChanEntry->usRinRoutTsiMemIndex; + + /* Remember that this channel is being tapped by us. */ + pTapEchoChanEntry->fBeingTapped = TRUE; + pTapEchoChanEntry->usTapChanIndex = f_usChanIndex; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pTempBridgeEntry, f_usBridgeIndex ); + + pTempBridgeEntry->usNumTappedClients++; + } + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + } + else /* f_fMute == TRUE */ + { + /* Do not load the sample if the channel is muted. */ + if ( pBridgeEntry->usNumClients == 0 ) + { + /* If the participant to be added is muted, and it would cause the conference to */ + /* be completely muted, load the silence TSI. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + /* We know for sure that the load of the bridge will be the silence one. */ + pBridgeEntry->usSilenceLoadEventPtr = f_usLoadEventIndex; + } + else + { + /* Do nothing! */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + if ( ( f_fMute == FALSE ) && ( f_fTap == FALSE ) ) + { + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + /* Select the TSI memory index and PCM law according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + /* Set the event type. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + } + else /* f_fMute == TRUE */ + { + /* Do not substore the sample if the channel is muted. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Select the PCM law according to the source port. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + /* Set the event type. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the Copy event - if using the SOUT port */ + if ( ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( f_fTap == FALSE ) ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pEchoChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set add copy event flag. */ + fAddSinCopy = TRUE; + + /* For sure. */ + pEchoChanEntry->fCopyEventCreated = TRUE; + } + else if ( f_fTap == TRUE ) + { + /* Accumulate the tapped channel's voice instead of building a copy event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + WriteParams.usWriteData |= pTapEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Link to next operation. */ + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = f_usSubStoreEventIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, f_usCopyEventIndex ); + + pTempEntry->usSourceChanIndex = f_usTapChanIndex; + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + pTempEntry->usNextEventPtr = f_usSubStoreEventIndex; + pTempEntry->usDestinationChanIndex = cOCT6100_INVALID_INDEX; + pTempEntry->fReserved = TRUE; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* Now insert the event into the list.*/ + if ( pBridgeEntry->usNumClients == 0 ) + { + /* This is the first entry for this bridge. Insert the two events at the head + of the list just after the last sub-store event.*/ + if ( f_fTap == FALSE ) + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usLastSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_26; + } + } + } + else + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + + /* An Entry was found, now, modify it's value.*/ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /* Set the Sub-Store event first.*/ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + pSubStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Program the Sub-Store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = (UINT16)( pSubStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the load/accumulate event now.*/ + if ( f_fTap == FALSE ) + { + pLoadEventEntry->usNextEventPtr = f_usSubStoreEventIndex; + } + else + { + /* This is a little tricky, we use the copy event index for accumulating the tapped channel's voice. */ + pLoadEventEntry->usNextEventPtr = f_usCopyEventIndex; + } + + /*=======================================================================*/ + /* Program the load/accumulate event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = f_usLoadEventIndex; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = f_usLoadEventIndex; + pBridgeEntry->usFirstSubStoreEventPtr = f_usSubStoreEventIndex; + pBridgeEntry->usLastSubStoreEventPtr = f_usSubStoreEventIndex; + + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This bridge is the first to generate mixer event. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadEventIndex; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* The two entries were added at the end of the bridge section, */ + /* change only the last pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + else if ( usLastSubStoreEventIndex == cOCT6100_MIXER_HEAD_NODE || + usLastSubStoreEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* The two entries were added at the start of the bridge section, */ + /* change only the first pointer. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadEventIndex; + } + } + else /* pBridgeEntry->usNumClients != 0 */ + { + /* For sanity. */ + if ( f_fTap == TRUE ) + return cOCT6100_ERR_FATAL_D2; + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Now find the last load entry of this bridge. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, pBridgeEntry->usFirstSubStoreEventPtr, 0, &usLastLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Add the load/accumulate event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastLoadEventIndex ); + + /* Set the load event now. */ + pLoadEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the previous last load event. */ + + /* Now modify the previous last load event. */ + pTempEntry->usNextEventPtr = f_usLoadEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the Sub-Store event. */ + + usLastSubStoreEventIndex = pBridgeEntry->usLastSubStoreEventPtr; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /* Set the Sub-Store event first. */ + pSubStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pSubStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the previous last sub store event of the bridge. */ + + /* Now modify the last Load event of the bridge. */ + pTempEntry->usNextEventPtr = f_usSubStoreEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Update the bridge pointers. */ + pBridgeEntry->usLastSubStoreEventPtr = f_usSubStoreEventIndex; + + /* Check if modification to the global mixer pointer are required. */ + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* We have a new last bridge pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usSubStoreEventIndex; + } + } + + if ( f_fTap == TRUE ) + { + if ( pEchoChanEntry->usRinTsstIndex == cOCT6100_INVALID_INDEX ) + { + /* Remove the mute on the Rin port. */ + + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usChanIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Configure the level control. */ + + UINT32 ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.usDwordOffset * 4; + UINT32 ulFeatureBitOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.byBitOffset; + UINT32 ulFeatureFieldLength = pSharedInfo->MemoryMap.RinLevelControlOfst.byFieldSize; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the DC filter to pass through.*/ + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the event entries as reserved. */ + pLoadEventEntry->fReserved = TRUE; + pSubStoreEventEntry->fReserved = TRUE; + + /* Store the event indexes into the channel structure. */ + pEchoChanEntry->usLoadEventIndex = f_usLoadEventIndex; + pEchoChanEntry->usSubStoreEventIndex = f_usSubStoreEventIndex; + + /* Check if must insert the Sin copy event in the list. */ + if ( fAddSinCopy == TRUE ) + { + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usChanIndex ); + } + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( ( f_fTap == FALSE ) && ( pEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + + /* Configure the RIN copy mixer entry and memory - if using the RIN port. */ + if ( ( f_fFlexibleConfBridge == TRUE ) && ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + if ( pEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usExtraRinTsiMemIndex, + pEchoChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if ( pBridgeEntry->fDominantSpeakerSet == TRUE ) + { + /* Dominant speaker is another channel. Set accordingly for this new conference channel. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, pBridgeEntry->usDominantSpeakerChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* No dominant speaker set on this bridge yet. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Update the bridge entry. */ + pBridgeEntry->usNumClients++; + + /* Store the bridge index into the channel structure. */ + pEchoChanEntry->usBridgeIndex = f_usBridgeIndex; + + /* Store the copy event index into the channel structure. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pEchoChanEntry->usSinCopyEventIndex = f_usCopyEventIndex; + } + else + { + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Remember if the channel is muted in the conference. */ + pEchoChanEntry->fMute = f_fMute; + + /* Remember if the channel is a tap in a conference. */ + pEchoChanEntry->fTap = f_fTap; + + /* We start by not being tapped. */ + pEchoChanEntry->fBeingTapped = FALSE; + pEchoChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + + /* Remember the tap bridge index if necessary. */ + if ( pEchoChanEntry->fTap == TRUE ) + { + pEchoChanEntry->usTapBridgeIndex = f_usTapBridgeIndex; + } + else + { + pEchoChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + } + + /* Indicate that the extra SIN TSI is currently in used by the conference bridge. */ + if ( f_ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt++; + } + + /* Indicate that the extra RIN TSI is currently in used by the conference bridge. */ + if ( ( f_fFlexibleConfBridge == TRUE ) && ( f_ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt++; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeAddParticipantToChannel + +Description: Used for the flexible conference bridges. Insert a participant + onto a channel that is on a conference. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index where this channel is located. +f_usSourceChannelIndex Source channel to copy voice from. +f_usDestinationChannelIndex Destination channel to store resulting voice to. +f_usLoadOrAccumulateEventIndex Load or Accumulate allocated event index. +f_usStoreEventIndex Store allocated event index. +f_usCopyEventIndex Copy allocated event index. +f_ulSourceInputPort Source input port of the conference for this channel. +f_ulDestinationInputPort Destination input port of the conference for this channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeAddParticipantToChannel +UINT32 Oct6100ApiBridgeAddParticipantToChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT16 f_usLoadOrAccumulateEventIndex, + IN UINT16 f_usStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulSourceInputPort, + IN UINT32 f_ulDestinationInputPort ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pSourceChanEntry; + tPOCT6100_API_CHANNEL pDestinationChanEntry; + + tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT16 usLastSubStoreEventIndex; + UINT16 usLastLoadEventIndex; + BOOL fInsertCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex ); + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadOrAccumulateEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pStoreEventEntry, f_usStoreEventIndex ); + + /* Check if we are creating the first event for this channel. */ + if ( pDestinationParticipant->fFlexibleMixerCreated == FALSE ) + { + /*=======================================================================*/ + /* Before creating the participant's flexible mixer, make sure the extra Sin */ + /* mixer event is programmed correctly for sending the voice stream to the right place. */ + + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( pDestinationChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usSinTsstIndex, + pDestinationChanEntry->usExtraSinTsiMemIndex, + pDestinationChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pDestinationChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Program the load event. This is the first event for this new destination channel. */ + + /* First set the TSI buffer where the resulting stream should be written to. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* For sure, we are loading. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Select the TSI memory index according to the source port. */ + if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pSourceChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pSourceChanEntry->usExtraRinTsiMemIndex; + } + + /* Set the event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Set the source channel index. */ + pLoadEventEntry->usSourceChanIndex = f_usSourceChannelIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Program the store event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Select the TSI memory index and PCM law according to the source port. */ + if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pDestinationChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pDestinationChanEntry->usRinRoutTsiMemIndex; + } + + /* Set the event type. */ + pStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* Set the destination channel index. */ + pStoreEventEntry->usDestinationChanIndex = f_usDestinationChannelIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Program the Copy event - if using the SOUT port */ + + if ( ( f_ulDestinationInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pDestinationChanEntry->fCopyEventCreated == FALSE ) ) + { + /* The copy event has not been created, create it once for the life of the participant on the bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pDestinationChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pDestinationChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pDestinationChanEntry->fCopyEventCreated = TRUE; + + /* Set insert copy flag. */ + fInsertCopy = TRUE; + } + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Now, insert the events into the current list. */ + /*=======================================================================*/ + /*=======================================================================*/ + + /* This is the first entry for this channel. Insert the two events at the head */ + /* of the list just after the last Sub-Store or Store event. */ + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, f_usLoadOrAccumulateEventIndex, &usLastSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usLastSubStoreEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usLastSubStoreEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_26; + } + } + + /* An entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastSubStoreEventIndex ); + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Link the store event first. */ + + pStoreEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + /* Link the store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = (UINT16)( pStoreEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Link the load event now.*/ + + pLoadEventEntry->usNextEventPtr = f_usStoreEventIndex; + + /* Link the load event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now modify the previous last Sub-Store or Store event from another bridge, */ + /* such that it links to us. */ + + pTempEntry->usNextEventPtr = f_usLoadOrAccumulateEventIndex; + + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Set the event pointer info in the bridge stucture. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == cOCT6100_INVALID_INDEX ) + { + /* We only do this once in case of the flexible conference bridges. */ + pBridgeEntry->usFirstLoadEventPtr = f_usLoadOrAccumulateEventIndex; + pBridgeEntry->usFirstSubStoreEventPtr = f_usStoreEventIndex; + } + + pBridgeEntry->usLastSubStoreEventPtr = f_usStoreEventIndex; + + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This bridge is the first to generate mixer event. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadOrAccumulateEventIndex; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usStoreEventIndex; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == usLastSubStoreEventIndex ) + { + /* The two entries were added at the end of the bridge section, */ + /* change only the last pointer. */ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = f_usStoreEventIndex; + } + else if ( usLastSubStoreEventIndex == cOCT6100_MIXER_HEAD_NODE || + usLastSubStoreEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* The two entries were added at the start of the bridge section, */ + /* change only the first pointer.*/ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = f_usLoadOrAccumulateEventIndex; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Insert the copy event if needed in the mixer's list. */ + + if ( fInsertCopy == TRUE ) + { + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usDestinationChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the status of the instance structures. */ + + pDestinationParticipant->fFlexibleMixerCreated = TRUE; + + /* Set the event entries as reserved. */ + pLoadEventEntry->fReserved = TRUE; + pStoreEventEntry->fReserved = TRUE; + + /* Store the event indexes into the channel structure. */ + pDestinationChanEntry->usLoadEventIndex = f_usLoadOrAccumulateEventIndex; + pDestinationChanEntry->usSubStoreEventIndex = f_usStoreEventIndex; + + /*=======================================================================*/ + } + else /* if ( pDestinationChanEntry->fFlexibleMixerCreated == TRUE ) */ + { + /*=======================================================================*/ + /* Program the Accumulate event. */ + + /* First set the TSI buffer where the resulting stream should be written to. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* For sure, we are accumulating. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + + /* Select the TSI memory index according to the source port. */ + if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + WriteParams.usWriteData |= pSourceChanEntry->usSinSoutTsiMemIndex; + } + else /* if ( f_ulSourceInputPort == cOCT6100_CHANNEL_PORT_RIN ) */ + { + WriteParams.usWriteData |= pSourceChanEntry->usExtraRinTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Now, insert the Accumulate event into the current list. */ + /*=======================================================================*/ + /*=======================================================================*/ + + /* Use the Load entry of this channel. */ + usLastLoadEventIndex = pDestinationChanEntry->usLoadEventIndex; + + /* Add the Accumulate event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usLastLoadEventIndex ); + + /* Set the accumulate event now. */ + pLoadEventEntry->usNextEventPtr = pTempEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadOrAccumulateEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pLoadEventEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Modify the previous Load event. */ + + /* Now modify the previous Load event. */ + pTempEntry->usNextEventPtr = f_usLoadOrAccumulateEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + + /*=======================================================================*/ + /* Update the status of the instance structures. */ + + /* Set the Accumulate event entry as reserved. */ + pLoadEventEntry->fReserved = TRUE; + /* Set the Event type. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + /* Set the source channel index. */ + pLoadEventEntry->usSourceChanIndex = f_usSourceChannelIndex; + + /*=======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanRemoveSer + +Description: Removes an echo channel from a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeRemove Pointer to conference bridge channel remove structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanRemoveSer +UINT32 Oct6100ConfBridgeChanRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + UINT16 usBridgeIndex; + UINT16 usChanIndex = 0; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT16 usCopyEventIndex; + UINT32 ulResult; + UINT8 fFlexibleConfBridge; + UINT8 fTap; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckChanRemoveParams( + f_pApiInstance, + f_pConfBridgeRemove, + &usBridgeIndex, + &usChanIndex, + &fFlexibleConfBridge, + &fTap, + &usLoadEventIndex, + &usSubStoreEventIndex, + &usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources reserved for the conference bridge. */ + ulResult = Oct6100ApiReleaseChanEventResources( + f_pApiInstance, + f_pConfBridgeRemove, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the memory entry for this channel within the bridge. */ + ulResult = Oct6100ApiBridgeEventRemove( + f_pApiInstance, + f_pConfBridgeRemove, + usBridgeIndex, + usChanIndex, + fFlexibleConfBridge, + usLoadEventIndex, + usSubStoreEventIndex, + usCopyEventIndex, + fTap ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChanRemoveParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to conference bridge channenl add structure. +f_pusBridgeIndex Pointer to the bridge index. +f_pfFlexibleConfBridge If this is a flexible conference bridge +f_pusChannelIndex Pointer to the channel index to be added to the bridge. +f_pusLoadEventIndex Pointer to the load mixer event. +f_pusSubStoreEventIndex Pointer to the sub-store mixer event. +f_pusCopyEventIndex Pointer to the copy mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChanRemoveParams +UINT32 Oct6100ApiCheckChanRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex ) +{ + UINT32 ulEntryOpenCnt; + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + /* Verify if the remove all flag is valid. */ + if ( f_pConfBridgeRemove->fRemoveAll != TRUE && + f_pConfBridgeRemove->fRemoveAll != FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_ALL; + + /* Check the channel handle only if the remove all flag is set to FALSE. */ + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pConfBridgeRemove->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeRemove->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeRemove->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + if ( pEchoChanEntry->fBeingTapped == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY; + + /*=====================================================================*/ + + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusCopyEventIndex = pEchoChanEntry->usSinCopyEventIndex; + + /* Check if the channel is really part of the bridge. */ + if ( *f_pusBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Return whether this is a flexible bridge or not. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + /* Return whether this is a tap or not. */ + *f_pfTap = pEchoChanEntry->fTap; + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + /* Check the provided handle. */ + if ( (f_pConfBridgeRemove->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeRemove->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeRemove->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* This information is not currently available. */ + *f_pusLoadEventIndex = cOCT6100_INVALID_INDEX; + *f_pusSubStoreEventIndex = cOCT6100_INVALID_INDEX; + *f_pusCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Return whether this is a flexible bridge or not. */ + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + *f_pfTap = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseChanEventResources + +Description: Release all resources reserved to the channel part of the + conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to conference bridge channel add structure. +f_usBridgeIndex Index of the bridge structure within the API's bridge list. +f_usChanIndex Index of the channel structure within the API's channel list +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Index of the load mixer event. +f_usSubStoreEventIndex Index of the sub-store mixer event. +f_usCopyEventIndex Index of the copy mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseChanEventResources +UINT32 Oct6100ApiReleaseChanEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Release an entry for the store event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Sout port was used - no need to release. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* Must travel all clients of this conference and release the load or accumulate events for */ + /* all participants which can hear us and vice versa. */ + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( i = 0; ( i < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ); i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, i ); + + /* Channel reserved? */ + if ( ( i != f_usChanIndex ) && pTempEchoChanEntry->fReserved == TRUE ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + + /* Check if this participant can hear us. */ + if ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + UINT32 ulListenerMaskIndex; + + ulResult = cOCT6100_ERR_OK; + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( i = 0; ( i < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ); i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + /* Channel reserved? */ + if ( pEchoChanEntry->fReserved == TRUE ) + { + /* On current bridge? */ + if ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Release an entry for the Store event in the Mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Sout port was used - no need to release. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraRinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* Check if something can be freed. */ + for ( ulListenerMaskIndex = 0; ulListenerMaskIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulListenerMaskIndex ++ ) + { + if ( pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the allocated mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + pParticipant->ausLoadOrAccumulateEventIndex[ ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + /* Release the entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the substract and store event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry. */ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + } + else /* f_pConfBridgeRemove->fRemoveAll == TRUE */ + { + /* Search through the list of API channel entry for the ones on to the specified bridge.*/ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + /* Release the entry for the load event in the mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usLoadEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the substract and store event in the Mixer memory. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usSubStoreEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Release an entry for the Sin copy event in the Mixer memory. */ + /* This value can be invalid if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + pEchoChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + + /* This value can be 0 if the Rin port was used - no need to release. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the extra TSI entry.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pEchoChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + } + } + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeEventRemove + +Description: Remove the event from the global event list of the chip and + update the bridge and channel structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeRemove Pointer to a conference bridge channel remove structure. +f_usBridgeIndex Index of the current bridge in the API list. +f_usChanIndex Index of the current channel in the API list. +f_fFlexibleConfBridge If this is a flexible conference bridge. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_usCopyEventIndex Allocated entry for the copy event of the channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeEventRemove +UINT32 Oct6100ApiBridgeEventRemove ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT8 f_fTap ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pCopyEventEntry = NULL; + tPOCT6100_API_MIXER_EVENT pTempEntry; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT16 usPreviousEventIndex; + UINT16 usTempEventIndex; + UINT32 ulLoopCount = 0; + UINT16 usReadData; + UINT16 usChannelIndex; + UINT32 i; + + BOOL fRemoveSinCopy = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + /* If no client on the bridge, and the remove all option is specified, return here. */ + if ( ( pBridgeEntry->usNumClients == 0 ) && ( f_pConfBridgeRemove->fRemoveAll == TRUE ) ) + return cOCT6100_ERR_OK; + + /* Make sure the dominant speaker feature is disabled first. */ + if ( pBridgeEntry->fDominantSpeakerSet == TRUE ) + { + /* If all channels are to be removed or if the dominant speaker is the current channel to be removed. */ + if ( ( f_pConfBridgeRemove->fRemoveAll == TRUE ) + || ( ( f_pConfBridgeRemove->fRemoveAll == FALSE ) && ( pBridgeEntry->usDominantSpeakerChanIndex == f_usChanIndex ) ) ) + { + /* Disable on all channels part of this conference. */ + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( pTempEchoChanEntry->fReserved == TRUE ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, usChannelIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Save this in the conference bridge structure. */ + pBridgeEntry->fDominantSpeakerSet = FALSE; + pBridgeEntry->usDominantSpeakerChanIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Only disable this current channel. */ + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /* The channel index is valid. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can hear this participant. */ + if ( ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pEchoChanEntry->fMute == FALSE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + f_usChanIndex, + usChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usChannelIndex; + break; + } + } + } + } + } + } + + /* Check if must manually clear the Sin copy event. */ + if ( ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->fCopyEventCreated == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /* Release an entry for the participant. */ + ulResult = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pEchoChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /*=======================================================================*/ + /* Update the event and channel API structure */ + pEchoChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Indicate that the extra RIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt--; + pEchoChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + pBridgeEntry->usNumClients--; + + /* For sure we have to mute the ports of this channel to be removed. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + f_usChanIndex, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + else /* if ( f_pConfBridgeRemove->fRemoveAll == TRUE ) */ + { + UINT16 usMainChannelIndex; + + for ( usMainChannelIndex = 0 ; usMainChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ; usMainChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usMainChannelIndex ); + + /* If this channel is on the bridge we are closing all the channels. */ + if ( ( pEchoChanEntry->fReserved == TRUE ) && ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usMainChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usMainChannelIndex; + break; + } + } + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = (UINT16)( usMainChannelIndex + 1 ); usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + if ( pTempEchoChanEntry->fReserved == TRUE ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Everyone that we can hear must be removed. */ + if ( ( ( pParticipant->ulListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + usMainChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pEchoChanEntry->fMute == FALSE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usMainChannelIndex, + usChannelIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Check if must manually clear the Sin copy event. */ + if ( ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->fCopyEventCreated == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /* Release an entry for the participant. */ + ulResult = Oct6100ApiReleaseFlexConfParticipantEntry( f_pApiInstance, pEchoChanEntry->usFlexConfParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /*=======================================================================*/ + /* Update the event and channel API structure */ + + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Indicate that the Extra RIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraRinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraRinTsiDependencyCnt--; + pEchoChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + + /* Clear the flexible conf bridge participant index. */ + pTempEchoChanEntry->usFlexConfParticipantIndex = cOCT6100_INVALID_INDEX; + } + + /* No more clients on bridge. */ + pBridgeEntry->usNumClients = 0; + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + if ( f_pConfBridgeRemove->fRemoveAll == FALSE ) + { + /* The channel index is valid. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + if ( f_fTap == TRUE ) + { + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pBridgeEntry, pEchoChanEntry->usTapBridgeIndex ); + } + + /* Get a pointer to the event entry. */ + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + + /*=======================================================================*/ + /* Check if have to modify the silence load event. */ + + if ( pBridgeEntry->usNumClients != 1 ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr != cOCT6100_INVALID_INDEX ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == f_usLoadEventIndex ) + { + /* Make sure the next event becomes the silence event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pLoadEventEntry->usNextEventPtr * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model to remember the silence load. */ + pBridgeEntry->usSilenceLoadEventPtr = pLoadEventEntry->usNextEventPtr; + } + else + { + /* Somebody else is the silence event, no need to worry. */ + } + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Load event. */ + + /* First verify if the event to be removed was a load event. */ + if ( f_usLoadEventIndex == pBridgeEntry->usLoadIndex ) + { + /* Change the next entry if one is present to a load event to keep the bridge alive. */ + if ( pBridgeEntry->usNumClients == 1 ) + { + /* There is no other entry on the bridge, no need to search for an Accumulate event. */ + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + /* Clear the silence event, for sure it's invalid. */ + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + /* Search for an accumulate event to tranform into a Load event. */ + usTempEventIndex = pLoadEventEntry->usNextEventPtr; + ulLoopCount = 0; + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set this entry as the load index. */ + pBridgeEntry->usLoadIndex = usTempEventIndex; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Stop searching. */ + break; + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + } + } + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the Copy event - if needed. */ + + if ( f_usCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_fTap == FALSE ) + { + /* Set remove Sin copy event flag to remove the event from the mixer's list. */ + fRemoveSinCopy = TRUE; + + /* Clear the copy event created flag. */ + pEchoChanEntry->fCopyEventCreated = FALSE; + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now remove the event from the event list. */ + + /* Look for the entry that is pointing at the first entry of our bridge. */ + if ( f_fTap == FALSE ) + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + } + else + { + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, pEchoChanEntry->usTapBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + /* If the entry was not found, we now check for the Sout copy event section/list. */ + if ( ulResult == cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* No Sout copy, it has to be the head node. */ + usPreviousEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + /* Use the last Sout copy event. */ + usPreviousEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_27; + } + } + + if ( pBridgeEntry->usNumClients == 1 ) + { + /* An entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the previous bridge to point to the next bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + /* There is no more bridge entry in the mixer link list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pSubStoreEventEntry->usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + if ( f_fTap == TRUE ) + { + /* The channel being tapped is not tapped anymore. */ + /* There is no direct way of finding the tap, so loop through all channels and find the */ + /* tapped channel index. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( pTempEchoChanEntry->usTapChanIndex == f_usChanIndex ) + { + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + + pTempEchoChanEntry->fBeingTapped = FALSE; + pTempEchoChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pTempBridgeEntry, f_usBridgeIndex ); + + pTempBridgeEntry->usNumTappedClients--; + + /* Re-assign Rin TSST for tapped channel. */ + if ( pTempEchoChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usRinRoutTsiMemIndex, + pTempEchoChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + break; + } + } + + /* Check if our model is broken. */ + if ( usChannelIndex == pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_FATAL_D3; + } + } + else /* pBridgeEntry->usNumClients > 1 */ + { + if ( pBridgeEntry->usFirstLoadEventPtr != f_usLoadEventIndex ) + { + /* Now find the load entry of this bridge pointing at this load event */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, f_usLoadEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the load event to the list. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge. */ + pTempEntry->usNextEventPtr = pLoadEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the previous node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now find the last load entry of this bridge ( the one pointing at the first sub-store event ). */ + if ( pBridgeEntry->usFirstSubStoreEventPtr == f_usSubStoreEventIndex ) + { + /* Must start with the first load to get the entry before the first sub store. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstLoadEventPtr, f_usSubStoreEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* Must start with the first load to get the entry before the first sub store. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pBridgeEntry->usFirstSubStoreEventPtr, f_usSubStoreEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /* Now modify the last load event of the bridge. */ + pTempEntry->usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = (UINT16)( pTempEntry->usNextEventPtr ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the bridge pointers. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == f_usLoadEventIndex ) + pBridgeEntry->usFirstLoadEventPtr = pLoadEventEntry->usNextEventPtr; + + if ( pBridgeEntry->usFirstSubStoreEventPtr == f_usSubStoreEventIndex ) + pBridgeEntry->usFirstSubStoreEventPtr = pSubStoreEventEntry->usNextEventPtr; + + if ( pBridgeEntry->usLastSubStoreEventPtr == f_usSubStoreEventIndex ) + pBridgeEntry->usLastSubStoreEventPtr = usPreviousEventIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == f_usLoadEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pLoadEventEntry->usNextEventPtr; + } + + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == f_usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + } + + /* Check if must remove the Sin copy event from the event list. */ + if ( fRemoveSinCopy == TRUE ) + { + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, f_usCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Get the channel. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + + /* Reprogram the TSST entry correctly if the Extra SIN TSI entry was released. */ + if ( ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) && ( f_fTap == FALSE ) ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usSinSoutTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSubStoreEventEntry->fReserved = FALSE; + pSubStoreEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pSubStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pCopyEventEntry != NULL ) + { + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + pBridgeEntry->usNumClients--; + + /*=======================================================================*/ + /* Update the event and channel API structure */ + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + if ( f_fTap == TRUE ) + { + /* Can now close the bridge. */ + tOCT6100_CONF_BRIDGE_CLOSE BridgeClose; + + Oct6100ConfBridgeCloseDef( &BridgeClose ); + + BridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pEchoChanEntry->usTapBridgeIndex; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &BridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->fTap = FALSE; + } + + /* Check if the Rin port must be muted. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + f_usChanIndex, + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + } + else /* f_ulBridgeChanRemove->fRemoveAll == TRUE ) */ + { + UINT16 usNextEventPtr; + + /* Save the next event pointer before invalidating everything. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, pBridgeEntry->usLastSubStoreEventPtr ); + + usNextEventPtr = pSubStoreEventEntry->usNextEventPtr; + + /* Search through the list of API channel entry for the ones on to the specified bridge. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + /* Check if we are being tapped. If so, remove the channel that taps us from the conference. */ + /* The removal of the channel will make sure the Rin TSST is re-assigned. */ + if ( pEchoChanEntry->fBeingTapped == TRUE ) + { + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ChanRemove; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, pEchoChanEntry->usTapChanIndex ); + + ulResult = Oct6100ConfBridgeChanRemoveDef( &ChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pTempEchoChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pEchoChanEntry->usTapChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &ChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* Clear the Load event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Clear the SIN copy event.*/ + + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, pEchoChanEntry->usSinCopyEventIndex ); + + /* Update the next event pointer if required. */ + if ( usNextEventPtr == pEchoChanEntry->usSinCopyEventIndex ) + usNextEventPtr = pCopyEventEntry->usNextEventPtr; + + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pEchoChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the copy event created flag. */ + pEchoChanEntry->fCopyEventCreated = FALSE; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the event and channel API structure */ + + /* Reprogram the TSST entry correctly if the Extra SIN TSI entry was released.*/ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + if ( pEchoChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pEchoChanEntry->usSinTsstIndex, + pEchoChanEntry->usSinSoutTsiMemIndex, + pEchoChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original Sin TSI. */ + if ( pEchoChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, pEchoChanEntry->usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, pEchoChanEntry->usSubStoreEventIndex ); + + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSubStoreEventEntry->fReserved = FALSE; + pSubStoreEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pSubStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pCopyEventEntry != NULL ) + { + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + /* Indicate that the Extra SIN TSI is not needed anymore by the mixer. */ + if ( pEchoChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + pEchoChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Decrement the dependency count, but do not clear the mem index. */ + pEchoChanEntry->usExtraSinTsiDependencyCnt--; + } + + /* Invalidate the channel entry. */ + pEchoChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + pEchoChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Update the chip stats structure. */ + pSharedInfo->ChipStats.usNumEcChanUsingMixer--; + + /*=======================================================================*/ + } + } + } + + ulResult = Oct6100ApiGetPrevLastSubStoreEvent( f_pApiInstance, f_usBridgeIndex, pBridgeEntry->usFirstLoadEventPtr, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND == ulResult ) + { + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + usPreviousEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usPreviousEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + return cOCT6100_ERR_FATAL_28; + } + } + + /* An Entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Now modify the previous last Sub Store event from another bridge.*/ + /* It will now point at the next bridge, or copy events. */ + pTempEntry->usNextEventPtr = usNextEventPtr; + + /*=======================================================================*/ + /* Modify the last node of the other bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pTempEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == pBridgeEntry->usFirstLoadEventPtr && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == pBridgeEntry->usLastSubStoreEventPtr ) + { + /* This bridge was the only one with event in the list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == pBridgeEntry->usFirstLoadEventPtr ) + { + /* This bridge was the first bridge. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == pBridgeEntry->usLastSubStoreEventPtr ) + { + /* This bridge was the last bridge.*/ + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + /*=======================================================================*/ + + /* Set the event pointer info in the bridge stucture. */ + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + + /* Set the number of clients to 0. */ + pBridgeEntry->usNumClients = 0; + + /* Search through the list of API channel entry for the ones on to the specified bridge. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, i ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) && ( pEchoChanEntry->fTap == FALSE ) ) + { + pEchoChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + /* Check if the Rin port must be muted. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + (UINT16)( i & 0xFFFF ), + pEchoChanEntry->usRinTsstIndex, + pEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeRemoveParticipantFromChannel + +Description: This will remove a flexible conference participant from + a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index where this channel is located. +f_usSourceChannelIndex Source channel to copy voice from. +f_usDestinationChannelIndex Destination channel to store resulting voice to. +f_fRemovePermanently Whether to remove permanently this participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeRemoveParticipantFromChannel +UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT8 f_fRemovePermanently ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pCopyEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + tPOCT6100_API_MIXER_EVENT pLoadTempEntry; + tPOCT6100_API_MIXER_EVENT pLastEventEntry; + + tPOCT6100_API_CHANNEL pDestinationChanEntry; + + tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant; + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT32 ulLoopCount; + UINT16 usLoadOrAccumulateEventIndex; + UINT16 usTempEventIndex; + UINT16 usPreviousEventIndex; + UINT16 usLastEventIndex; + + UINT16 usReadData; + BOOL fLastEvent = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ); + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex ); + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex ); + + /* Check if the mixer has been created on this channel. */ + if ( pDestinationParticipant->fFlexibleMixerCreated == TRUE ) + { + /*=======================================================================*/ + /* Clear the Load or Accumulate event.*/ + + usTempEventIndex = pDestinationChanEntry->usLoadEventIndex; + ulLoopCount = 0; + + /* Find the Load or Accumulate event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, usTempEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pStoreEventEntry, pDestinationChanEntry->usSubStoreEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + pLastEventEntry = pLoadEventEntry; + usLastEventIndex = usTempEventIndex; + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + /* If this is the entry we are looking for. */ + if ( pTempEntry->usSourceChanIndex == f_usSourceChannelIndex ) + { + /* Check if this is a Load or Accumulate event. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + /* This is the first entry. Check if next entry is an accumulate. */ + pLoadTempEntry = pTempEntry; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, pTempEntry->usNextEventPtr ); + + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a Load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pLoadTempEntry->usNextEventPtr * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel information with this new load event. */ + pDestinationChanEntry->usLoadEventIndex = pLoadTempEntry->usNextEventPtr; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + /* Get back the event to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + /* This is the only event on this channel so we can clear everything up. */ + fLastEvent = TRUE; + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C5; + } + + } + else if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Simply remove the entry. */ + + /* Get the previous event. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usTempEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLastEventEntry, usPreviousEventIndex ); + usLastEventIndex = usPreviousEventIndex; + + /* Stop searching. */ + break; + } + else + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C6; + } + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_C8; + } + + /* Check if we found what we were looking for. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE + || pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_SUB_STORE ) + { + /* Software model is broken. */ + return cOCT6100_ERR_FATAL_C7; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Store event - if needed. */ + + if ( fLastEvent == TRUE ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Load or Accumulate event. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save this event index. It's the Load or Accumulate we want to remove from the list later. */ + usLoadOrAccumulateEventIndex = usTempEventIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the Copy event - if needed. */ + + if ( ( fLastEvent == TRUE ) && ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) && ( f_fRemovePermanently == TRUE ) ) + { + /* Transform event into no-operation. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* The event remove from the list will be done below. */ + + /* Clear the copy event created flag. */ + pDestinationChanEntry->fCopyEventCreated = FALSE; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /*=======================================================================*/ + /* Remove the events from the mixer event list.*/ + /*=======================================================================*/ + /*=======================================================================*/ + + /*=======================================================================*/ + /* Remove the Load or Accumulate event from the event list. */ + + if ( fLastEvent == FALSE ) + { + /*=======================================================================*/ + /* Remove the Accumulate event from the event list. */ + + /* We saved the Load or Accumulate event above. We also saved the previous event. Use those. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, usLoadOrAccumulateEventIndex ); + + /* Now modify the previous last event. */ + pLastEventEntry->usNextEventPtr = pLoadEventEntry->usNextEventPtr; + + /* Modify the previous node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usLastEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pLastEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if this is the first load event on the bridge. */ + if ( pBridgeEntry->usFirstLoadEventPtr == usLoadOrAccumulateEventIndex ) + { + pBridgeEntry->usFirstLoadEventPtr = pLoadEventEntry->usNextEventPtr; + } + + /* Check if this was the first load of all bridges. */ + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pLoadEventEntry->usNextEventPtr; + } + + /*=======================================================================*/ + } + else /* if ( fLastEvent == TRUE ) */ + { + /*=======================================================================*/ + /* Remove the Load event from the event list. */ + + /* Look for the entry that is pointing at the first entry of our mixer. */ + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, cOCT6100_MIXER_HEAD_NODE, usLoadOrAccumulateEventIndex, 0, &usPreviousEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* An Entry was found, now, modify it's value. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousEventIndex ); + + /* Check if this is a Sout copy event. */ + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_COPY ) + { + /* No more previous bridges. */ + } + + /* Now modify the previous last Store or Sub-Store or Head-Node event from another bridge/channel. */ + pTempEntry->usNextEventPtr = pStoreEventEntry->usNextEventPtr; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Modify the last node of the previous bridge/channel to point to the next bridge. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + + WriteParams.usWriteData = pTempEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Set the event pointer info in the bridge stucture. */ + + if ( pBridgeEntry->usFirstLoadEventPtr == pDestinationChanEntry->usLoadEventIndex ) + { + UINT16 usChannelIndex; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + + /* Find the next channel in this conference that could give us valid values. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usDestinationChannelIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + { + pBridgeEntry->usFirstSubStoreEventPtr = pTempEchoChanEntry->usSubStoreEventIndex; + pBridgeEntry->usFirstLoadEventPtr = pTempEchoChanEntry->usLoadEventIndex; + break; + } + } + } + } + } + + /* Reprogram the TSST entry correctly if the extra SIN TSI entry was released. */ + if ( ( pDestinationChanEntry->usExtraSinTsiDependencyCnt == 1 ) && ( f_fRemovePermanently == TRUE ) ) + { + if ( pDestinationChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usSinTsstIndex, + pDestinationChanEntry->usSinSoutTsiMemIndex, + pDestinationChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the original sin TSI. */ + if ( pDestinationChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pDestinationChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pDestinationChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Reprogram the TSST entry correctly if the extra RIN TSI entry was released. */ + if ( ( pDestinationChanEntry->usExtraRinTsiDependencyCnt == 1 ) && ( f_fRemovePermanently == TRUE ) ) + { + if ( pDestinationChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pDestinationChanEntry->usRinTsstIndex, + pDestinationChanEntry->usRinRoutTsiMemIndex, + pDestinationChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + + if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex && + pSharedInfo->MixerInfo.usLastBridgeEventPtr == pDestinationChanEntry->usSubStoreEventIndex ) + { + /* There is no more bridge entry in the mixer link list. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + } + else if ( pSharedInfo->MixerInfo.usFirstBridgeEventPtr == usLoadOrAccumulateEventIndex ) + { + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = pStoreEventEntry->usNextEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == pDestinationChanEntry->usSubStoreEventIndex ) + { + pSharedInfo->MixerInfo.usLastBridgeEventPtr = usPreviousEventIndex; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if must remove the Sin copy event from the list. */ + + if ( ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) && ( f_fRemovePermanently == TRUE ) ) + { + /* Now remove the copy event from the event list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, pDestinationChanEntry->usSinCopyEventIndex, cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + + /*=======================================================================*/ + + if ( f_fRemovePermanently == TRUE ) + { + /* Set the event entries as free. */ + pLoadEventEntry->fReserved = FALSE; + pLoadEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pLoadEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pStoreEventEntry->fReserved = FALSE; + pStoreEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pStoreEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + if ( pDestinationChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, pDestinationChanEntry->usSinCopyEventIndex ); + + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pCopyEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + } + + /* Flexible mixer for this channel not created anymore. */ + pDestinationParticipant->fFlexibleMixerCreated = FALSE; + + /*=======================================================================*/ + } + + /*=======================================================================*/ + } + else /* if ( pDestinationChanEntry->fFlexibleMixerCreated == FALSE ) */ + { + /* This point should never be reached. */ + return cOCT6100_ERR_FATAL_C9; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanMuteSer + +Description: Mute an echo channel present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge mute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanMuteSer +UINT32 Oct6100ConfBridgeChanMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT32 ulResult; + UINT8 fFlexibleConferencing; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeMuteParams( + f_pApiInstance, + f_pConfBridgeMute, + &usChanIndex, + &usLoadEventIndex, + &usSubStoreEventIndex, + &fFlexibleConferencing ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeMuteResources( + f_pApiInstance, + usChanIndex, + usLoadEventIndex, + usSubStoreEventIndex, + fFlexibleConferencing ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeMuteParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge channel mute structure. +f_pusChannelIndex Pointer to a channel index. +f_pusLoadEventIndex Pointer to a load mixer event index. +f_pusSubStoreEventIndex Pointer to a sub-store mixer event index. +f_pfFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeMuteParams +UINT32 Oct6100ApiCheckBridgeMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeMute->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check if channel is already muted. */ + if ( pEchoChanEntry->fMute == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_ALREADY_MUTED; + + /* Check if this is a tap channel, which is always mute. */ + if ( pEchoChanEntry->fTap == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( pEchoChanEntry->usBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + { + /* Check the event entries.*/ + if ( pEchoChanEntry->usLoadEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + if ( pEchoChanEntry->usSubStoreEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + } + + /*=====================================================================*/ + + /* Return the config of the channel and all other important information. */ + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeMuteResources + +Description: Modify the conference bridge entry for this channel in order + to mute the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be muted. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_fFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeMuteResources +UINT32 Oct6100ApiUpdateBridgeMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount; + UINT16 usReadData; + + BOOL fCreateSilenceLoad = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT16 usChannelIndex; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Search through the list of API channel entry for the ones on to this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + if ( pTempEchoChanEntry->usBridgeIndex == pEchoChanEntry->usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant can hear us. */ + if ( ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pTempParticipant->fFlexibleMixerCreated == TRUE ) ) + { + /* Then update this channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + pEchoChanEntry->usBridgeIndex, + f_usChanIndex, + usChannelIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == usChannelIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = usChannelIndex; + break; + } + } + } + } + } + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED ) + { + UINT32 ulTempResult; + + /* Cleanup resources, unmute channel... */ + ulTempResult = Oct6100ApiUpdateBridgeUnMuteResources( + f_pApiInstance, + f_usChanIndex, + f_usLoadEventIndex, + f_usSubStoreEventIndex, + TRUE ); + if ( ulTempResult != cOCT6100_ERR_OK ) + return ulTempResult; + else + return ulResult; + } + else + { + return ulResult; + } + } + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Create silence load if this is the first event of the bridge. */ + if ( f_usLoadEventIndex == pBridgeEntry->usFirstLoadEventPtr ) + fCreateSilenceLoad = TRUE; + + /* First check if this event was a load or an accumulate event, if it's a load */ + /* we need to find a new load. */ + if ( f_usLoadEventIndex == pBridgeEntry->usLoadIndex ) + { + /* Change the next entry if one is present to a load event to keep the bridge alive. */ + if ( pBridgeEntry->usNumClients == 1 ) + { + /* There is no other entry on the bridge, no need to search for an Accumulate event. */ + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + } + else + { + /* Search for an accumulate event to tranform into a Load event. */ + usTempEventIndex = pLoadEventEntry->usNextEventPtr; + ulLoopCount = 0; + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ) + { + /* Change this entry into a load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_LOAD); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set this entry as the load index. */ + pBridgeEntry->usLoadIndex = usTempEventIndex; + + /* Update the software model. */ + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + + /* Stop searching. */ + break; + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + } + } + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* Do not load the sample if the channel is muted. */ + if ( fCreateSilenceLoad == TRUE ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == cOCT6100_INVALID_INDEX ) + { + /* Instead of No-oping, load the silence TSI, to make sure the other conferences before us are not heard. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_LOAD; + WriteParams.usWriteData |= 1534; /* TSI index 1534 reserved for silence */ + + /* Remember the silence load event. */ + pBridgeEntry->usSilenceLoadEventPtr = f_usLoadEventIndex; + } + else + { + /* Do nothing. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + } + else + { + /* Do nothing. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + pLoadEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + /* Do not load the sample if the channel is muted. */ + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout input. */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* if ( pEchoChanEntry->usSinCopyEventIndex == cOCT6100_INVALID_INDEX ) */ + { + /* Rin input. */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software model. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_STORE; + + /*=======================================================================*/ + } + + /* Update the channel entry API structure */ + pEchoChanEntry->fMute = TRUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanUnMuteSer + +Description: UnMute an echo channel present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanUnMuteSer +UINT32 Oct6100ConfBridgeChanUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + UINT16 usChanIndex; + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + UINT8 fFlexibleConfBridge; + UINT32 ulResult; + + /* Check the validity of the channel and conference bridge given. */ + ulResult = Oct6100ApiCheckBridgeUnMuteParams( + f_pApiInstance, + f_pConfBridgeUnMute, + &usChanIndex, + &usLoadEventIndex, + &usSubStoreEventIndex, + &fFlexibleConfBridge ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeUnMuteResources( + f_pApiInstance, + usChanIndex, + usLoadEventIndex, + usSubStoreEventIndex, + fFlexibleConfBridge ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeUnMuteParams + +Description: Check the validity of the channel and conference bridge given. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. +f_pusChannelIndex Pointer to the channel index fo the channel to be unmuted. +f_pusLoadEventIndex Pointer to the load index of the channel. +f_pusSubStoreEventIndex Pointer to the sub-store event of the channel. +f_pfFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeUnMuteParams +UINT32 Oct6100ApiCheckBridgeUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeUnMute->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeUnMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeUnMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeUnMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge.*/ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check if channel is already muted.*/ + if ( pEchoChanEntry->fMute == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_NOT_MUTED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + if ( pEchoChanEntry->usBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + /* Check the event entries.*/ + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + { + if ( pEchoChanEntry->usLoadEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + + /* Check the event entries.*/ + if ( pEchoChanEntry->usSubStoreEventIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE; + } + + /*=====================================================================*/ + + /* Return the config of the channel and all other important information.*/ + *f_pusSubStoreEventIndex = pEchoChanEntry->usSubStoreEventIndex; + *f_pusLoadEventIndex = pEchoChanEntry->usLoadEventIndex; + *f_pfFlexibleConfBridge = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeUnMuteResources + +Description: Modify the conference bridge entry for this channel in order + to un-mute the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be unmuted. +f_usLoadEventIndex Allocated entry for the Load event of the channel. +f_usSubStoreEventIndex Allocated entry for the substract and store event of the channel. +f_fFlexibleConfBridge If this is a flexible conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeUnMuteResources +UINT32 Oct6100ApiUpdateBridgeUnMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + tPOCT6100_API_MIXER_EVENT pLoadEventEntry; + tPOCT6100_API_MIXER_EVENT pSubStoreEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEntry; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount; + UINT16 usReadData; + + UINT16 usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + UINT16 usPreviousLoadIndex = cOCT6100_INVALID_INDEX; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_usChanIndex ); + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pEchoChanEntry->usBridgeIndex ) + + if ( f_fFlexibleConfBridge == TRUE ) + { + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + UINT16 usChannelIndex; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pEchoChanEntry->usFlexConfParticipantIndex ); + + /* Before doing anything, check if the copy events must be created. */ + if ( ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChanEntry->fCopyEventCreated == FALSE ) ) + { + /* The copy event has not been created, create it once for the life of the participant on the bridge. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pEchoChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pEchoChanEntry->usExtraSinTsiMemIndex; + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now insert the Sin copy event into the list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pEchoChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pEchoChanEntry->fCopyEventCreated = TRUE; + } + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == pEchoChanEntry->usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if this participant can hear us. */ + if ( ( pTempParticipant->ulListenerMask & ( 0x1 << pParticipant->ulListenerMaskIndex ) ) == 0x0 ) + { + /* Then create/update this channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + pEchoChanEntry->usBridgeIndex, + f_usChanIndex, + usChannelIndex, + pTempParticipant->ausLoadOrAccumulateEventIndex[ pParticipant->ulListenerMaskIndex ], + pTempEchoChanEntry->usSubStoreEventIndex, + pTempEchoChanEntry->usSinCopyEventIndex, + pParticipant->ulInputPort, + pTempParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the Rin silence event can be cleared now that the */ + /* channel has unmuted. */ + if ( ( pTempParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pTempEchoChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pTempEchoChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pTempEchoChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + } + } + } + else /* if ( f_fFlexibleConfBridge == FALSE ) */ + { + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pLoadEventEntry, f_usLoadEventIndex ); + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pSubStoreEventEntry, f_usSubStoreEventIndex ); + + /*=======================================================================*/ + /* Program the Load event. */ + + /* Before reactivating this event, check what type of event this event must be. */ + if ( f_usLoadEventIndex == pBridgeEntry->usFirstLoadEventPtr || + pBridgeEntry->usLoadIndex == cOCT6100_INVALID_INDEX ) + { + /* This event must become a Load event. */ + usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + pBridgeEntry->usLoadIndex = f_usLoadEventIndex; + } + + usTempEventIndex = pBridgeEntry->usFirstLoadEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount = 0; + + while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE && + pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_STORE ) + { + if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + usPreviousLoadIndex = usTempEventIndex; + } + + /* Check if the previous load event is before or after the event about to be unmuted. */ + if ( pTempEntry->usNextEventPtr == f_usLoadEventIndex ) + { + if ( usPreviousLoadIndex == cOCT6100_INVALID_INDEX ) + { + /* We did not find a load event before our node, this mean this one */ + /* is about to become the new load event. */ + usLoadEventType = cOCT6100_MIXER_CONTROL_MEM_LOAD; + } + } + + /* Go to the next entry into the list. */ + usTempEventIndex = pTempEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_9B; + } + + /* Now program the current event node. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usLoadEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = usLoadEventType; + + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout source */ + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + /* Rin source */ + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + pLoadEventEntry->usEventType = usLoadEventType; + + /* Check if we need to change another node. */ + if ( usLoadEventType == cOCT6100_MIXER_CONTROL_MEM_LOAD ) + { + if ( usPreviousLoadIndex != cOCT6100_INVALID_INDEX ) + { + /* Now program the old load event. */ + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usPreviousLoadIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = (UINT16)(( usReadData & 0x1FFF ) | cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usPreviousLoadIndex ); + pTempEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE; + } + } + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Substract and store event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSubStoreEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + /* If we have an extra Sin copy event, we know we are using the Sout port as a source. */ + if ( pEchoChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Sout port source */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usSinSoutTsiMemIndex; + } + else + { + /* Rin port source */ + WriteParams.usWriteData |= pEchoChanEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + WriteParams.usWriteData |= pEchoChanEntry->usRinRoutTsiMemIndex; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pEchoChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the software event to reflect the hardware. */ + pSubStoreEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_SUB_STORE; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if have to remove silence load event. */ + + if ( pBridgeEntry->usSilenceLoadEventPtr != cOCT6100_INVALID_INDEX ) + { + if ( pBridgeEntry->usSilenceLoadEventPtr == f_usLoadEventIndex ) + { + /* Clear the silence load event ptr. */ + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + } + } + } + + /* Update the channel entry API structure */ + pEchoChanEntry->fMute = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeDominantSpeakerSetSer + +Description: This function sets the dominant speaker of a bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeDominant Pointer to conference bridge dominant speaker + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSetSer +UINT32 Oct6100ConfBridgeDominantSpeakerSetSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + UINT16 usChanIndex; + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Check the validity of the channel handle given. */ + ulResult = Oct6100ApiCheckBridgeDominantSpeakerParams( f_pApiInstance, f_pConfBridgeDominantSpeaker, &usChanIndex, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify all resources needed by the conference bridge. */ + ulResult = Oct6100ApiUpdateBridgeDominantSpeakerResources( f_pApiInstance, usChanIndex, usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeDominantSpeakerParams + +Description: Check the validity of the channel given for setting the + dominant speaker. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pConfBridgeDominant Pointer to conference bridge channel dominant speaker structure. +f_pusChannelIndex Pointer to a channel index. +f_pusChannelIndex Pointer to a bridge index. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeDominantSpeakerParams +UINT32 Oct6100ApiCheckBridgeDominantSpeakerParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + BOOL fCheckEntryOpenCnt = FALSE; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeDominantSpeaker->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( f_pConfBridgeDominantSpeaker->ulChannelHndl != cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL ) + { + if ( (f_pConfBridgeDominantSpeaker->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeDominantSpeaker->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeDominantSpeaker->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + /* Check if the NLP is enabled on this channel. */ + if ( pEchoChanEntry->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_NLP_MUST_BE_ENABLED; + + /* Check if conferencing noise reduction is enabled on this channel. */ + if ( pEchoChanEntry->VqeConfig.fSoutConferencingNoiseReduction == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_CNR_MUST_BE_ENABLED; + + /* Check if this is a tap channel. If it is, it will never be the dominant speaker! */ + if ( pEchoChanEntry->fTap == TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + } + else + { + /* Set this such that there is no dominant speaker on this conference bridge. */ + *f_pusChannelIndex = cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED; + + /* Check the conference bridge handle. */ + if ( (f_pConfBridgeDominantSpeaker->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeDominantSpeaker->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeDominantSpeaker->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + fCheckEntryOpenCnt = TRUE; + } + + /*=====================================================================*/ + + /*=====================================================================*/ + + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( fCheckEntryOpenCnt == TRUE ) + { + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + } + + /*=====================================================================*/ + /* Check if dominant speaker is supported in this firmware version. */ + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_DOMINANT_SPEAKER; + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeDominantSpeakerResources + +Description: Modify the conference bridge such that the new dominant + speaker is the one specified by the index. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Index of the channel to be set as the dominant speaker. +f_usBridgeIndex Index of the bridge where this channel is on. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeDominantSpeakerResources +UINT32 Oct6100ApiUpdateBridgeDominantSpeakerResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + UINT16 usChannelIndex; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the bridge entry for this channel. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ) + + /* Set the dominant speaker index for all channels in this conference. */ + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, usChannelIndex ); + + if ( pEchoChanEntry->fReserved == TRUE ) + { + if ( pEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + /* If we are unsetting the dominant speaker, of if it is not our channel index. */ + if ( ( f_usChanIndex == cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ) + || ( f_usChanIndex != usChannelIndex ) ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, usChannelIndex, f_usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Make sure this channel is disabled. */ + if ( f_usChanIndex != cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_usChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Save this in the conference bridge structure. */ + /* This will be needed later when removing the channel. */ + pBridgeEntry->fDominantSpeakerSet = TRUE; + pBridgeEntry->usDominantSpeakerChanIndex = f_usChanIndex; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeMaskChangeSer + +Description: This function changes the mask of flexible bridge + participant. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeMaskChange Pointer to conference bridge participant mask + change structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeMaskChangeSer +UINT32 Oct6100ConfBridgeMaskChangeSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + UINT16 usChanIndex; + UINT16 usBridgeIndex; + UINT32 ulResult; + UINT32 ulNewParticipantMask; + + /* Check the validity of the channel handle given. */ + ulResult = Oct6100ApiCheckBridgeMaskChangeParams( f_pApiInstance, f_pConfBridgeMaskChange, &usChanIndex, &usBridgeIndex, &ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update all resources needed by the new mask. */ + ulResult = Oct6100ApiUpdateMaskModifyResources( f_pApiInstance, usBridgeIndex, usChanIndex, ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Commit the changes to the chip's internal memories. */ + ulResult = Oct6100ApiBridgeUpdateMask( f_pApiInstance, usBridgeIndex, usChanIndex, ulNewParticipantMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeMaskChangeParams + +Description: Check the validity of the channel given for setting the + mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMaskChange Pointer to conference bridge channel mask change structure. +f_pusChannelIndex Pointer to a channel index. +f_pusBridgeIndex Pointer to a bridge index. +f_pulNewParticipantMask New mask to apply for this participant. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeMaskChangeParams +UINT32 Oct6100ApiCheckBridgeMaskChangeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT32 f_pulNewParticipantMask ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CHANNEL pEchoChanEntry; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeMaskChange->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + /* Check the channel handle.*/ + + if ( (f_pConfBridgeMaskChange->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusChannelIndex = (UINT16)( f_pConfBridgeMaskChange->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, *f_pusChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeMaskChange->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /* Check if the channel is bound to a conference bridge. */ + if ( pEchoChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE; + + /* Set the bridge index. */ + *f_pusBridgeIndex = pEchoChanEntry->usBridgeIndex; + + /*=====================================================================*/ + + /*=====================================================================*/ + + if ( ( *f_pusBridgeIndex == cOCT6100_INVALID_INDEX ) + || ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + + /* Check if this is bridge is a flexible conference bridge. */ + if ( pBridgeEntry->fFlexibleConferencing == FALSE ) + return cOCT6100_ERR_CONF_BRIDGE_SIMPLE_BRIDGE; + + /*=====================================================================*/ + + /* Return new mask to apply. */ + *f_pulNewParticipantMask = f_pConfBridgeMaskChange->ulNewListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateMaskModifyResources + +Description: Modify/reserve all resources needed for the modification of + the participant's mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex Bridge index of the bridge where this channel is residing. +f_usChanIndex Channel index of the channel to be modified. +f_ulNewListenerMask New mask to apply to the selected participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateMaskModifyResources +UINT32 Oct6100ApiUpdateMaskModifyResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + UINT32 ulOldListenerMask; + UINT16 usChannelIndex; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pChanEntry->usFlexConfParticipantIndex ); + + /* Must travel all clients of this conference and reserve a load or accumulate event for */ + /* all participants which could not hear us but now can. While at it, check for events that */ + /* could be released, for example a participant that we cannot hear anymore. */ + + ulOldListenerMask = pParticipant->ulListenerMask; + + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; ( usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels ) && ( ulResult == cOCT6100_ERR_OK ) ; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* Must reserve a load or accumulate entry mixer event here! */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Most probably, the hardware is out of mixer events. */ + break; + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* Must release the load or accumulate entry mixer event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulResult != cOCT6100_ERR_OK ) + { + break; + } + } + } + } + } + + /* If an error is returned, make sure everything is cleaned up properly. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Search through the list of API channel entry for the ones on to this bridge.*/ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] != cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + /* If the load or event entry in the mixer memory was reserved. */ + if ( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] == cOCT6100_INVALID_INDEX ) + { + /* Must release the load or accumulate entry mixer event. */ + ulTempVar = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, &( pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] ) ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + } + } + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeUpdateMask + +Description: Update the participant's mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_usBridgeIndex Bridge index of the bridge where this channel is residing. +f_usChanIndex Channel index of the channel to be modified. +f_ulNewListenerMask New mask to apply to the selected participant. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeUpdateMask +UINT32 Oct6100ApiBridgeUpdateMask( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL pTempEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pParticipant; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pTempParticipant; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + UINT32 ulOldListenerMask; + UINT16 usChannelIndex; + + UINT16 ausMutePortChannelIndexes[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + UINT32 ulMutePortChannelIndex; + + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = cOCT6100_INVALID_INDEX; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pParticipant, pChanEntry->usFlexConfParticipantIndex ); + + ulOldListenerMask = pParticipant->ulListenerMask; + + /* Search through the list of API channel entry for the ones onto this bridge. */ + for ( usChannelIndex = 0; usChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; usChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, usChannelIndex ); + + /* Channel reserved? */ + if ( ( usChannelIndex != f_usChanIndex ) && ( pTempEchoChanEntry->fReserved == TRUE ) ) + { + /* On current bridge? */ + if ( pTempEchoChanEntry->usBridgeIndex == f_usBridgeIndex ) + { + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + /* Check if we can now hear this participant, but could not before. */ + if ( ( pTempEchoChanEntry->fMute == FALSE ) + && ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) ) + { + /* First create/update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeAddParticipantToChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ], + pChanEntry->usSubStoreEventIndex, + pChanEntry->usSinCopyEventIndex, + pTempParticipant->ulInputPort, + pParticipant->ulInputPort ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pParticipant->fFlexibleMixerCreated == TRUE ) + { + /* Check if the Rin silence event can be cleared now that the */ + /* channel has been added to a conference. */ + if ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + } + } + + /* Check if we can now NOT hear this participant, but could before. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) + && ( pParticipant->fFlexibleMixerCreated == TRUE ) + && ( pTempEchoChanEntry->fMute == FALSE ) ) + { + /* First update the current channel's mixer. */ + ulResult = Oct6100ApiBridgeRemoveParticipantFromChannel( + f_pApiInstance, + f_usBridgeIndex, + usChannelIndex, + f_usChanIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Remember to mute the port on this channel. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == f_usChanIndex ) + { + break; + } + else if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) + { + ausMutePortChannelIndexes[ ulMutePortChannelIndex ] = f_usChanIndex; + break; + } + } + } + } + + /* Clear the load or accumulate event index for this participant. */ + if ( ( ( f_ulNewListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) != 0x0 ) + && ( ( ulOldListenerMask & ( 0x1 << pTempParticipant->ulListenerMaskIndex ) ) == 0x0 ) ) + { + pParticipant->ausLoadOrAccumulateEventIndex[ pTempParticipant->ulListenerMaskIndex ] = cOCT6100_INVALID_INDEX; + } + } + } + + /* Travel through the channels that were heard by the participant removed and check if their Rin port must be muted. */ + for( ulMutePortChannelIndex = 0; ulMutePortChannelIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulMutePortChannelIndex ++ ) + { + if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempEchoChanEntry, ausMutePortChannelIndexes[ ulMutePortChannelIndex ] ); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pTempParticipant, pTempEchoChanEntry->usFlexConfParticipantIndex ); + + if ( pTempParticipant->fFlexibleMixerCreated == FALSE ) + { + /* Check if the Rin port must be muted on this channel. */ + ulResult = Oct6100ApiMutePorts( + f_pApiInstance, + ausMutePortChannelIndexes[ ulMutePortChannelIndex ], + pTempEchoChanEntry->usRinTsstIndex, + pTempEchoChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ausMutePortChannelIndexes[ ulMutePortChannelIndex ] == cOCT6100_INVALID_INDEX ) */ + { + /* No more channels to check for muting. */ + break; + } + } + } + + /* Configure the SIN copy mixer entry and memory - if using the SOUT port. */ + if ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + pChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If the silence TSI is loaded on this port, update with the extra sin TSI. */ + if ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usExtraSinTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure the RIN copy mixer entry and memory - if using the RIN port. */ + if ( pParticipant->ulInputPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + pChanEntry->TdmConfig.byRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Save the new mask permanently in the API instance. */ + pParticipant->ulListenerMask = f_ulNewListenerMask; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeGetStatsSer + +Description: This function returns the statistics from the specified bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeStats Pointer to conference bridge stats structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeGetStatsSer +UINT32 Oct6100ConfBridgeGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + UINT16 usConfBridgeIndex; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + /*=====================================================================*/ + /* Check the conference bridge handle. */ + + /* Check the provided handle. */ + if ( (f_pConfBridgeStats->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + usConfBridgeIndex = (UINT16)( f_pConfBridgeStats->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usConfBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, usConfBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeStats->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + /*=====================================================================*/ + + /* Return the stats.*/ + f_pConfBridgeStats->ulNumChannels = pBridgeEntry->usNumClients; + f_pConfBridgeStats->ulNumTappedChannels = pBridgeEntry->usNumTappedClients; + f_pConfBridgeStats->fFlexibleConferencing = pBridgeEntry->fFlexibleConferencing; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeEntry + +Description: Reserves a free entry in the Bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pusBridgeIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeEntry +UINT32 Oct6100ApiReserveBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBridgeIndex ) +{ + PVOID pBridgeAlloc; + UINT32 ulResult; + UINT32 ulBridgeIndex; + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBridgeAlloc ) + + ulResult = OctapiLlmAllocAlloc( pBridgeAlloc, &ulBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CONF_BRIDGE_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_29; + } + + *f_pusBridgeIndex = (UINT16)( ulBridgeIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBridgeEntry + +Description: Release an entry from the bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBridgeEntry +UINT32 Oct6100ApiReleaseBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex ) +{ + PVOID pBridgeAlloc; + UINT32 ulResult; + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBridgeAlloc ) + + ulResult = OctapiLlmAllocDealloc( pBridgeAlloc, f_usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2A; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPrevLastSubStoreEvent + +Description: This function will search for the first valid LastSubStoreEvent + in a bridge located before the current bridge in the bridge + link list. + + If the function does not find an event before reaching the end + of the mixers list, then the event head node will be used as the + last Store or SubStore event. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBridgeEntry Bridge entry. +f_usBridgeFirstLoadEventPtr Load index to check against. +First valid sub store index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPrevLastSubStoreEvent +UINT32 Oct6100ApiGetPrevLastSubStoreEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usBridgeFirstLoadEventPtr, + OUT PUINT16 f_pusLastSubStoreEventIndex ) +{ + tPOCT6100_API_MIXER_EVENT pTempMixerEntry; + UINT16 usNextEventPtr; + UINT16 usHeadEventPtr; + UINT16 usLastSubStoreEventPtr; + UINT32 ulLoopCount = 0; + UINT16 usCurrentPtr; + UINT32 ulResult = cOCT6100_ERR_OK; + + /* Since we have flexible bridges, we have to */ + /* run down the list and check for the appropriate event. */ + + /* Travel down the list for the last Store or Sub/Store event before the bridge. */ + + if ( f_pApiInstance->pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list then is the head node.*/ + usHeadEventPtr = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usHeadEventPtr = f_pApiInstance->pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempMixerEntry, usHeadEventPtr ); + usLastSubStoreEventPtr = usHeadEventPtr; + usNextEventPtr = pTempMixerEntry->usNextEventPtr; + usCurrentPtr = usHeadEventPtr; + while( usCurrentPtr != f_usBridgeFirstLoadEventPtr ) + { + if ( ( pTempMixerEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_STORE ) + || ( pTempMixerEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_SUB_STORE ) ) + { + usLastSubStoreEventPtr = usNextEventPtr; + } + + /* Next pointer. */ + usCurrentPtr = usNextEventPtr; + usNextEventPtr = pTempMixerEntry->usNextEventPtr; + + /* Check if next event pointer is valid. */ + if ( ( ( f_usBridgeFirstLoadEventPtr != usCurrentPtr ) + && ( pTempMixerEntry->usNextEventPtr == cOCT6100_INVALID_INDEX ) ) + || ( pTempMixerEntry->usNextEventPtr == cOCT6100_MIXER_HEAD_NODE ) ) + return cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND; + + if ( usNextEventPtr != cOCT6100_INVALID_INDEX ) + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempMixerEntry, usNextEventPtr ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_CA; + } + + /* Return the result to the user. */ + *f_pusLastSubStoreEventIndex = usLastSubStoreEventPtr; + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPreviousEvent + +Description: This is a recursive function, it requires an entry event index and + will run down the list until it finds the node just before the one + required. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEntryIndex Event entry index. +f_pusBridgeEntry Bridge entry. +f_pusPreviousIndex Previous index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPreviousEvent +UINT32 Oct6100ApiGetPreviousEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEntryIndex, + IN UINT16 f_usSearchedIndex, + IN UINT16 f_usLoopCnt, + OUT PUINT16 f_pusPreviousIndex ) +{ + tPOCT6100_API_MIXER_EVENT pCurrentEntry; + UINT32 ulResult; + + /* Get current entry to obtain the link to the previous entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pCurrentEntry, f_usEntryIndex ); + + /* Avoid stack overflows. */ + if ( f_usLoopCnt == cOCT6100_MAX_MIXER_EVENTS ) + return cOCT6100_ERR_FATAL_E3; + + if ( pCurrentEntry->usNextEventPtr == cOCT6100_INVALID_INDEX ) + { + /* Event not found. */ + ulResult = cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND; + } + else if ( pCurrentEntry->usNextEventPtr == f_usSearchedIndex ) + { + /* We found our node. */ + *f_pusPreviousIndex = f_usEntryIndex; + ulResult = cOCT6100_ERR_OK; + } + else + { + /* Keep searching.*/ + f_usLoopCnt++; + ulResult = Oct6100ApiGetPreviousEvent( f_pApiInstance, pCurrentEntry->usNextEventPtr, f_usSearchedIndex, f_usLoopCnt, f_pusPreviousIndex ); + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBridgeSetDominantSpeaker + +Description: This function will set the index of the dominant speaker + for the channel index specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_usChannelIndex Index of the channel where the API must set the + current dominant speaker for the conference. +f_usDominantSpeakerIndex Index of the channel which is the dominant + speaker in the conference. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBridgeSetDominantSpeaker +UINT32 Oct6100ApiBridgeSetDominantSpeaker( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex, + IN UINT16 f_usDominantSpeakerIndex ) +{ + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulMask; + + tPOCT6100_API_CHANNEL pEchoChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChanEntry, f_usChannelIndex ); + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst; + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst.byFieldSize; + + /* Retrieve the current configuration. */ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( f_usDominantSpeakerIndex ) << ulFeatureBitOffset ); + + /* Save the new dominant speaker. */ + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveFlexConfParticipantEntry + +Description: Reserves a free entry in the participant list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pusParticipantIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveFlexConfParticipantEntry +UINT32 Oct6100ApiReserveFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusParticipantIndex ) +{ + PVOID pParticipantAlloc; + UINT32 ulResult; + UINT32 ulParticipantIndex; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pParticipantAlloc ) + + ulResult = OctapiLlmAllocAlloc( pParticipantAlloc, &ulParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_29; + } + + *f_pusParticipantIndex = (UINT16)( ulParticipantIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseFlexConfParticipantEntry + +Description: Release an entry from the flexible conferencing participant + list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usParticipantIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseFlexConfParticipantEntry +UINT32 Oct6100ApiReleaseFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usParticipantIndex ) +{ + PVOID pParticipantAlloc; + UINT32 ulResult; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pParticipantAlloc ) + + ulResult = OctapiLlmAllocDealloc( pParticipantAlloc, f_usParticipantIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2A; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c new file mode 100644 index 0000000..1f4de01 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c @@ -0,0 +1,1278 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to debug the OCT6100. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 65 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugSelectChannel + +Description: This function sets the current debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pSelectDebugChan Pointer to select debug channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugSelectChannelDef +UINT32 Oct6100DebugSelectChannelDef( + tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ) +{ + f_pSelectDebugChan->ulChannelHndl = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DebugSelectChannel +UINT32 Oct6100DebugSelectChannel( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100DebugSelectChannelSer( f_pApiInstance, f_pSelectDebugChan, TRUE ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugGetData + +Description: This function retrieves the last recorded debug data. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetData Pointer to debug get data structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugGetDataDef +UINT32 Oct6100DebugGetDataDef( + tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + f_pGetData->ulGetDataMode = cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE; + f_pGetData->ulGetDataContent = cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE; + f_pGetData->ulRemainingNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulTotalNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulMaxBytes = cOCT6100_INVALID_VALUE; + f_pGetData->ulValidNumBytes = cOCT6100_INVALID_VALUE; + f_pGetData->pbyData = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DebugGetData +UINT32 Oct6100DebugGetData( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100DebugGetDataSer( f_pApiInstance, f_pGetData ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugSelectChannelSer + +Description: This function sets the debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pSelectDebugChan Pointer to a tOCT6100_DEBUG_SELECT_CHANNEL structure. +f_fCheckChannelRecording Check if channel recording is enabled or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugSelectChannelSer +UINT32 Oct6100DebugSelectChannelSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan, + IN BOOL f_fCheckChannelRecording ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry = NULL; + tPOCT6100_API_CHANNEL pTempChanEntry; + tOCT6100_CHANNEL_OPEN TempChanOpen; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 usChanIndex = 0; + UINT32 ulEntryOpenCnt; + UINT16 ausWriteData[ 2 ]; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + + /* First release the resources reserved for the channel that was previously debugged. */ + if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex != cOCT6100_INVALID_INDEX && + pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + + /* Release the extra TSI memory entry and reprogram the TSST control memory if required. */ + if ( pTempChanEntry->usExtraSinTsiDependencyCnt >= 1 ) + { + /*=======================================================================*/ + /* Clear memcpy operations. */ + + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + ausWriteData[ 1 ] = 0x0; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* If we are the last dependency using the extra Sin TSI, release it */ + if ( pTempChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pTempChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Do not forget to reprogram the TSST control memory. */ + if ( pTempChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pTempChanEntry->usSinTsstIndex, + pTempChanEntry->usSinSoutTsiMemIndex, + pTempChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + pTempChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + + /* XXX: What about the silence TSI usSinSilenceEventIndex ?? */ + } + + pTempChanEntry->usExtraSinTsiDependencyCnt--; + + } + } + + /* Set the new parameters. */ + if ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE ) + { + /* Check the provided handle. */ + if ( (f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE; + + usChanIndex = (UINT16)( f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE; + + if ( f_fCheckChannelRecording == TRUE ) + { + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED; + } + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, usChanIndex ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pSelectDebugChan->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* First program the mixer entry if the user wants to record. */ + /* Check if the API needs to reserve an extra TSI memory to load the SIN signal. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Reserve the extra Sin TSI memory if it was not already reserved. */ + if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reprogram the TSST control memory accordingly. */ + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + pChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* XXX: What about the silence TSI usSinSilenceEventIndex ?? */ + } + + + /*=======================================================================*/ + /* Program the Sout Copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY; + ausWriteData[ 0 ] |= pChanEntry->usSinSoutTsiMemIndex; + ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + ausWriteData[ 1 ] = (UINT16)( pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 2; + + ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY; + ausWriteData[ 0 ] |= pChanEntry->usExtraSinTsiMemIndex; + ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + ausWriteData[ 1 ] = pChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + pChanEntry->usExtraSinTsiDependencyCnt++; + } + } + else + { + /* Set the index to invalid to deactivate the recording. */ + usChanIndex = cOCT6100_INVALID_INDEX; + } + + /* Set law of newly selected hot channel. */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE ) + && ( pChanEntry != NULL ) ) + { + /* Set the PCM law of the debug channel. */ + /* Let's program the channel memory. */ + Oct6100ChannelOpenDef( &TempChanOpen ); + + TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel. */ + TempChanOpen.VqeConfig.fEnableNlp = FALSE; + TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.lDefaultErlDb = 0; + + /* Use the law of the channel being recorded. */ + TempChanOpen.TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw; + TempChanOpen.TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw; + TempChanOpen.TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw; + TempChanOpen.TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw; + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + &TempChanOpen.TdmConfig, + &TempChanOpen.VqeConfig, + &TempChanOpen, + pSharedInfo->DebugInfo.usRecordChanIndex, + pSharedInfo->DebugInfo.usRecordMemIndex, + pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex, + pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ausWriteData[ 0 ] = 0x0; + ausWriteData[ 1 ] = (UINT16)(( usChanIndex >> 0) & 0xFFFF); + + /* Write the channel number into the Matrix hot channel field.*/ + BurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + BurstParams.pusWriteData = ausWriteData; + BurstParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = usChanIndex; + + /* Cancel data dump request, if there was one. */ + pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE; + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE; + + /* Call from remote client. */ + if ( f_fCheckChannelRecording == FALSE ) + { + /* If the user has not activated recording, let the remote client know. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DebugGetDataSer + +Description: This function retrieves the latest recorded debug data. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetData Pointer to a tOCT6100_DEBUG_GET_DATA structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DebugGetDataSer +UINT32 Oct6100DebugGetDataSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ) +{ + + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry = NULL; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + + UINT16 ausWriteData[ 2 ]; + UINT16 usReadData; + UINT16 usDebugEventReadPtr; + UINT16 usTempNumEvents; + + UINT32 ulResult; + UINT32 ulToneEventIndex; + UINT32 ulReadPointer; + UINT32 ulUserBufWriteIndex = 0; + UINT32 ulTimestamp; + UINT32 ulDebugEventIndex = 0; + UINT32 ulStreamIndex; + UINT32 ulPcmSampleIndex; + UINT32 ulNumAfEvents; + UINT32 ulNumReads = 0; + UINT32 ulTempIndex; + UINT32 ulCopyIndex; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulStreamIndexMin; + UINT32 ulStreamIndexMax; + UINT32 ulTempData; + UINT32 ulMask; + BOOL fResetRemainingDataFlag = FALSE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Check all user parameters. */ + + /* Check if channel recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED; + + /* Check if a current debugging channel has been selected. */ + /* If not, the user has not yet called Oct6100DebugSelectChannel. */ + if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED; + + /* Check that the user supplied a valid max bytes value. */ + if ( f_pGetData->ulMaxBytes == cOCT6100_INVALID_VALUE ) + return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES; + + /* Data buffer must be aligned on 1024 bytes. */ + if ( ( f_pGetData->ulMaxBytes % 1024 ) != 0 ) + return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES; + + /* Check that the user provided the required memory to transfer the information. */ + if ( f_pGetData->pbyData == NULL ) + return cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID; + + /* Check dump type. */ + if ( ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S ) + && ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + return cOCT6100_ERR_DEBUG_GET_DATA_MODE; + + /* Check dump content. */ + if ( ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) + && ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + return cOCT6100_ERR_DEBUG_GET_DATA_CONTENT; + + /* Check if can accomodate the 120 seconds dump. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + if ( pSharedInfo->DebugInfo.ulDebugEventSize != 0x100 ) + return cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S; + } + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + + /* Lets go dump the requested data. */ + + usDebugEventReadPtr = 0; + + /* Check if this is the first time this function is called since the hot channel was set. */ + if ( pSharedInfo->DebugInfo.fDebugDataBeingDumped == FALSE ) + { + /* Check that the channel is not in POWER_DOWN. When the channel is in POWER_DOWN, */ + /* the debug events are not recorded correctly in external memory. */ + if ( pChanEntry->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + return cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN; + + pSharedInfo->DebugInfo.fDebugDataBeingDumped = TRUE; + + /* Flag the hot channel that it must stop recording. The data is being transfered. */ + /* This also tells the remote client not to do anything right now. */ + + ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + ReadBurstParams.ulReadLength = 2; + ReadBurstParams.pusReadData = pSharedInfo->DebugInfo.ausHotChannelData; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteBurstParams.pusWriteData = ausWriteData; + WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + WriteBurstParams.ulWriteLength = 2; + + WriteBurstParams.pusWriteData[ 0 ] = 0xFFFF; + WriteBurstParams.pusWriteData[ 1 ] = 0xFFFF; + + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get the maximum number of events this firmware supports from the TLVs. */ + pSharedInfo->DebugInfo.usMatrixCBMask = (UINT16)( pSharedInfo->DebugInfo.ulDebugEventSize & 0xFFFF ); + pSharedInfo->DebugInfo.usMatrixCBMask -= 1; + + /* Find out the chip log write pointer. */ + + /* Now get the current write pointer for matrix events. */ + ReadParams.pusReadData = &pSharedInfo->DebugInfo.usChipDebugEventWritePtr; + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixWpBaseAddress + 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.pusReadData = &usReadData; + + /* This write pointer might have wrapped, but we don't know for sure. */ + /* To be confident, the chip frame timestamp is read. */ + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulTimestamp = usReadData << 16; + + ReadParams.ulReadAddress += 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulTimestamp |= usReadData; + + ulTimestamp >>= 12; /* TDM time for 1 event (512 ms) */ + + /* There is a probability here (once very 6.2 days) that the timestamp is close */ + /* to 0, because it has wrapped. But still, we need a way to workaround the highly */ + /* occuring case of the chip just being opened. This will fix this problem. */ + if ( ulTimestamp < (UINT32)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) ) + { + if ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr >= 2 ) + { + /* Must trash the first 2 events. The chip is not yet ready. */ + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - 2 ); + } + else + { + pSharedInfo->DebugInfo.usNumEvents = 0x0; + } + } + else + { + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ); + + /* Account for event being created right now while the chip is running. */ + /* The event at the write pointer will be discarded. */ + if ( pSharedInfo->DebugInfo.usNumEvents > 0 ) + pSharedInfo->DebugInfo.usNumEvents--; + } + + + /* If the user only requested the last 16 seconds, cap the number of events. */ + if ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S + || f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + { + /* x events to get the last 16 seconds. */ + if ( pSharedInfo->DebugInfo.usNumEvents > ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) ) + pSharedInfo->DebugInfo.usNumEvents = (UINT16)( ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) & 0xFFFF ); + } + + /* Make sure that all the events are pertaining to the current hot channel. */ + /* Calculate the event read pointer. */ + ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + /* Travel through the events and throw away the bad events. */ + usTempNumEvents = pSharedInfo->DebugInfo.usNumEvents; + pSharedInfo->DebugInfo.usNumEvents = 0; + for ( ulDebugEventIndex = 0; ulDebugEventIndex < usTempNumEvents; ulDebugEventIndex ++ ) + { + /* The HOT channel index for the event is stored at offset 0xF2 (word offset) */ + + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer; + ReadParams.ulReadAddress += 0xF2 * sizeof(UINT16); + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the current debug index is the same as the one found in the event. */ + if ( usReadData != pSharedInfo->DebugInfo.usCurrentDebugChanIndex ) + pSharedInfo->DebugInfo.usNumEvents = 0; /* As soon as we hit another channel, we reset the number of valid events. */ + else + pSharedInfo->DebugInfo.usNumEvents++; + + /* Increment read pointer to get next event. */ + ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + } + + /* In heavy mode, the AF log pointer is retrieved. */ + if ( ( pSharedInfo->DebugInfo.usNumEvents >= 2 ) + && ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) ) + { + /* The latest AF log write pointer is at the latest matrix event. */ + ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr & pSharedInfo->DebugInfo.usMatrixCBMask ) * 1024 ); + + /* To get the AF log write pointer, which is at offset pSharedInfo->ImageInfo.ulAfWritePtrByteOffset. */ + ReadParams.ulReadAddress += pSharedInfo->DebugInfo.ulAfWritePtrByteOffset; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSharedInfo->DebugInfo.usAfLogWritePtr = usReadData; + + /* The AF event read pointer is the AF write pointer +4096 */ + /* This will make sure we do not get mixed up and fetch events that have */ + /* just been written, but we think are old. */ + + /* To get the exact AF log pointer, the API would have to wait 512 milliseconds to make */ + /* sure logging had stopped. This is not required since missing a few last events is not */ + /* important at this point (the user knows that valid data has already been recorded). */ + pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)( ( pSharedInfo->DebugInfo.usAfLogWritePtr + 4096 ) & 0xFFFF ); + + /* Note that if the chip has just been booted, some of the AF events might not be initialized. */ + } + else + { + pSharedInfo->DebugInfo.usLastAfLogReadPtr = 0; + pSharedInfo->DebugInfo.usAfLogWritePtr = 0; + } + + /* To be aligned correctly for the bursts. */ + while ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) != 0 ) + pSharedInfo->DebugInfo.usLastAfLogReadPtr++; + + /* Remember the data mode for later checks. Also, the user cannot change this "mode". */ + pSharedInfo->DebugInfo.ulCurrentGetDataMode = f_pGetData->ulGetDataMode; + } + else + { + /* Check that the user did not change the current data mode. */ + if ( pSharedInfo->DebugInfo.ulCurrentGetDataMode != f_pGetData->ulGetDataMode ) + return cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE; + } + + /* Check if this is the first pass here. */ + if ( pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes == cOCT6100_INVALID_VALUE ) + { + /* Calculate how many bytes of data will be returned with respect to the selected data content. */ + + /* Check what content type the user requested. */ + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Remember first AF Event Read Pointer. */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr >> 8 ) & 0xFF ); + + /* Remember the AF Event Write Pointer. */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr >> 8 ) & 0xFF ); + + /* Remember law and hot channel */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex >> 2 ) & 0xFE ) ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySoutPcmLaw ); + + /* Insert light or heavy mode in array. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex - 1 ] |= 0x80; + } + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.byRinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex & 0x1F ) << 3 ) ); + + /* Remember usNumEvents */ + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents >> 8 ) & 0xFF ); + } + + /* Last indexes set to '0'! */ + pSharedInfo->DebugInfo.usLastDebugEventIndex = 0; + pSharedInfo->DebugInfo.ulLastPcmSampleIndex = 0; + + /* No tone event has been retrieved. */ + pSharedInfo->DebugInfo.usLastToneEventIndex = 0; + + /* The version strings have not yet been copied. */ + pSharedInfo->DebugInfo.fImageVersionCopied = FALSE; + pSharedInfo->DebugInfo.fApiVersionCopied = FALSE; + + /* Estimate the total size of the buffer that will be returned. */ + f_pGetData->ulTotalNumBytes = ulUserBufWriteIndex; + + /* If the full content is requested, add all the debug data. */ + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Add the matrix events. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + /* Heavy mode! Grab everything! */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + } + else + { + /* Lite mode! Only the most important stuff. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize; + } + + /* Add the PCM samples. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * 3; + + /* If requested, add the AF log events. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + f_pGetData->ulTotalNumBytes += (UINT32)( ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF ) * 16; + } + + /* Add the tone events strings. */ + f_pGetData->ulTotalNumBytes += cOCT6100_TLV_MAX_TONE_NAME_SIZE * pSharedInfo->ImageInfo.byNumToneDetectors; + + /* Add the image version string. */ + f_pGetData->ulTotalNumBytes += 512; + + /* Add the API version string. */ + f_pGetData->ulTotalNumBytes += sizeof( cOCT6100_API_VERSION ); + } + else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + /* Add one PCM stream. */ + f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + } + + /* Save this in the instance for further calls. */ + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = f_pGetData->ulTotalNumBytes; + + /* Calculate remaining bytes. All the bytes for now! */ + f_pGetData->ulRemainingNumBytes = f_pGetData->ulTotalNumBytes; + + /* Save this in the instance for the next calls. */ + pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes = f_pGetData->ulRemainingNumBytes; + } + else + { + f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes; + } + + /* Calculate the event read pointer. */ + ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + + ulReadPointer += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize * pSharedInfo->DebugInfo.usLastDebugEventIndex; + ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + /* Copy the debug events in the user buffer. */ + for( ulDebugEventIndex = pSharedInfo->DebugInfo.usLastDebugEventIndex; ulDebugEventIndex < pSharedInfo->DebugInfo.usNumEvents; ulDebugEventIndex ++ ) + { + ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer; + + /* Check if we are in light or heavy mode. The burst size is not the same. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) + ulNumReads = pSharedInfo->DebugInfo.ulDebugChanStatsByteSize / 2; + else + break; + } + else + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize ) + ulNumReads = pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize / 2; + else + break; + } + + ulTempIndex = 0; + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Copy data byte per byte to avoid endianess problems. */ + for ( ulCopyIndex = 0; ulCopyIndex < ReadBurstParams.ulReadLength; ulCopyIndex ++ ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( ReadBurstParams.pusReadData[ ulCopyIndex ] & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( ReadBurstParams.pusReadData[ ulCopyIndex ] >> 8 ) & 0xFF ); + } + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength * 2; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + + /* Store register 0x202 in the event structure. */ + f_pGetData->pbyData[ ulUserBufWriteIndex + 255 ] = (UINT8)( pSharedInfo->IntrptManage.usRegister202h & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + 256 ] = (UINT8)( ( pSharedInfo->IntrptManage.usRegister202h >> 8 ) & 0xFF ); + + /* Increment index. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize; + } + else + { + ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize; + } + + /* Increment read pointer to get next event. */ + ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + + /* Save in the instance that one of the events was dumped. */ + pSharedInfo->DebugInfo.usLastDebugEventIndex ++; + } + } + + /* Check if all debug events have been transfered. */ + if ( ( ulDebugEventIndex == pSharedInfo->DebugInfo.usNumEvents ) + || ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) ) + { + /* Fetch all streams per event. */ + for ( ulPcmSampleIndex = pSharedInfo->DebugInfo.ulLastPcmSampleIndex; ulPcmSampleIndex < ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); ulPcmSampleIndex ++ ) + { + /* Check if enough room for this sample. */ + if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 1 ) + break; + } + else /* if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 3 ) + break; + } + + /* Check if must retrieve data from external memory. */ + if ( ( ulPcmSampleIndex % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE * 2 ) ) == 0x0 ) + { + ulReadPointer = ( ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) & ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) ); + ulReadPointer += ( ulPcmSampleIndex / pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + ulReadPointer &= ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); + ulReadPointer += ulPcmSampleIndex % pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize; + + /* Retrieve more data from external memory. */ + switch ( f_pGetData->ulGetDataContent ) + { + case cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM: + ulStreamIndexMin = 0; + ulStreamIndexMax = 1; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM: + ulStreamIndexMin = 1; + ulStreamIndexMax = 2; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM: + ulStreamIndexMin = 2; + ulStreamIndexMax = 3; + break; + case cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE: + default: + ulStreamIndexMin = 0; + ulStreamIndexMax = 3; + break; + } + + for ( ulStreamIndex = ulStreamIndexMin; ulStreamIndex < ulStreamIndexMax; ulStreamIndex ++ ) + { + ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase; + /* To get right channel information. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->DebugInfo.ulAfEventCbByteSize; + /* To get correct stream. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * ulStreamIndex ); + /* PCM sample pointer in that stream. */ + ReadBurstParams.ulReadAddress += ulReadPointer; + + /* As much as we can for the burst. */ + ulTempIndex = 0; + ulNumReads = cOCT6100_INTERNAL_SUPER_ARRAY_SIZE; + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + if ( ulStreamIndex == 0 ) + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ]; + else if ( ulStreamIndex == 1 ) + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray1[ ulTempIndex ]; + else /* if ( ulStreamIndex == 2 ) */ + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray2[ ulTempIndex ]; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + } + } + + /* We now have the stream data for all streams for 1 event. */ + /* Return what we can to the user. */ + if ( ( ulPcmSampleIndex % 2 ) == 0 ) + { + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF ); + } + else /* if ( ulPcmSampleIndex % 2 == 1 ) */ + { + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + + if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + || ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) ) + f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF ); + } + + pSharedInfo->DebugInfo.ulLastPcmSampleIndex++; + } + + /* Check if we are done dumping the PCM samples! */ + if ( pSharedInfo->DebugInfo.ulLastPcmSampleIndex == ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) ) + { + if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) + { + + /* Go for the AF events. The AF events are only copied in heavy mode. */ + if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S ) + || ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) + { + while ( pSharedInfo->DebugInfo.usLastAfLogReadPtr != pSharedInfo->DebugInfo.usAfLogWritePtr ) + { + /* Check if enough room for an event. */ + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 16 ) + break; + + /* Check if must fill our buffer. */ + if ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) == 0x0 ) + { + ulNumAfEvents = ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF; + + /* Check for the size of the available buffer. */ + if ( ulNumAfEvents > ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) + ulNumAfEvents = ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ); + + /* Start at channel main base address. */ + ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase; + /* To get right channel information. */ + ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize ); + /* To get the right AF log. */ + ReadBurstParams.ulReadAddress += ( pSharedInfo->DebugInfo.usLastAfLogReadPtr * 16 ); + + ulTempIndex = 0; + ulNumReads = ulNumAfEvents * 8; + + while ( ulNumReads != 0 ) + { + if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + ReadBurstParams.ulReadLength = ulNumReads; + + /* Set pointer where to write data. */ + ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ]; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update indexes, temp variables, addresses. */ + ulNumReads -= ReadBurstParams.ulReadLength; + ulTempIndex += ReadBurstParams.ulReadLength; + ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2; + } + } + + /* Copy data byte per byte to avoid endianess problems. */ + for ( ulCopyIndex = 0; ulCopyIndex < 8; ulCopyIndex ++ ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] >> 8 ) & 0xFF ); + } + + ulUserBufWriteIndex += 16; + + /* Increment AF log read ptr. */ + pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)(( pSharedInfo->DebugInfo.usLastAfLogReadPtr + 1 ) & 0xFFFF ); + } + } + + /* Check if we are done with the AF events. */ + if ( pSharedInfo->DebugInfo.usLastAfLogReadPtr == pSharedInfo->DebugInfo.usAfLogWritePtr ) + { + /* Insert the tone event information. */ + for ( ulToneEventIndex = pSharedInfo->DebugInfo.usLastToneEventIndex; ulToneEventIndex < pSharedInfo->ImageInfo.byNumToneDetectors; ulToneEventIndex++ ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + break; + + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.aToneInfo[ ulToneEventIndex ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + + ulUserBufWriteIndex += cOCT6100_TLV_MAX_TONE_NAME_SIZE; + + pSharedInfo->DebugInfo.usLastToneEventIndex++; + } + + /* If all the tone information has been copied. */ + if ( ulToneEventIndex == pSharedInfo->ImageInfo.byNumToneDetectors ) + { + /* Copy the image version. */ + if ( pSharedInfo->DebugInfo.fImageVersionCopied == FALSE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= 512 ) + { + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.szVersionNumber, 512 ); + + /* Get PLL jitter count from external memory. */ + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Create the mask to retrieve the appropriate value. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Mask data. */ + ulTempData &= ulMask; + /* Move to right position. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] = (UINT8)( ( ulTempData >> 8 ) & 0xFF ); + f_pGetData->pbyData[ ulUserBufWriteIndex + 511 ] = (UINT8)( ( ulTempData >> 0 ) & 0xFF ); + } + + /* Add "ISR is not called" bit. */ + if ( pSharedInfo->IntrptManage.fIsrCalled == FALSE ) + { + f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] |= 0x80; + } + + ulUserBufWriteIndex += 512; + + /* The version has been copied. */ + pSharedInfo->DebugInfo.fImageVersionCopied = TRUE; + } + } + + /* If the image version has been copied, proceed with the API version. */ + if ( pSharedInfo->DebugInfo.fImageVersionCopied == TRUE ) + { + if ( pSharedInfo->DebugInfo.fApiVersionCopied == FALSE ) + { + if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= sizeof(cOCT6100_API_VERSION) ) + { + Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + ulUserBufWriteIndex += sizeof(cOCT6100_API_VERSION); + + /* The API version has been copied. */ + pSharedInfo->DebugInfo.fApiVersionCopied = TRUE; + } + } + } + } + + /* Check if we are done! */ + if ( pSharedInfo->DebugInfo.fApiVersionCopied == TRUE ) + { + /* Done dumping. */ + + /* Reset data being dumpped flag. */ + pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE; + + /* Reset data recording in the chip. */ + WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress; + WriteBurstParams.ulWriteLength = 2; + WriteBurstParams.pusWriteData = pSharedInfo->DebugInfo.ausHotChannelData; + + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + fResetRemainingDataFlag = TRUE; + } + } + } + else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */ + { + fResetRemainingDataFlag = TRUE; + } + } + } + + /* Return number of valid bytes in buffer to user. */ + f_pGetData->ulValidNumBytes = ulUserBufWriteIndex; + + /* Update remaining bytes. */ + pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes -= ulUserBufWriteIndex; + + /* Return remaining bytes. */ + f_pGetData->ulRemainingNumBytes = pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes; + + /* Return total number of bytes. */ + f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes; + + /* Check if we are done dump the requested content. */ + if ( fResetRemainingDataFlag == TRUE ) + pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c new file mode 100644 index 0000000..776c6d9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c @@ -0,0 +1,1379 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to retrieve tone and playout events. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 81 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_playout_buf_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100EventGetTone + +Description: Retreives an array of tone events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetTone Pointer to structure used to store the Tone events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100EventGetToneDef +UINT32 Oct6100EventGetToneDef( + tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + f_pEventGetTone->pToneEvent = NULL; + f_pEventGetTone->ulMaxToneEvent = 1; + f_pEventGetTone->ulNumValidToneEvent = cOCT6100_INVALID_VALUE; + f_pEventGetTone->fMoreEvents = FALSE; + f_pEventGetTone->fResetBufs = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100EventGetTone +UINT32 Oct6100EventGetTone( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutGetEvent + +Description: Retrieves an array of playout stop events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufPlayoutGetEvent Pointer to structure used to store the playout events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutGetEventDef +UINT32 Oct6100BufferPlayoutGetEventDef( + tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + f_pBufPlayoutGetEvent->pBufferPlayoutEvent = NULL; + f_pBufPlayoutGetEvent->ulMaxEvent = 1; + f_pBufPlayoutGetEvent->ulNumValidEvent = cOCT6100_INVALID_VALUE; + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + f_pBufPlayoutGetEvent->fResetBufs = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100BufferPlayoutGetEvent +UINT32 Oct6100BufferPlayoutGetEvent( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetEventsSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the tone events and playout events + software buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetEventsSwSizes +UINT32 Oct6100ApiGetEventsSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + + { + UINT32 ulTempVar; + + /* Memory needed by soft tone event buffers. */ + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + f_pInstSizes->ulSoftToneEventsBuffer = ( f_pOpenChip->ulSoftToneEventsBufSize + 1 ) * sizeof( tOCT6100_API_TONE_EVENT ); + + /* Round off the sizes of the soft buffers above. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar ) + } + + { + UINT32 ulTempVar; + + /* Memory needed by soft playout stop event buffers. */ + if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + { + f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT ); + + /* Round off the sizes of the soft buffers above. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar ) + } + else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */ + { + f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100EventGetToneSer + +Description: Retreives an array of tone event from the software event buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetTone Pointer to structure which will contain the retreived + events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100EventGetToneSer +UINT32 Oct6100EventGetToneSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TONE_EVENT pSoftEvent; + UINT32 ulSoftReadPnt; + UINT32 ulSoftWritePnt; + UINT32 ulSoftBufSize; + UINT32 ulNumEventsReturned; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the parameters given by the user. */ + if ( f_pEventGetTone->fResetBufs != TRUE && + f_pEventGetTone->fResetBufs != FALSE ) + return cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS; + + /* Check max tones. */ + if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize ) + return cOCT6100_ERR_EVENTS_MAX_TONES; + + if ( f_pEventGetTone->fResetBufs == FALSE ) + { + /* Check if the events need to be fetched from the chip buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + if ( ulSoftReadPnt == ulSoftWritePnt ) + { + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If there are no events in the soft buffer then there are none in the chip */ + /* either, so return the empty case. Else, return the events in the buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + ulSoftBufSize = pSharedInfo->SoftBufs.ulToneEventBufferSize; + + if ( ulSoftReadPnt != ulSoftWritePnt ) + { + ulNumEventsReturned = 0; + + while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) ) + { + /* Get a pointer to the first event in the buffer. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += ulSoftReadPnt; + + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulToneDetected = pSoftEvent->ulToneDetected; + f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulExtToneDetectionPort = pSoftEvent->ulExtToneDetectionPort; + + /* Update the pointers of the soft buffer. */ + ulSoftReadPnt++; + if ( ulSoftReadPnt == ulSoftBufSize ) + ulSoftReadPnt = 0; + + ulNumEventsReturned++; + } + + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt; + + /* Detemine if there are more events pending in the soft buffer. */ + if ( ulSoftReadPnt != ulSoftWritePnt ) + f_pEventGetTone->fMoreEvents = TRUE; + else /* ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + f_pEventGetTone->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + } + + f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned; + } + else + { + /* No valid tone.*/ + f_pEventGetTone->ulNumValidToneEvent = 0; + f_pEventGetTone->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + + return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY; + } + } + else /* ( f_pEventGetTone->fResetBufs == TRUE ) */ + { + /* Empty the hardware buffer. */ + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the buffers are to be reset then update the pointers and full flag. */ + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + f_pEventGetTone->fMoreEvents = FALSE; + f_pEventGetTone->ulNumValidToneEvent = 0; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTransferToneEvents + +Description: Transfers all tone events from the PGSP event out chip buffer + to the soft buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulResetBuf Reset flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTransferToneEvents +UINT32 Oct6100ApiTransferToneEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TONE_EVENT pSoftEvent; + tPOCT6100_API_CHANNEL pEchoChannel; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS BurstParams; + UINT32 ulChipBufFill; + UINT32 ulChipWritePtr = 0; + UINT32 ulChipReadPtr = 0; + + UINT32 usChannelIndex; + UINT32 ulBaseTimestamp; + UINT32 ulToneCnt; + UINT32 ulNumWordsToRead; + UINT32 ulEventCode; + + UINT32 ulResult; + UINT32 i, j; + UINT16 usReadData; + UINT16 ausReadData[ cOCT6100_NUM_WORDS_PER_TONE_EVENT ]; + + UINT32 ulExtToneDetectionPort; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* If the buffer is to be reset then clear the overflow flag. */ + if ( f_ulResetBuf == TRUE ) + { + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + } + + /* Set some parameters of read struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Get the current read pointer of the chip buffer. */ + ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_READ_PTR_REG; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulChipReadPtr = usReadData; + + /* Now get the current write pointer. */ + ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_WRITE_PTR_REG; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulChipWritePtr = usReadData; + + ulChipBufFill = (( ulChipWritePtr - ulChipReadPtr ) & ( cOCT6100_NUM_PGSP_EVENT_OUT - 1 )); + + /* Set some parameters of write structs. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Read in the tone event one at a time. */ + for ( i = 0; i < ulChipBufFill; i++ ) + { + /* Skip the event processing if the buffer is to be reset. */ + if ( f_ulResetBuf == TRUE ) + { + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( cOCT6100_NUM_PGSP_EVENT_OUT == ulChipReadPtr ) + ulChipReadPtr = 0; + } + else + { + /* Read in the event only if there's enough room in the soft buffer, and */ + /* the chip buffer is NOT to be reset. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + BurstParams.ulReadAddress = cOCT6100_PGSP_EVENT_OUT_BASE + ( ulChipReadPtr * cOCT6100_PGSP_TONE_EVENT_SIZE ); + BurstParams.pusReadData = ausReadData; + + ulNumWordsToRead = cOCT6100_PGSP_TONE_EVENT_SIZE / 2; + + while ( ulNumWordsToRead > 0 ) + { + if ( ulNumWordsToRead > pSharedInfo->ChipConfig.usMaxRwAccesses ) + { + BurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + } + else + { + BurstParams.ulReadLength = ulNumWordsToRead; + } + + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.pusReadData += BurstParams.ulReadLength; + BurstParams.ulReadAddress += BurstParams.ulReadLength * 2; + + ulNumWordsToRead -= BurstParams.ulReadLength; + } + + /* Verify if the event is valid. */ + if ( ( ausReadData[ 0 ] & cOCT6100_VALID_TONE_EVENT ) == 0x0 ) + return cOCT6100_ERR_FATAL_2D; + + /* First extract the channel number of the tone event. */ + usChannelIndex = ausReadData[ 1 ] & 0x3FF; + + /* Now the timestamp. */ + ulBaseTimestamp = ausReadData[ 2 ] << 16; + ulBaseTimestamp |= ausReadData[ 3 ]; + + /* This timestamp is 256 in adwance, must remove 256 frames. */ + ulBaseTimestamp -= 256; + + /* Fetch the channel stucture to validate which event can be reported. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex ); + + if ( pEchoChannel->fReserved != TRUE ) + { + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT ) + ulChipReadPtr = 0; + + /* This channel has been closed since the generation of the event. */ + continue; + } + + /* Extract the extended tone detection port if available. */ + if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_SIN_PORT_MODE ) + { + ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + } + else if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_RIN_PORT_MODE ) + { + ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_RIN; + + /* Modify the channel index. */ + usChannelIndex = pEchoChannel->usExtToneChanIndex; + + /* Change the channel entry to the original one for statistical purposes. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex ); + + } + else /* pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_DISABLED */ + { + ulExtToneDetectionPort = cOCT6100_INVALID_VALUE; + } + + ulToneCnt = 0; + /* Verify all the possible events that might have been detected. */ + for ( j = 4; j < cOCT6100_NUM_WORDS_PER_TONE_EVENT; j++ ) + { + ulEventCode = ( ausReadData[ j ] >> 8 ) & 0x7; + + if ( ulEventCode != 0x0 ) + { + /* This tone generated an event, now check if event is masked for the channel. */ + if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 ) + { + BOOL f2100Tone; + + /* Check if it is a 2100 Tone STOP and if the user wants receive those events*/ + ulResult = Oct6100ApiIs2100Tone(f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &f2100Tone); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f2100Tone == FALSE) || + ( (f2100Tone == TRUE) && (ulEventCode != 2) ) || + ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) ) + { + + /* If enough space. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + /* The tone event is not masked, The API can create a soft tone event. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + /* Decode the event type. */ + switch( ulEventCode ) + { + case 1: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + case 2: + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + break; + case 3: + /* This one is a little tricky. We first */ + /* generate the "PRESENT" event and then generate the "STOP" event. */ + + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + /* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */ + pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1; + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* If enough space for the "STOP" event. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + continue; + } + + break; + case 4: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + default: + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++; + /* do not process this packet*/ + continue; + } + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + } + } + else + { + BOOL fSSTone; + + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Check if this is a "PRESENT" or "STOP" event */ + switch( ulEventCode ) + { + case 1: + /* This is a signaling system present event. Keep this in the instance memory. */ + pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + break; + case 2: + /* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */ + pEchoChannel->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pEchoChannel->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + break; + default: + break; + } + } + } + } + ulToneCnt++; + + /* Check the other tone of this word. */ + ulEventCode = ausReadData[ j ] & 0x7; + + if ( ulEventCode != 0x0 ) + { + if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 ) + { + BOOL f2100Tone; + + /* Check if it is a 2100 Tone STOP and if the user wants receive those events*/ + ulResult = Oct6100ApiIs2100Tone(f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &f2100Tone); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f2100Tone == FALSE) || + ( (f2100Tone == TRUE) && (ulEventCode != 2) ) || + ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) ) + { + + /* If enough space. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + /* The tone event is not masked, The API can create a soft tone event. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + /* Decode the event type. */ + switch( ulEventCode ) + { + case 1: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + case 2: + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + break; + case 3: + /* This one is a little tricky. We first */ + /* generate the "PRESENT" event and then generate the "STOP" event. */ + + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + /* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */ + pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1; + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* If enough space for the "STOP" event. */ + if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) && + ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) ) + { + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulEventType = cOCT6100_TONE_STOP; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + continue; + } + + break; + case 4: + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + break; + default: + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++; + /* Do not process this packet. */ + continue; + } + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + } + } + else + { + BOOL fSSTone; + + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Check if this is a "PRESENT" event. */ + switch ( ulEventCode ) + { + case 1: + /* This is a signaling system present event. Keep this in the instance memory. */ + pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID; + pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ); + break; + case 2: + /* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */ + pEchoChannel->ulLastSSToneDetected = (PTR_TYPE)cOCT6100_INVALID_VALUE; + pEchoChannel->ulLastSSToneTimestamp = (PTR_TYPE)cOCT6100_INVALID_VALUE; + break; + default: + break; + } + } + } + } + ulToneCnt++; + } + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + + /* We continue in the loop in order to empty the hardware buffer. */ + } + + /* Update the control variables of the buffer. */ + ulChipReadPtr++; + if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT ) + ulChipReadPtr = 0; + } + } + + /* Write the value of the new Read pointer.*/ + WriteParams.ulWriteAddress = cOCT6100_TONE_EVENT_READ_PTR_REG; + WriteParams.usWriteData = (UINT16)( ulChipReadPtr ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutGetEventSer + +Description: Retreives an array of buffer playout event from the software + event buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pEventGetPlayoutStop Pointer to structure which will contain the retreived + events. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutGetEventSer +UINT32 Oct6100BufferPlayoutGetEventSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent; + UINT32 ulSoftReadPnt; + UINT32 ulSoftWritePnt; + UINT32 ulSoftBufSize; + UINT32 ulNumEventsReturned; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the parameters past by the user. */ + if ( f_pBufPlayoutGetEvent->fResetBufs != TRUE && + f_pBufPlayoutGetEvent->fResetBufs != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET; + + /* Check if software buffer has been allocated and thus enabled. */ + if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED; + + /* Checking max playout events. */ + if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize ) + return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT; + + if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE ) + { + /* Check if events need to be fetched from the chip. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + + if ( ulSoftReadPnt == ulSoftWritePnt ) + { + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* If there are no events in the soft buffer then there are none in the chip */ + /* either, so return the empty case. Else, return the events in the buffer. */ + ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr; + ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + ulSoftBufSize = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize; + + if ( ulSoftReadPnt != ulSoftWritePnt ) + { + ulNumEventsReturned = 0; + + while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) ) + { + /* Get a pointer to the first event in the buffer. */ + mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += ulSoftReadPnt; + + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelPort = pSoftEvent->ulChannelPort; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserEventId = pSoftEvent->ulUserEventId; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType; + f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp; + + /* Update the pointers of the soft buffer. */ + ulSoftReadPnt++; + if ( ulSoftReadPnt == ulSoftBufSize ) + ulSoftReadPnt = 0; + + ulNumEventsReturned++; + } + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt; + + /* Detemine if there are more events pending in the soft buffer. */ + if ( ulSoftReadPnt != ulSoftWritePnt ) + f_pBufPlayoutGetEvent->fMoreEvents = TRUE; + else /* ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + } + + f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned; + } + else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */ + { + /* No valid buffer playout events. */ + f_pBufPlayoutGetEvent->ulNumValidEvent = 0; + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY; + } + } + else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */ + { + /* Check with the hardware first. */ + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the buffers are to be reset, then update the pointers and full flag. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + + f_pBufPlayoutGetEvent->fMoreEvents = FALSE; + f_pBufPlayoutGetEvent->ulNumValidEvent = 0; + + /* Remember this state in the interrupt manager. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutTransferEvents + +Description: Check all channels that are currently playing a buffer and + generate an event if a buffer has stopped playing. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulResetBuf Reset flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutTransferEvents +UINT32 Oct6100BufferPlayoutTransferEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pEchoChannel; + + UINT32 ulChannelIndex; + UINT32 ulResult; + UINT32 ulLastBufPlayoutEventBufferOverflowCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* If the buffer is to be reset then clear the overflow flag. */ + if ( f_ulResetBuf == TRUE ) + { + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + /* We are done for now. */ + /* No need to check for new events since the user requested to empty the soft buffer. */ + return cOCT6100_ERR_OK; + } + + /* Check if buffer playout has been activated on some ports. */ + if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 ) + { + /* Buffer playout has not been activated on any channel, */ + /* let's not waste time here. */ + return cOCT6100_ERR_OK; + } + + /* Save the current overflow count. We want to know if an overflow occured to get out of the loop. */ + ulLastBufPlayoutEventBufferOverflowCnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt; + + /* Search through the list of API channel entry for the ones that need playout event checking. */ + for ( ulChannelIndex = 0; ulChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; ulChannelIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex ); + + /* Check if buffer playout is active on this channel, using the optimization flag. */ + /* This flag is redundant of other flags used for playout, but will make the above loop */ + /* much faster. This is needed since this function is called very frequently on systems */ + /* which use buffer playout stop events. */ + if ( pEchoChannel->fBufPlayoutActive == TRUE ) + { + /* Read in the event only if there's enough room in the soft buffer. */ + if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) + { + /* Check Rout buffer playout first. */ + if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE ) + && ( pEchoChannel->fRinBufPlaying == TRUE ) ) + { + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */ + { + /* Get out of the loop, no more events can be inserted in the soft buffer. */ + break; + } + + /* An overflow might have been detected in the lower level function. */ + /* Check the overflow count once again to make sure there might be room for a next event. */ + if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) + { + /* Check Sout buffer playout. */ + if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE ) + && ( pEchoChannel->fSoutBufPlaying == TRUE ) ) + { + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */ + { + /* Get out of the loop, no more events can be inserted in the soft buffer. */ + break; + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutCheckForSpecificEvent + +Description: Check a specific channel/port for playout buffer events. + If asked to, save this event to the software event buffer. + Return a flag specifying whether the event was detected or not. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel to be checked. +f_ulChannelPort Port of the channel to be checked. +f_fSaveToSoftBuffer Save event to software buffer. +f_pfEventDetected Whether or not an event was detected. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutCheckForSpecificEvent +UINT32 Oct6100BufferPlayoutCheckForSpecificEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulChannelPort, + IN BOOL f_fSaveToSoftBuffer, + OUT PBOOL f_pfEventDetected ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent; + tPOCT6100_API_CHANNEL pEchoChannel; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_GET_TIME GetTimeParms; + + UINT32 ulResult; + UINT16 usReadData; + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulTempData; + UINT32 ulReadPtr; + UINT32 ulMask; + UINT32 ulWritePtr; + UINT32 ulUserEventId; + UINT32 ulEventType; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Compare the read and write pointers for matching. If they matched, playout stopped. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check on the Rout port. */ + ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId; + ulEventType = pEchoChannel->byRinPlayoutStopEventType; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + /* Check on the Sout port. */ + ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId; + ulEventType = pEchoChannel->bySoutPlayoutStopEventType; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /* Retrieve the current write pointer. */ + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulPlayoutBaseAddress + ulWritePtrBytesOfst, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer.*/ + ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst; + + /* Read the read pointer.*/ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr != ulWritePtr ) + { + /* Still playing -- do not generate an event. */ + if ( f_pfEventDetected != NULL ) + *f_pfEventDetected = FALSE; + } + else + { + /* Buffer stopped playing, generate an event here, if asked. */ + if ( ( f_fSaveToSoftBuffer == TRUE ) + && ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr ) + && ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize || pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr != 0 ) ) + { + /* The API can create a soft buffer playout event. */ + mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr; + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex; + pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId; + pSoftEvent->ulUserEventId = ulUserEventId; + pSoftEvent->ulChannelPort = f_ulChannelPort; + /* For now, only this type of event is available. */ + pSoftEvent->ulEventType = ulEventType; + + /* Generate millisecond timestamp. */ + GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext; + ulResult = Oct6100UserGetTime( &GetTimeParms ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 ); + pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 ); + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize ) + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some playout events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = TRUE; + } + else if ( f_fSaveToSoftBuffer == TRUE ) + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++; + } + + /* Update the channel entry to set the playing flag to FALSE. */ + + /* Select the port of interest. */ + if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Decrement the number of active buffer playout ports. */ + /* No need to check anything here, it's been done in the calling function. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + + pEchoChannel->fRinBufPlaying = FALSE; + pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Decrement the number of active buffer playout ports. */ + /* No need to check anything here, it's been done in the calling function. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + + pEchoChannel->fSoutBufPlaying = FALSE; + pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + + /* Return that an event was detected. */ + if ( f_pfEventDetected != NULL ) + *f_pfEventDetected = TRUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c new file mode 100644 index 0000000..898267d --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c @@ -0,0 +1,1997 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the API's interrupt service routine and all of its + sub-functions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 81 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_interrupts_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptConfigure + +Description: Configure the operation of all possible interrupt sources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptConfigureDef +UINT32 Oct6100InterruptConfigureDef( + tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + f_pIntrptConfig->ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pIntrptConfig->ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pIntrptConfig->ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pIntrptConfig->ulFatalMemoryTimeout = 100; + + f_pIntrptConfig->ulErrorMemoryTimeout = 100; + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout = 100; + f_pIntrptConfig->ulErrorH100Timeout = 100; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100InterruptConfigure +UINT32 Oct6100InterruptConfigure( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulResult; + UINT32 ulFncRes; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Create serialization object for ISR. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulResult = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call serialized sub-function. */ + ulFncRes = Oct6100InterruptConfigureSer( f_pApiInstance, f_pIntrptConfig, TRUE ); + /* Release serialization object. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulResult = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error occured in sub-function. */ + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptServiceRoutine + +Description: The API's interrupt service routine. This function clears all + register ROLs which have generated an interrupt and report the + events in the user supplied structure. Also, the tone event + and/or playout event buffer will be emptied if valid events + are present. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to structure containing event flags returned + to user. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptServiceRoutineDef +UINT32 Oct6100InterruptServiceRoutineDef( + tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + f_pIntFlags->fFatalGeneral = FALSE; + f_pIntFlags->ulFatalGeneralFlags = 0x0; + f_pIntFlags->fFatalReadTimeout = FALSE; + + f_pIntFlags->fErrorRefreshTooLate = FALSE; + f_pIntFlags->fErrorPllJitter = FALSE; + + f_pIntFlags->fErrorOverflowToneEvents = FALSE; + + f_pIntFlags->fErrorH100OutOfSync = FALSE; + f_pIntFlags->fErrorH100ClkA = FALSE; + f_pIntFlags->fErrorH100ClkB = FALSE; + f_pIntFlags->fErrorH100FrameA = FALSE; + + f_pIntFlags->fToneEventsPending = FALSE; + f_pIntFlags->fBufferPlayoutEventsPending = FALSE; + + f_pIntFlags->fApiSynch = FALSE; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100InterruptServiceRoutine +UINT32 Oct6100InterruptServiceRoutine( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulResult; + UINT32 ulFncRes; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize the serialization object for the ISR. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulResult = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Call the serialized sub-function. */ + ulFncRes = Oct6100InterruptServiceRoutineSer( f_pApiInstance, f_pIntFlags ); + } + else + { + return ulResult; + } + + /* Release the serialization object. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulResult = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for an error in the sub-function. */ + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsrSwInit + +Description: Initializes portions of API instance associated to the API's + interrupt service routine. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsrSwInit +UINT32 Oct6100ApiIsrSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the state of each interrupt group to disabled. The state will */ + /* be updated to the true configuration once the configure interrupts function is called. */ + pSharedInfo->IntrptManage.byFatalGeneralState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byFatalMemoryState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorMemoryState = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorH100State = cOCT6100_INTRPT_DISABLED; + pSharedInfo->IntrptManage.byErrorOverflowToneEventsState = cOCT6100_INTRPT_DISABLED; + + /* Indicate that the mclk interrupt is not active at the moment. */ + pSharedInfo->IntrptManage.fMclkIntrptActive = FALSE; + + /* Indicate that no buffer playout events are pending for the moment. */ + pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE; + + /* Indicate that no tone events are pending for the moment. */ + pSharedInfo->IntrptManage.fToneEventsPending = FALSE; + + /* The ISR has never been called. */ + pSharedInfo->IntrptManage.fIsrCalled = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsrHwInit + +Description: Initializes the chip's interrupt registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to structure defining how the interrupts + should be configured. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsrHwInit +UINT32 Oct6100ApiIsrHwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Enable all the interrupts */ + + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0001; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x1C05; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0xFFFF; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x504; + WriteParams.usWriteData = 0x0002; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0007; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + /* Calculate the number of mclk cycles in 1 ms. */ + f_pApiInstance->pSharedInfo->IntrptManage.ulNumMclkCyclesIn1Ms = f_pApiInstance->pSharedInfo->MiscVars.ulMclkFreq / 1000; + + /* Configure the interrupt registers as requested by the user. */ + ulResult = Oct6100InterruptConfigureSer( f_pApiInstance, f_pIntrptConfig, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptConfigureSer + +Description: Configure the operation of interrupt groups. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. +f_fCheckParams Check parameter enable flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptConfigureSer +UINT32 Oct6100InterruptConfigureSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig, + IN BOOL f_fCheckParams ) +{ + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + UINT32 ulResult; + + /* Check for errors. */ + if ( f_fCheckParams == TRUE ) + { + if ( f_pIntrptConfig->ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_FATAL_GENERAL_CONFIG; + if ( f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_FATAL_MEMORY_CONFIG; + if ( f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_CONFIG; + if ( f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_CONFIG; + if ( f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE && + f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pIntrptConfig->ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT ) + return cOCT6100_ERR_INTRPTS_H100_ERROR_CONFIG; + + if ( f_pIntrptConfig->ulFatalMemoryTimeout < 10 || + f_pIntrptConfig->ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_FATAL_MEMORY_TIMEOUT; + if ( f_pIntrptConfig->ulErrorMemoryTimeout < 10 || + f_pIntrptConfig->ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_TIMEOUT; + if ( f_pIntrptConfig->ulErrorOverflowToneEventsTimeout < 10 || + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_TIMEOUT; + if ( f_pIntrptConfig->ulErrorH100Timeout < 10 || + f_pIntrptConfig->ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_INTRPTS_H100_ERROR_TIMEOUT; + } + + /* Copy the configuration to the API instance. */ + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + pIntrptConfig->byFatalGeneralConfig = (UINT8)( f_pIntrptConfig->ulFatalGeneralConfig & 0xFF ); + pIntrptConfig->byFatalMemoryConfig = (UINT8)( f_pIntrptConfig->ulFatalMemoryConfig & 0xFF ); + pIntrptConfig->byErrorMemoryConfig = (UINT8)( f_pIntrptConfig->ulErrorMemoryConfig & 0xFF ); + pIntrptConfig->byErrorOverflowToneEventsConfig = (UINT8)( f_pIntrptConfig->ulErrorOverflowToneEventsConfig & 0xFF ); + pIntrptConfig->byErrorH100Config = (UINT8)( f_pIntrptConfig->ulErrorH100Config & 0xFF ); + + f_pIntrptConfig->ulFatalMemoryTimeout = ((f_pIntrptConfig->ulFatalMemoryTimeout + 9) / 10) * 10; + pIntrptConfig->ulFatalMemoryTimeoutMclk = f_pIntrptConfig->ulFatalMemoryTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorMemoryTimeout = ((f_pIntrptConfig->ulErrorMemoryTimeout + 9) / 10) * 10; + pIntrptConfig->ulErrorMemoryTimeoutMclk = f_pIntrptConfig->ulErrorMemoryTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorOverflowToneEventsTimeout = ((f_pIntrptConfig->ulErrorOverflowToneEventsTimeout + 9) / 10) * 10; + pIntrptConfig->ulErrorOverflowToneEventsTimeoutMclk = f_pIntrptConfig->ulErrorOverflowToneEventsTimeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + f_pIntrptConfig->ulErrorH100Timeout = ((f_pIntrptConfig->ulErrorH100Timeout + 9) / 10) * 10; + pIntrptConfig->ulErrorH100TimeoutMclk = f_pIntrptConfig->ulErrorH100Timeout * pIntrptManage->ulNumMclkCyclesIn1Ms; + + + /*Clear all interrupts that were already enabled*/ + ulResult = Oct6100ApiClearEnabledInterrupts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Before writing the new configuration to the chip's registers, make sure that any */ + /* interrupts which are either disabled or have no timeout period are not on the */ + /* disabled interrupt list. */ + + /*==================================================================================*/ + if ( pIntrptConfig->byFatalGeneralConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byFatalGeneralState = cOCT6100_INTRPT_DISABLED; + else /* pIntrptConfig->byFatalGeneralConfig == cOCT6100_INTERRUPT_NO_TIMEOUT */ + pIntrptManage->byFatalGeneralState = cOCT6100_INTRPT_ACTIVE; + + /*==================================================================================*/ + if ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_ACTIVE; + else /* ( pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_ACTIVE; + } + + /*==================================================================================*/ + if ( pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_DISABLE ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_DISABLED; + else if ( pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_NO_TIMEOUT ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_ACTIVE; + else /* (pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_TIMEOUT ) */ + { + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_DISABLED ) + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_ACTIVE; + } + + + /* Write to the interrupt registers to update the state of each interrupt group. */ + ulResult = Oct6100ApiWriteIeRegs( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearEnabledInterrupts + +Description: Disabled interruption are not reported but still available. This + function will clear the interrupts that were disabled and wish + to enable now. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntrptConfig Pointer to interrupt configuration structure. +f_pIntrptManage Pointer to interrupt manager structure. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#if !SKIP_Oct6100ApiClearEnabledInterrupts +UINT32 Oct6100ApiClearEnabledInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy the configuration to the API instance. */ + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + if ( pIntrptConfig->byFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byFatalGeneralState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_102H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = 0x1800; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_502H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_202H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorH100Config != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorH100State != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_302H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pIntrptConfig->byErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE && + pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_DISABLED ) + { + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_702H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + return cOCT6100_ERR_OK; + +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptServiceRoutineSer + +Description: Serialized sub-function of API's interrupt service routine. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to structure containing event flags returned + to user. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100InterruptServiceRoutineSer +UINT32 Oct6100InterruptServiceRoutineSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulRegister210h; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Must update the statistics. Set parameters in read and write structs. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set all the flags to default values to make sure the variables are initialized. */ + f_pIntFlags->fFatalGeneral = FALSE; + f_pIntFlags->ulFatalGeneralFlags = 0x0; + f_pIntFlags->fFatalReadTimeout = FALSE; + + f_pIntFlags->fErrorRefreshTooLate = FALSE; + f_pIntFlags->fErrorPllJitter = FALSE; + + f_pIntFlags->fErrorH100OutOfSync = FALSE; + f_pIntFlags->fErrorH100ClkA = FALSE; + f_pIntFlags->fErrorH100ClkB = FALSE; + f_pIntFlags->fErrorH100FrameA = FALSE; + f_pIntFlags->fApiSynch = FALSE; + + f_pIntFlags->fErrorOverflowToneEvents = FALSE; + + /* Start by reading registers 210h to determine if any modules have flagged an interrupt. */ + ReadParams.ulReadAddress = 0x210; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + ulRegister210h = usReadData; + + /* Update the extended mclk counter. */ + ulResult = Oct6100ApiReadChipMclkTime( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the mclk interrupt is active then check which interrupt timeout periods have expired. */ + ReadParams.ulReadAddress = 0x302; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( (usReadData & 0x1) != 0 && pSharedInfo->IntrptManage.fMclkIntrptActive == TRUE ) + { + /* Update timeout periods. */ + ulResult = Oct6100ApiUpdateIntrptTimeouts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pIntFlags->fApiSynch = TRUE; + + /* Read registers 210h and 212h again to determine if any modules have flagged an interrupt. */ + ReadParams.ulReadAddress = 0x210; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + ulRegister210h = usReadData; + } + + /* Read the interrupt registers to determine what interrupt conditions have occured. */ + ulResult = Oct6100ApiReadIntrptRegs( f_pApiInstance, f_pIntFlags, ulRegister210h ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Empty the tone buffer if any events are pending. */ + ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the tone events pending flag. */ + f_pIntFlags->fToneEventsPending = pSharedInfo->IntrptManage.fToneEventsPending; + + /* Check for buffer playout events and insert in the software queue -- if activated. */ + if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize != 0 ) + { + ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the buffer playout events pending flag. */ + f_pIntFlags->fBufferPlayoutEventsPending = pSharedInfo->IntrptManage.fBufferPlayoutEventsPending; + } + else + { + f_pIntFlags->fBufferPlayoutEventsPending = FALSE; + } + + /* Update the states of each interrupt group. */ + ulResult = Oct6100ApiUpdateIntrptStates( f_pApiInstance, f_pIntFlags ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check the state of the NLP timestamp if required.*/ + ulResult = Oct6100ApiCheckProcessorState( f_pApiInstance, f_pIntFlags ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to the necessary IE registers. */ + ulResult = Oct6100ApiWriteIntrptRegs( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Schedule the next mclk interrupt, if one is needed. */ + ulResult = Oct6100ApiScheduleNextMclkIntrptSer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Indicate that the interrupt ROLs have been treated. */ + WriteParams.ulWriteAddress = 0x212; + WriteParams.usWriteData = 0x8000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadIntrptRegs + +Description: Reads the interrupt registers of all modules currently + indicating an interrupt condition. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to an interrupt flag structure. +f_ulRegister210h Value of register 0x210. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadIntrptRegs +UINT32 Oct6100ApiReadIntrptRegs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags, + IN UINT32 f_ulRegister210h ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_ERROR_STATS pErrorStats; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + UINT16 usReadData; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulTempData; + UINT32 ulCounterValue; + UINT32 ulMask; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + pErrorStats = &pSharedInfo->ErrorStats; + pIntrptManage = &pSharedInfo->IntrptManage; + + /* Set some parameters of read struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* CPU registers. */ + if ( (f_ulRegister210h & 0x00001) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x102; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupt(s) were set. */ + if ( (usReadData & 0x0001) != 0 ) + { + f_pIntFlags->fFatalReadTimeout = TRUE; + pErrorStats->ulInternalReadTimeoutCnt++; + } + + pIntrptManage->usRegister102h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister102h = 0x0; + } + + /* MAIN registers. */ + if ( (f_ulRegister210h & 0x00002) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x202; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save current value in instance. */ + pIntrptManage->usRegister202h = usReadData; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0001) != 0 ) + { + f_pIntFlags->fErrorRefreshTooLate = TRUE; + pErrorStats->ulSdramRefreshTooLateCnt++; + } + if ( (usReadData & 0x0800) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_1; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + if ( (usReadData & 0x1000) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_2; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + if ( (usReadData & 0x0400) != 0 ) + { + f_pIntFlags->fErrorPllJitter = TRUE; + pErrorStats->ulPllJitterErrorCnt++; + + /* Update the PLL jitter error count here. */ + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Update counter. */ + ulCounterValue = ulTempData & ulMask; + ulCounterValue = ulCounterValue >> ulFeatureBitOffset; + ulCounterValue ++; + /* Handle wrap around case. */ + ulCounterValue &= ( 1 << ulFeatureFieldLength ) - 1; + + /* Clear old counter value. */ + ulTempData &= (~ulMask); + ulTempData |= ulCounterValue << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister202h = 0x0; + } + + /* H.100 registers. */ + if ( (f_ulRegister210h & 0x00004) != 0 ) + { + /*=======================================================================*/ + /* Read registers of this module. */ + ReadParams.ulReadAddress = 0x302; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0100) != 0 ) + { + f_pIntFlags->fErrorH100OutOfSync = TRUE; + pErrorStats->ulH100OutOfSyncCnt++; + } + if ( (usReadData & 0x1000) != 0 ) + { + f_pIntFlags->fErrorH100FrameA = TRUE; + pErrorStats->ulH100FrameABadCnt++; + } + if ( (usReadData & 0x4000) != 0 ) + { + f_pIntFlags->fErrorH100ClkA = TRUE; + pErrorStats->ulH100ClkABadCnt++; + } + if ( (usReadData & 0x8000) != 0 ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + f_pIntFlags->fErrorH100ClkB = TRUE; + pErrorStats->ulH100ClkBBadCnt++; + } + } + + pIntrptManage->usRegister302h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister302h = 0x0; + } + + /* TDMIE registers. */ + if ( (f_ulRegister210h & 0x00010) != 0 ) + { + /*=======================================================================*/ + /* Read register. */ + ReadParams.ulReadAddress = 0x502; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0002) != 0 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_3; + f_pIntFlags->fFatalGeneral = TRUE; + pErrorStats->fFatalChipError = TRUE; + } + + pIntrptManage->usRegister502h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister502h = 0x0; + } + + /* PGSP registers. */ + if ( (f_ulRegister210h & 0x00080) != 0 ) + { + /*=======================================================================*/ + /* Read register. */ + ReadParams.ulReadAddress = 0x702; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check which interrupts were set. */ + if ( (usReadData & 0x0002) != 0 ) + { + f_pIntFlags->fErrorOverflowToneEvents = TRUE; + pErrorStats->ulOverflowToneEventsCnt++; + } + + pIntrptManage->usRegister702h = usReadData; + /*=======================================================================*/ + } + else + { + pIntrptManage->usRegister702h = 0x0; + } + + + + /* If this is the first time the ISR is called, clear the ISR is not called bit */ + /* in external memory to signal the remote client that we are called. */ + if ( pSharedInfo->IntrptManage.fIsrCalled == FALSE ) + { + /* Remember that we are being called. */ + pSharedInfo->IntrptManage.fIsrCalled = TRUE; + + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear the field. */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateIntrptStates + +Description: Updates the state of all interrupt register groups. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Interrupt flags. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateIntrptStates +UINT32 Oct6100ApiUpdateIntrptStates( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + + pIntrptConfig = &f_pApiInstance->pSharedInfo->IntrptConfig; + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /*-----------------------------------------------------------------------*/ + if ( ( f_pIntFlags->fFatalReadTimeout == TRUE) && + pIntrptConfig->byFatalMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byFatalMemoryState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulFatalMemoryDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulFatalMemoryDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorRefreshTooLate == TRUE || + f_pIntFlags->fErrorPllJitter == TRUE ) && + pIntrptConfig->byErrorMemoryConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorMemoryState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorMemoryDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorMemoryDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorOverflowToneEvents == TRUE) && + pIntrptConfig->byErrorOverflowToneEventsConfig == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorOverflowToneEventsState = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorOverflowToneEventsDisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorOverflowToneEventsDisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + if ( (f_pIntFlags->fErrorH100OutOfSync == TRUE || + f_pIntFlags->fErrorH100ClkA == TRUE || + f_pIntFlags->fErrorH100ClkB == TRUE || + f_pIntFlags->fErrorH100FrameA == TRUE ) && + pIntrptConfig->byErrorH100Config == cOCT6100_INTERRUPT_TIMEOUT && + pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + pIntrptManage->byErrorH100State = cOCT6100_INTRPT_WILL_TIMEOUT; + pIntrptManage->ulErrorH100DisableMclkHigh = pIntrptManage->ulRegMclkTimeHigh; + pIntrptManage->ulErrorH100DisableMclkLow = pIntrptManage->ulRegMclkTimeLow; + } + /*-----------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteIntrptRegs + +Description: Writes to interrupt registers to clear interrupt condition, and + writes to an interrupt's IE register if interrupt is to time + out. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteIntrptRegs +UINT32 Oct6100ApiWriteIntrptRegs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + + /* Get some local pointers. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + + + /*===========================================================================*/ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister102h & cOCT6100_INTRPT_MASK_REG_102H) != 0 ) + { + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = pIntrptManage->usRegister102h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT || + pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister202h & cOCT6100_INTRPT_MASK_REG_202H) != 0 ) + { + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = pIntrptManage->usRegister202h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister302h & cOCT6100_INTRPT_MASK_REG_302H) != 0 ) + { + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = pIntrptManage->usRegister302h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( (pIntrptManage->usRegister502h & cOCT6100_INTRPT_MASK_REG_502H) != 0 ) + { + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = pIntrptManage->usRegister502h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + /*===========================================================================*/ + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_WILL_TIMEOUT ) + { + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + if ( (pIntrptManage->usRegister702h & cOCT6100_INTRPT_MASK_REG_702H) != 0 ) + { + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = pIntrptManage->usRegister702h; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*===========================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteIeRegs + +Description: Writes the IE field of each interrupt register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteIeRegs +UINT32 Oct6100ApiWriteIeRegs( + tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get some local pointers. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x504; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalGeneralState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + /*==================================================================================*/ + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + + /*==================================================================================*/ + /* Enable the GLOBAL IEs for the interrupt pin. */ + WriteParams.ulWriteAddress = 0x218; + WriteParams.usWriteData = 0x00D7; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadChipMclkTime + +Description: Reads the chip's mclk cycle count to construct a chip time. + The time is used to manage interrupts. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadChipMclkTime +UINT32 Oct6100ApiReadChipMclkTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulCheckData; + UINT32 ulResult; + UINT32 i; + UINT16 usReadData; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + pIntrptManage = &pSharedInfo->IntrptManage; + + /* Assign memory for read data. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Perform reads. */ + for ( i = 0; i < 100; i++ ) + { + ReadParams.ulReadAddress = 0x306; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + pIntrptManage->ulRegMclkTimeHigh = usReadData & 0xFF; + ulCheckData = usReadData; + + ReadParams.ulReadAddress = 0x308; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + pIntrptManage->ulRegMclkTimeLow = (usReadData & 0xFFFF) << 16; + + ReadParams.ulReadAddress = 0x306; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( ulCheckData == usReadData ) + break; + } + + if ( i == 100 ) + return cOCT6100_ERR_FATAL_2F; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateIntrptTimeouts + +Description: Checks which interrupt groups have finished their timeout + period. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateIntrptTimeouts +UINT32 Oct6100ApiUpdateIntrptTimeouts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulRegMclkTimePlus5MsHigh; + UINT32 ulRegMclkTimePlus5MsLow; + UINT32 ulResult; + BOOL fFatalMemoryChange = FALSE; + BOOL fDataErrMemoryChange = FALSE; + BOOL fErrorOverflowToneEventsChange = FALSE; + BOOL fH100ErrorChange = FALSE; + + /* Get local pointer to interrupt management structure. */ + pIntrptManage = &f_pApiInstance->pSharedInfo->IntrptManage; + + /* Calculate mclk time + 5 ms. */ + ulRegMclkTimePlus5MsLow = pIntrptManage->ulRegMclkTimeLow + (5 * pIntrptManage->ulNumMclkCyclesIn1Ms); + if ( ulRegMclkTimePlus5MsLow < pIntrptManage->ulRegMclkTimeLow ) + ulRegMclkTimePlus5MsHigh = pIntrptManage->ulRegMclkTimeHigh + 1; + else /* ( ulRegMclkTimePlus5MsLow >= pIntrptManage->ulRegMclkTimeLow ) */ + ulRegMclkTimePlus5MsHigh = pIntrptManage->ulRegMclkTimeHigh; + + /* Check which interrupts are timed out and need to be reenabled now. */ + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulFatalMemoryDisableMclkHigh, pIntrptManage->ulFatalMemoryDisableMclkLow, pIntrptManage->ulFatalMemoryEnableMclkHigh, pIntrptManage->ulFatalMemoryEnableMclkLow, pIntrptManage->byFatalMemoryState, fFatalMemoryChange ) + } + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorMemoryDisableMclkHigh, pIntrptManage->ulErrorMemoryDisableMclkLow, pIntrptManage->ulErrorMemoryEnableMclkHigh, pIntrptManage->ulErrorMemoryEnableMclkLow, pIntrptManage->byErrorMemoryState, fDataErrMemoryChange ) + } + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorOverflowToneEventsDisableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsDisableMclkLow, pIntrptManage->ulErrorOverflowToneEventsEnableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsEnableMclkLow, pIntrptManage->byErrorOverflowToneEventsState, fErrorOverflowToneEventsChange ) + } + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_IN_TIMEOUT ) + { + mOCT6100_CHECK_INTRPT_TIMEOUT( ulRegMclkTimePlus5MsHigh, ulRegMclkTimePlus5MsLow, pIntrptManage->ulErrorH100DisableMclkHigh, pIntrptManage->ulErrorH100DisableMclkLow, pIntrptManage->ulErrorH100EnableMclkHigh, pIntrptManage->ulErrorH100EnableMclkLow, pIntrptManage->byErrorH100State, fH100ErrorChange ) + } + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write to the IE registers which have changed. */ + + /*==================================================================================*/ + if ( fFatalMemoryChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x104; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + /*==================================================================================*/ + if ( fFatalMemoryChange == TRUE || + fDataErrMemoryChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x204; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byFatalMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x1800; + if ( pIntrptManage->byErrorMemoryState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0401; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + /*==================================================================================*/ + if ( pIntrptManage->fMclkIntrptActive == TRUE || + fH100ErrorChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData |= 0x0001; + + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + + /*==================================================================================*/ + if ( fErrorOverflowToneEventsChange == TRUE ) + { + WriteParams.ulWriteAddress = 0x704; + WriteParams.usWriteData = 0x0000; + + if ( pIntrptManage->byErrorOverflowToneEventsState == cOCT6100_INTRPT_ACTIVE ) + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiScheduleNextMclkIntrptSer + +Description: Serialized sub-function of Oct6100ApiScheduleNextMclkIntrpt. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiScheduleNextMclkIntrptSer +UINT32 Oct6100ApiScheduleNextMclkIntrptSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_INTRPT_CONFIG pIntrptConfig; + tPOCT6100_API_INTRPT_MANAGE pIntrptManage; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulTimeDiff; + UINT32 ulRegMclkTimeHigh; + UINT32 ulRegMclkTimeLow; + UINT32 ulResult; + BOOL fConditionFlag = TRUE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain temporary pointers to reduce indirection, thus speeding up processing. */ + pIntrptConfig = &pSharedInfo->IntrptConfig; + pIntrptManage = &pSharedInfo->IntrptManage; + ulRegMclkTimeHigh = pIntrptManage->ulRegMclkTimeHigh; + ulRegMclkTimeLow = pIntrptManage->ulRegMclkTimeLow; + + /* First, check if any interrupts have just been disabled. If there are any, */ + /* determine the time at which they should be reenabled. */ + pIntrptManage->ulNextMclkIntrptTimeHigh = cOCT6100_INVALID_VALUE; + pIntrptManage->ulNextMclkIntrptTimeLow = cOCT6100_INVALID_VALUE; + + while ( fConditionFlag ) + { + /* Indicate that no mclk interrupt is needed, yet. */ + ulTimeDiff = cOCT6100_INVALID_VALUE; + + /* Check each interrupt category to see if an mclk interrupt is needed to */ + /* reenable an interrupt at a later time. */ + if ( pIntrptManage->byFatalMemoryState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byFatalMemoryState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byFatalMemoryState, pIntrptManage->ulFatalMemoryEnableMclkHigh, pIntrptManage->ulFatalMemoryEnableMclkLow, pIntrptConfig->ulFatalMemoryTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorMemoryState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorMemoryState, pIntrptManage->ulErrorMemoryEnableMclkHigh, pIntrptManage->ulErrorMemoryEnableMclkLow, pIntrptConfig->ulErrorMemoryTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorOverflowToneEventsState != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorOverflowToneEventsState, pIntrptManage->ulErrorOverflowToneEventsEnableMclkHigh, pIntrptManage->ulErrorOverflowToneEventsEnableMclkLow, pIntrptConfig->ulErrorOverflowToneEventsTimeoutMclk, ulTimeDiff ) + } + if ( pIntrptManage->byErrorH100State != cOCT6100_INTRPT_ACTIVE && + pIntrptManage->byErrorH100State != cOCT6100_INTRPT_DISABLED ) + { + mOCT6100_GET_INTRPT_ENABLE_TIME( ulRegMclkTimeHigh, ulRegMclkTimeLow, pIntrptManage->byErrorH100State, pIntrptManage->ulErrorH100EnableMclkHigh, pIntrptManage->ulErrorH100EnableMclkLow, pIntrptConfig->ulErrorH100TimeoutMclk, ulTimeDiff ) + } + + /* Set some parameters of write struct. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Schedule next mclk interrupt, if any is needed. */ + if ( ulTimeDiff != cOCT6100_INVALID_VALUE ) + { + UINT32 ulMclkTimeTest; + UINT32 ulAlarmTimeTest; + UINT32 ulTimeDiffTest; + BOOL fAlarmTimePassed; + + /* Indicate that an mclk interrupt is scheduled.*/ + pIntrptManage->fMclkIntrptActive = TRUE; + + pIntrptManage->ulNextMclkIntrptTimeLow = ulRegMclkTimeLow + ulTimeDiff; + if ( pIntrptManage->ulNextMclkIntrptTimeLow < ulRegMclkTimeLow ) + pIntrptManage->ulNextMclkIntrptTimeHigh = ulRegMclkTimeHigh + 1; + else /* ( pIntrptManage->ulNextMclkIntrptTimeLow >= ulRegMclkTimeLow ) */ + pIntrptManage->ulNextMclkIntrptTimeHigh = ulRegMclkTimeHigh; + + WriteParams.ulWriteAddress = 0x30C; + WriteParams.usWriteData = (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeLow >> 24) & 0xFF ); + WriteParams.usWriteData |= (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeHigh & 0xFF) << 8 ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x30E; + WriteParams.usWriteData = (UINT16)( (pIntrptManage->ulNextMclkIntrptTimeLow >> 8) & 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0; + + if ( pIntrptManage->fMclkIntrptActive == TRUE ) + WriteParams.usWriteData = 0x0001; + + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable the ROL if previously set. */ + WriteParams.ulWriteAddress = 0x302; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if already passed the next interrupt time. */ + ulResult = Oct6100ApiReadChipMclkTime( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulMclkTimeTest = (pIntrptManage->ulRegMclkTimeLow >> 16) & 0xFFFF; + ulAlarmTimeTest = (pIntrptManage->ulNextMclkIntrptTimeLow >> 16) & 0xFFFF; + + /* Update the local Mlck timer values.*/ + ulRegMclkTimeHigh = pIntrptManage->ulRegMclkTimeHigh; + ulRegMclkTimeLow = pIntrptManage->ulRegMclkTimeLow; + + fAlarmTimePassed = FALSE; + + if ( ulMclkTimeTest > ulAlarmTimeTest ) + { + ulTimeDiffTest = ulMclkTimeTest - ulAlarmTimeTest; + if ( ulTimeDiffTest <= 0x8000 ) + fAlarmTimePassed = TRUE; + } + else /* ( ulMclkTimeTest <= ulAlarmTimeTest ) */ + { + ulTimeDiffTest = ulAlarmTimeTest - ulMclkTimeTest; + if ( ulTimeDiffTest > 0x8000 ) + fAlarmTimePassed = TRUE; + } + + if ( fAlarmTimePassed == TRUE ) + { + /* Passed the interrupt time. Schedule next interrupt (if needed). */ + ulResult = Oct6100ApiUpdateIntrptTimeouts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + continue; + } + else + { + fConditionFlag = FALSE; + } + } + else + { + /* Indicate that no mclk interrupt is scheduled. */ + pIntrptManage->fMclkIntrptActive = FALSE; + + /* Insure that the mclk interrupt is not enabled. */ + WriteParams.ulWriteAddress = 0x304; + WriteParams.usWriteData = 0x0000; + if ( pIntrptManage->byErrorH100State == cOCT6100_INTRPT_ACTIVE ) + { + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData |= 0xD100; + else + WriteParams.usWriteData |= 0x5100; + } + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + fConditionFlag = FALSE; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckProcessorState + +Description: This function verifies if the NLP and AF processors are operating + correctly. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pIntFlags Pointer to a tOCT6100_INTERRUPT_FLAGS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckProcessorState +UINT32 Oct6100ApiCheckProcessorState( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + + UINT32 ulNlpTimestamp; + UINT32 ulAfTimestamp; + UINT32 ulTimestampDiff; + + UINT32 ulResult; + UINT32 i; + + UINT16 usReadData; + UINT16 ausReadData[ 2 ]; + + UINT32 aulWaitTime[ 2 ]; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set some parameters of write struct. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set some parameters of write struct. */ + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadBurstParams.pusReadData = ausReadData; + + /*-----------------------------------------------------------------------*/ + /* Check if chip is in reset. */ + + /* Read the main control register. */ + ReadParams.ulReadAddress = 0x100; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == 0x0000 ) + { + /* Chip was resetted. */ + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_4; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Reading the AF timestamp.*/ + + for ( i = 0; i < cOCT6100_MAX_LOOP; i++ ) + { + /* Read the timestamp.*/ + ReadBurstParams.ulReadAddress = 0x082E0008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read the high part again to make sure it didn't wrap. */ + ReadParams.ulReadAddress = 0x082E0008; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the low part wrapped. */ + if ( ausReadData[ 0 ] == usReadData ) + break; + } + + if ( i == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_INTRPTS_AF_TIMESTAMP_READ_TIMEOUT; + + /* Save the AF timestamp. */ + ulAfTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Reading the NLP timestamp. */ + + for ( i = 0; i < cOCT6100_MAX_LOOP; i++ ) + { + /* Read the timestamp. */ + ReadBurstParams.ulReadAddress = 0x08000008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read the high part again to make sure it didn't wrap. */ + ReadParams.ulReadAddress = 0x08000008; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the low part wrapped. */ + if ( ausReadData[ 0 ] == usReadData ) + break; + } + + if ( i == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_INTRPTS_NLP_TIMESTAMP_READ_TIMEOUT; + + /* Save the NLP timestamp. */ + ulNlpTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + /*-----------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------*/ + /* Check the validity of the timestamp. */ + + if ( ulAfTimestamp > ulNlpTimestamp ) + { + /* The NLP timestamp wrapped. */ + ulTimestampDiff = 0xFFFFFFFF - ulAfTimestamp + 1; + ulTimestampDiff += ulNlpTimestamp; + } + else + ulTimestampDiff = ulNlpTimestamp - ulAfTimestamp; + + if ( ulTimestampDiff > 0x2000 ) + { + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_5; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + + /*Check if AF and NLP are both stuck*/ + if ( f_pIntFlags->fErrorH100ClkA == FALSE && + f_pIntFlags->fErrorH100ClkB == FALSE && + f_pIntFlags->fErrorH100FrameA == FALSE && + f_pIntFlags->fErrorH100OutOfSync == FALSE ) + + { + if ( ulAfTimestamp == 0 && ulNlpTimestamp == 0 ) + { + /*Give some time to the counters*/ + aulWaitTime[ 0 ] = 250; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*Let's read again the AF timestamp to be sure. Maybe they were at 0 at the same time*/ + ReadBurstParams.ulReadAddress = 0x082E0008; + ReadBurstParams.ulReadLength = 2; + + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulAfTimestamp = (ausReadData[ 0 ] << 16) | ausReadData[ 1 ]; + + if ( ulAfTimestamp == 0 ) + { + /*TDM Clocks are ok but NLP and AF timestamps are both at 0*/ + f_pIntFlags->ulFatalGeneralFlags |= cOCT6100_FATAL_GENERAL_ERROR_TYPE_9; + f_pIntFlags->fFatalGeneral = TRUE; + pSharedInfo->ErrorStats.fFatalChipError = TRUE; + } + } + + } + + /*-----------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c new file mode 100644 index 0000000..b2c0e8e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c @@ -0,0 +1,831 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_memory.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of memory + blocks in external memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 42 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_memory_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetMemorySwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetMemorySwSizes +UINT32 Oct6100ApiGetMemorySwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + UINT32 ulNumTsiChariots; + + /*=========================================================================*/ + /* Internal memory */ + + /* Evaluate the number of available TSI memory after reserving the ones used by channels. */ + ulNumTsiChariots = cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY - f_pOpenChip->ulMaxPhasingTssts - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + + if ( f_pOpenChip->fEnableExtToneDetection == TRUE ) + ulNumTsiChariots--; + + /* Calculate memory needed for TSI memory allocation. */ + ulResult = OctapiLlmAllocGetSize( ulNumTsiChariots, &f_pInstSizes->ulTsiMemoryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_94; + + /* Calculate memory needed for conversion memory allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS, &f_pInstSizes->ulConversionMemoryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B5; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiMemoryAlloc, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConversionMemoryAlloc, ulTempVar ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMemorySwInit + +Description: Initializes all elements of the instance structure associated + to memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMemorySwInit +UINT32 Oct6100ApiMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + PVOID pAllocPnt; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*=========================================================================*/ + /* Internal memory */ + + /* Initialize the TSI memory allocation structure. */ + pSharedInfo->MemoryMap.ulNumTsiEntries = cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY - pSharedInfo->ChipConfig.usMaxPhasingTssts - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + + if ( pSharedInfo->ChipConfig.fEnableExtToneDetection == TRUE ) + pSharedInfo->MemoryMap.ulNumTsiEntries--; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ); + + ulResult = OctapiLlmAllocInit( &pTsiMemAlloc, pSharedInfo->MemoryMap.ulNumTsiEntries ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_95; + + /* Initialize the conversion memory allocation structure. */ + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pAllocPnt ); + + ulResult = OctapiLlmAllocInit( &pAllocPnt, cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B6; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBufferPlayoutMemorySwInit + +Description: Initialize the buffer playout memory allocation working + structures. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBufferPlayoutMemorySwInit +UINT32 Oct6100ApiBufferPlayoutMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Only if buffer playout will be used. */ + if ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers > 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_LIST_PNT( pSharedInfo, pNode ); + + /* First node contains all free memory at beginning. This node is not used, but represents the memory. */ + pNode->ulSize = ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) - pSharedInfo->MemoryMap.ulFreeMemBaseAddress; + pNode->ulNext = 0; + pNode->ulPrevious = 0; + pNode->fAllocated = FALSE; + pNode->ulStartAddress = pSharedInfo->MemoryMap.ulFreeMemBaseAddress; + + pNode++; + + /* Now create the first node of the free list, i.e. nodes that can be used later for modeling the memory. */ + pNode->ulSize = 0; + /* Next free. */ + pNode->ulNext = 2; + /* Last. */ + pNode->ulPrevious = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + pNode->fAllocated = FALSE; + pNode->ulStartAddress = 0; + + pNode++; + + /* Link all the unused nodes. */ + for( i = 2; i < (UINT32)( ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1 ); i ++ ) + { + pNode->ulNext = i + 1; + pNode->ulPrevious = i - 1; + pNode->ulStartAddress = 0; + pNode->ulSize = 0; + pNode->fAllocated = FALSE; + pNode++; + } + + /* Last node of the unused list. */ + pNode->fAllocated = FALSE; + pNode->ulPrevious = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 2; + /* Free list head. */ + pNode->ulNext = 1; + pNode->ulSize = 0; + pNode->ulStartAddress = 0; + + /* Set roving pointer to first node ( which can be used! ) */ + pSharedInfo->PlayoutInfo.ulRovingNode = 0; + + /* First unused node. */ + pSharedInfo->PlayoutInfo.ulFirstUnusedNode = 1; + + /* Last unused node. */ + pSharedInfo->PlayoutInfo.ulLastUnusedNode = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + + /* Number of unused nodes. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt = ( pSharedInfo->ChipConfig.usMaxPlayoutBuffers * 2 ) - 1; + } + else + { + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt = 0; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferPlayoutMemoryNode + +Description: Get a free node from the unused buffer playout node list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulNewNode The index of the node. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferPlayoutMemoryNode +UINT32 Oct6100ApiReserveBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulNewNode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if a free block is left. */ + if ( pSharedInfo->PlayoutInfo.ulUnusedNodeCnt == 0 ) + { + /* This should not happen according to the allocated list from the beginning. */ + return cOCT6100_ERR_FATAL_CC; + } + + /* The new node is the first in the unused list. */ + *f_pulNewNode = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + + /* Unlink this new node from the unused list. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, *f_pulNewNode ); + + pSharedInfo->PlayoutInfo.ulFirstUnusedNode = pNode->ulNext; + + pNode->ulPrevious = pSharedInfo->PlayoutInfo.ulLastUnusedNode; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, pSharedInfo->PlayoutInfo.ulLastUnusedNode ); + + pNode->ulNext = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + + /* Update unused node count. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt--; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferPlayoutMemoryNode + +Description: Release a node that is not used anymore. Insert this node + into the unused list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulOldNode The index of the node. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferPlayoutMemoryNode +UINT32 Oct6100ApiReleaseBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulOldNode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the last unused node. Insert this old node at the end of the unused list. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, pSharedInfo->PlayoutInfo.ulLastUnusedNode ); + + /* Last node points to old node. */ + pNode->ulNext = f_ulOldNode; + + /* Update old node. */ + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNode, f_ulOldNode ); + + pNode->ulPrevious = pSharedInfo->PlayoutInfo.ulLastUnusedNode; + pNode->ulNext = pSharedInfo->PlayoutInfo.ulFirstUnusedNode; + pSharedInfo->PlayoutInfo.ulLastUnusedNode = f_ulOldNode; + + /* Keep unused node count. */ + pSharedInfo->PlayoutInfo.ulUnusedNodeCnt++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferPlayoutMemory + +Description: Try to allocate requested size. + Returns an error if malloc point could not be found. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulSize Needed size. +f_pulMallocAddress Alloc point. This memory can now be used. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferPlayoutMemory +UINT32 Oct6100ApiReserveBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulSize, + OUT PUINT32 f_pulMallocAddress ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pCurrentNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pTempNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pNewNode; + + UINT32 ulCurrentBufferPlayoutMallocNode; + UINT32 ulNewNode; + BOOL fFoundMemory = FALSE; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Requested size must be divisible by 64. */ + if ( f_ulSize % 64 ) + { + f_ulSize = f_ulSize + ( 64 - ( f_ulSize % 64 ) ); + } + + /* Start with roving pointer. */ + ulCurrentBufferPlayoutMallocNode = pSharedInfo->PlayoutInfo.ulRovingNode; + + *f_pulMallocAddress = 0; + + /* Return an error if size requested is zero. */ + if ( f_ulSize == 0 ) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_ZERO; + } + + do + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pCurrentNode, ulCurrentBufferPlayoutMallocNode ); + + /* Look for a free node big enough to fulfill user requested size. */ + if ( ( pCurrentNode->fAllocated == FALSE ) && ( pCurrentNode->ulSize >= f_ulSize ) ) + { + /* Use this node! */ + pCurrentNode->fAllocated = TRUE; + + if ( pCurrentNode->ulNext != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + if( ( pTempNode->fAllocated == TRUE ) && ( pCurrentNode->ulSize > f_ulSize ) ) + { + /* Fragmentation NOW! */ + + /* Allocate new node that will contain free size. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemoryNode( f_pApiInstance, &ulNewNode ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNewNode, ulNewNode ); + + /* Can use this free node. */ + pNewNode->ulSize = pCurrentNode->ulSize - f_ulSize; + pNewNode->ulStartAddress = pCurrentNode->ulStartAddress + f_ulSize; + + /* Link new node into the list. */ + pNewNode->ulNext = pCurrentNode->ulNext; + pNewNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + pNewNode->fAllocated = FALSE; + pTempNode->ulPrevious = ulNewNode; + pCurrentNode->ulNext = ulNewNode; + } + } + else if ( pCurrentNode->ulSize > f_ulSize ) + { + /* Must allocate a new free node for the rest of the space. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemoryNode( f_pApiInstance, &ulNewNode ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pNewNode, ulNewNode ); + + pNewNode->ulNext = pCurrentNode->ulNext; + pCurrentNode->ulNext = ulNewNode; + pNewNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + pNewNode->fAllocated = FALSE; + pNewNode->ulSize = pCurrentNode->ulSize - f_ulSize; + pNewNode->ulStartAddress = pCurrentNode->ulStartAddress + f_ulSize; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, 0 ); + + /* Check for the head node that would have to be updated. */ + if ( ( ulCurrentBufferPlayoutMallocNode == 0 ) && ( pTempNode->ulPrevious == 0 ) ) + pTempNode->ulPrevious = ulNewNode; + } + else + { + /* Perfect fit. */ + } + pCurrentNode->ulSize = f_ulSize; + + /* Update roving pointer. */ + pSharedInfo->PlayoutInfo.ulRovingNode = ulCurrentBufferPlayoutMallocNode; + *f_pulMallocAddress = pCurrentNode->ulStartAddress; + fFoundMemory = TRUE; + break; + } + + /* Next block! */ + ulCurrentBufferPlayoutMallocNode = pCurrentNode->ulNext; + + } while ( pSharedInfo->PlayoutInfo.ulRovingNode != ulCurrentBufferPlayoutMallocNode ); + + if ( fFoundMemory == FALSE ) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_NO_MEMORY; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferPlayoutMemory + +Description: Free what was allocated at address. Free is somewhat slower + then Malloc. O(n), must travel through the list looking for + the malloc point. Return an error if alloc point was not found. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulMallocAddress Alloc point. The memory at address will be freed. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferPlayoutMemory +UINT32 Oct6100ApiReleaseBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMallocAddress ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pCurrentNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pTempNode; + tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE pOldNode; + + UINT32 ulResult = cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_POINT_NOT_FOUND; + UINT32 ulNodeToMerge; + UINT32 ulNodeToRemove; + UINT32 ulCurrentBufferPlayoutMallocNode; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Start from the beginning and find the alloc node. */ + ulCurrentBufferPlayoutMallocNode = 0; + + do + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pCurrentNode, ulCurrentBufferPlayoutMallocNode ); + + if ( ( pCurrentNode->ulStartAddress == f_ulMallocAddress ) && ( pCurrentNode->fAllocated == TRUE ) ) + { + /* We found the block! */ + pCurrentNode->fAllocated = FALSE; + + /* Check if the next node can be merged. */ + if ( pCurrentNode->ulNext != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + if ( pTempNode->fAllocated == FALSE ) + { + /* Can merge this block to us. */ + pCurrentNode->ulSize += pTempNode->ulSize; + pTempNode->ulSize = 0; + + /* Unlink unused node. */ + ulNodeToRemove = pCurrentNode->ulNext; + pCurrentNode->ulNext = pTempNode->ulNext; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulNext ); + + pTempNode->ulPrevious = ulCurrentBufferPlayoutMallocNode; + + ulResult = Oct6100ApiReleaseBufferPlayoutMemoryNode( f_pApiInstance, ulNodeToRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move roving pointer if have to. */ + if ( pSharedInfo->PlayoutInfo.ulRovingNode == ulNodeToRemove ) + pSharedInfo->PlayoutInfo.ulRovingNode = ulCurrentBufferPlayoutMallocNode; + } + } + + /* Check if previous node can merge. */ + if ( ulCurrentBufferPlayoutMallocNode != 0 ) + { + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pCurrentNode->ulPrevious ); + + if ( pTempNode->fAllocated == FALSE ) + { + ulNodeToMerge = pCurrentNode->ulPrevious; + + /* Can merge us to this node. */ + pTempNode->ulSize += pCurrentNode->ulSize; + pCurrentNode->ulSize = 0; + + /* Unlink unused node. */ + ulNodeToRemove = ulCurrentBufferPlayoutMallocNode; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pOldNode, ulNodeToRemove ); + + pTempNode->ulNext = pOldNode->ulNext; + + mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pTempNode, pTempNode->ulNext ); + + pTempNode->ulPrevious = ulNodeToMerge; + + pOldNode->fAllocated = FALSE; + pOldNode->ulSize = 0; + pOldNode->ulStartAddress = 0; + + /* Move roving pointer if have to. */ + if ( pSharedInfo->PlayoutInfo.ulRovingNode == ulNodeToRemove ) + pSharedInfo->PlayoutInfo.ulRovingNode = ulNodeToMerge; + + /* Release this unused node. */ + ulResult = Oct6100ApiReleaseBufferPlayoutMemoryNode( f_pApiInstance, ulNodeToRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* All's good! */ + ulResult = 0; + break; + } + + /* Next node. */ + ulCurrentBufferPlayoutMallocNode = pCurrentNode->ulNext; + + } while( ulCurrentBufferPlayoutMallocNode != 0 ); + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiMemEntry + +Description: Reserves a TSI chariot memory entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusTsiMemIndex Resulting index reserved in the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiMemEntry +UINT32 Oct6100ApiReserveTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + UINT32 ulResult; + UINT32 ulIndex; + UINT32 ulNumTsiB4Timestamp; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ) + + ulResult = OctapiLlmAllocAlloc( pTsiMemAlloc, &ulIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MEMORY_ALL_TSI_MEM_ENTRY_RESERVED; + else + return cOCT6100_ERR_FATAL_92; + } + + + if ( ulIndex >= cOCT6100_NUM_TSI_B4_PHASING ) + { + /* Evaluate the number of TSI memory before the timestamp TSI. */ + ulNumTsiB4Timestamp = cOCT6100_NUM_TSI_B4_PHASING + cOCT6100_MAX_TSI_B4_TIMESTAMP - pSharedInfo->ChipConfig.usMaxPhasingTssts; + + if ( ulIndex >= ulNumTsiB4Timestamp ) + { + /* + 4 for the timestamp TSI entries.*/ + *f_pusTsiMemIndex = (UINT16)( pSharedInfo->ChipConfig.usMaxPhasingTssts + ulIndex + cOCT6100_TSI_MEM_FOR_TIMESTAMP ); + } + else /* ulIndex < ulNumTsiB4Timestamp */ + { + *f_pusTsiMemIndex = (UINT16)( pSharedInfo->ChipConfig.usMaxPhasingTssts + ulIndex ); + } + } + else /* ulIndex < ulNumTsiB4Timestamp */ + { + *f_pusTsiMemIndex = (UINT16)( ulIndex ); + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiMemEntry + +Description: Releases a TSI chariot memory entry specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsiMemIndex Index reserved in the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiMemEntry +UINT32 Oct6100ApiReleaseTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiMemAlloc; + UINT32 ulResult; + UINT32 ulIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if the entry programmed is greater then the timestamp entries. */ + if ( f_usTsiMemIndex > cOCT6100_TSST_CONTROL_TIMESTAMP_BASE_ENTRY ) + ulIndex = f_usTsiMemIndex - cOCT6100_TSI_MEM_FOR_TIMESTAMP; + else + ulIndex = f_usTsiMemIndex; + + /* Check if the entry programmed is greater then the phasing TSST entries. */ + if ( ulIndex > cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY ) + ulIndex -= pSharedInfo->ChipConfig.usMaxPhasingTssts; + + mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pTsiMemAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsiMemAlloc, ulIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_93; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveConversionMemEntry + +Description: Reserves one of the conversion memory entry + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pusConversionMemIndex Resulting index reserved in the conversion memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveConversionMemEntry +UINT32 Oct6100ApiReserveConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusConversionMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pConversionMemAlloc; + UINT32 ulConversionMemIndex; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pConversionMemAlloc ) + + ulResult = OctapiLlmAllocAlloc( pConversionMemAlloc, &ulConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MEMORY_ALL_CONVERSION_MEM_ENTRY_RESERVED; + else + return cOCT6100_ERR_FATAL_B8; + } + + *f_pusConversionMemIndex = (UINT16)( ulConversionMemIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseConversionMemEntry + +Description: Releases the conversion chariot memory entry specified. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_usConversionMemIndex Index reserved in the conversion chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseConversionMemEntry +UINT32 Oct6100ApiReleaseConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pConversionMemAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pConversionMemAlloc ) + + ulResult = OctapiLlmAllocDealloc( pConversionMemAlloc, f_usConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_B7; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c new file mode 100644 index 0000000..4e5c189 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c @@ -0,0 +1,640 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_miscellaneous.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains miscellaneous functions used in various files. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 35 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_largmath.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_miscellaneous_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWaitForTime + +Description: Waits for the specified amount of time. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_aulWaitTime[ 2 ] The amout of time to be waited. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWaitForTime +UINT32 Oct6100ApiWaitForTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_aulWaitTime[ 2 ] ) +{ + tOCT6100_GET_TIME StartTime; + tOCT6100_GET_TIME CurrentTime; + UINT32 aulTimeDelta[ 2 ]; + UINT32 ulResult; + UINT16 usTempVar; + BOOL fConditionFlag = TRUE; + + /* Copy the process context. */ + StartTime.pProcessContext = f_pApiInstance->pProcessContext; + CurrentTime.pProcessContext = f_pApiInstance->pProcessContext; + + ulResult = Oct6100UserGetTime( &StartTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( fConditionFlag ) + { + ulResult = Oct6100UserGetTime( &CurrentTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = octapi_lm_subtract( + CurrentTime.aulWallTimeUs, 1, + StartTime.aulWallTimeUs, 1, + aulTimeDelta, 1, + &usTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_37; + + if ( aulTimeDelta[ 1 ] >= f_aulWaitTime[ 1 ] && + aulTimeDelta[ 0 ] >= f_aulWaitTime[ 0 ] ) + fConditionFlag = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWaitForPcRegisterBit + +Description: Polls the specified PC register bit. The function exits once + the bit is cleared by hardware, or when the specified timeout + period has been expired. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulPcRegAdd Address of the register containing the PC bit. +f_ulPcBitNum Number of the PC bit within the register. +f_ulValue Expected value of the bit. +f_ulTimeoutUs The timeout period, in usec. +f_pfBitEqual Pointer to the result of the bit comparison. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWaitForPcRegisterBit +UINT32 Oct6100ApiWaitForPcRegisterBit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulPcRegAdd, + IN UINT32 f_ulPcBitNum, + IN UINT32 f_ulValue, + IN UINT32 f_ulTimeoutUs, + OUT PBOOL f_pfBitEqual ) +{ + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_GET_TIME StartTime; + tOCT6100_GET_TIME TimeoutTime; + tOCT6100_GET_TIME CurrentTime; + UINT32 ulResult; + UINT16 usReadData; + BOOL fConditionFlag = TRUE; + + /* Copy the process context. */ + StartTime.pProcessContext = f_pApiInstance->pProcessContext; + CurrentTime.pProcessContext = f_pApiInstance->pProcessContext; + + /* Get the current system time. */ + ulResult = Oct6100UserGetTime( &StartTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Mark the bit as not being equal, for now. */ + *f_pfBitEqual = FALSE; + + /* Determine the time at which the timeout has expired. */ + ulResult = octapi_lm_add( + StartTime.aulWallTimeUs, 1, + &f_ulTimeoutUs, 0, + TimeoutTime.aulWallTimeUs, 1 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Prepare read structure. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = f_ulPcRegAdd; + ReadParams.pusReadData = &usReadData; + + /* Read the PC bit while the timeout period hasn't expired. */ + while ( fConditionFlag ) + { + /* Read the current time again to check for timeout. */ + ulResult = Oct6100UserGetTime( &CurrentTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100UserDriverReadApi( &ReadParams ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( UINT16 )((usReadData >> f_ulPcBitNum) & 0x1) == ( UINT16 )f_ulValue ) + { + /* Mark the bit as being equal. */ + *f_pfBitEqual = TRUE; + fConditionFlag = FALSE; + } + + if ( CurrentTime.aulWallTimeUs[ 1 ] > TimeoutTime.aulWallTimeUs[ 1 ] || + (CurrentTime.aulWallTimeUs[ 1 ] == TimeoutTime.aulWallTimeUs[ 1 ] && + CurrentTime.aulWallTimeUs[ 0 ] >= TimeoutTime.aulWallTimeUs[ 0 ]) ) + fConditionFlag = FALSE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadDword + +Description: Read a DWORD at specified address in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress DWORD address where to read. +f_pulReadData Resulting data. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReadDword +UINT32 Oct6100ApiReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + UINT32 ulResult; + UINT32 ulTempData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*==================================================================================*/ + /* Read the first 16 bits. */ + ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTempData = usReadData << 16; + + /* Read the last 16 bits. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTempData |= usReadData; + + /*==================================================================================*/ + + /* Return the read value.*/ + *f_pulReadData = ulTempData; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDword + +Description: Write a DWORD at specified address in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress DWORD address where to write. +f_ulWriteData DWORD data to write. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDword +UINT32 Oct6100ApiWriteDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + IN UINT32 f_ulWriteData ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the first 16 bits. */ + WriteParams.ulWriteAddress = f_ulAddress; + WriteParams.usWriteData = (UINT16)((f_ulWriteData >> 16) & 0xFFFF); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the last word. */ + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(f_ulWriteData & 0xFFFF); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateFeatureMask + +Description: + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulFieldSize Size of the field, in bits. +f_ulFieldBitOffset Bit offset, from the least significant bit. +f_pulFieldMask Resulting mask. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateFeatureMask +VOID Oct6100ApiCreateFeatureMask( + IN UINT32 f_ulFieldSize, + IN UINT32 f_ulFieldBitOffset, + OUT PUINT32 f_pulFieldMask ) +{ + UINT32 ulMask; + UINT32 i; + + ulMask = 0; + + /* Create the mask based on the field size. */ + for ( i = 0; i < f_ulFieldSize; i++ ) + { + ulMask <<= 1; + ulMask |= 1; + } + + /* Once the mask is of the desired size, offset it to fit the field */ + /* within the DWORD read. */ + ulMask <<= f_ulFieldBitOffset; + + /* Return the mask. */ + *f_pulFieldMask = ulMask; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiStrStr + +Description: OCT6100 API version of strstr() + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pszSource Source string to analyze. +f_pszString String to look for. +f_pszLastCharPtr Last character in the source string. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiStrStr +unsigned char const *Oct6100ApiStrStr( + IN unsigned char const *f_pszSource, + IN unsigned char const *f_pszString, + IN unsigned char const *f_pszLastCharPtr ) +{ + UINT32 ulCurrentPos; + UINT32 ulStringLength; + UINT32 ulNumMatchingCharFound = 0; + unsigned char const *pchFirstChar = NULL; + UINT32 ulSourceLength; + + if ( f_pszLastCharPtr < f_pszSource ) + return NULL; + + ulSourceLength = (UINT32)( f_pszLastCharPtr - f_pszSource ); + ulStringLength = Oct6100ApiStrLen( f_pszString ); + + for ( ulCurrentPos = 0; ulCurrentPos < ulSourceLength; ulCurrentPos++ ) + { + /* Check if the character matches. */ + if ( f_pszSource[ ulCurrentPos ] == f_pszString[ ulNumMatchingCharFound ] ) + { + if ( ulNumMatchingCharFound == 0 ) + pchFirstChar = ( f_pszSource + ulCurrentPos ); + + ulNumMatchingCharFound++; + + /* Check if the whole string matched. */ + if ( ulNumMatchingCharFound == ulStringLength ) + break; + } + else if ( ulNumMatchingCharFound != 0 ) + { + ulNumMatchingCharFound = 0; + + /* Reset the search, but take a look at the current character. It might */ + /* be the beginning of the string we are looking for. */ + if ( f_pszSource[ ulCurrentPos ] == f_pszString[ ulNumMatchingCharFound ] ) + { + pchFirstChar = ( f_pszSource + ulCurrentPos ); + ulNumMatchingCharFound++; + + /* Check if the whole string matched. */ + /* This check must be done in case we have the 1 character strstr */ + if ( ulNumMatchingCharFound == ulStringLength ) + break; + } + } + } + + if ( ulCurrentPos == ulSourceLength ) + return NULL; + else + return pchFirstChar; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiStrLen + +Description: OCT6100 API version of strlen() + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pszString Source string to count length of. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiStrLen +UINT32 Oct6100ApiStrLen( + IN unsigned char const *f_pszString ) +{ + UINT32 ulCount = 0; + + while( f_pszString[ ulCount ] != '\0' ) + ulCount++; + + return ulCount; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAsciiToHex + +Description: Convert an ASCII character to an hexadecimal value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_chCharacter ASCII character to convert. +f_pulValue Resulting hexadecimal value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAsciiToHex +UINT32 Oct6100ApiAsciiToHex( + IN UINT8 f_chCharacter, + OUT PUINT32 f_pulValue ) +{ + switch ( f_chCharacter ) + { + case '0': + (*f_pulValue) = 0x0; + break; + case '1': + (*f_pulValue) = 0x1; + break; + case '2': + (*f_pulValue) = 0x2; + break; + case '3': + (*f_pulValue) = 0x3; + break; + case '4': + (*f_pulValue) = 0x4; + break; + case '5': + (*f_pulValue) = 0x5; + break; + case '6': + (*f_pulValue) = 0x6; + break; + case '7': + (*f_pulValue) = 0x7; + break; + case '8': + (*f_pulValue) = 0x8; + break; + case '9': + (*f_pulValue) = 0x9; + break; + case 'A': + case 'a': + (*f_pulValue) = 0xA; + break; + case 'B': + case 'b': + (*f_pulValue) = 0xB; + break; + case 'C': + case 'c': + (*f_pulValue) = 0xC; + break; + case 'D': + case 'd': + (*f_pulValue) = 0xD; + break; + case 'E': + case 'e': + (*f_pulValue) = 0xE; + break; + case 'F': + case 'f': + (*f_pulValue) = 0xF; + break; + default: + (*f_pulValue) = 0x0; + return cOCT6100_ERR_MISC_ASCII_CONVERSION_FAILED; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiHexToAscii + +Description: Convert an hexadecimal value to an ASCII character. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulNumber Hexadecimal value to convert. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiHexToAscii +UINT8 Oct6100ApiHexToAscii( + IN UINT32 f_ulNumber ) +{ + if ( f_ulNumber >= 0xA ) + return (UINT8)( 55 + f_ulNumber ); /* Hex values from 0xA to 0xF */ + else + return (UINT8)( 48 + f_ulNumber ); /* Hex values from 0x0 to 0x9 */ +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRand + +Description: Random number generator. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_ulRange Range of the random number to be generated. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRand +UINT32 Oct6100ApiRand( + IN UINT32 f_ulRange ) +{ + static UINT32 ulRandomSeed = 0x12345678; + UINT32 ulBit0; + + UINT32 i, j; + UINT16 ulWithinRange = FALSE; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 ulLoop; + + UINT32 ulRangeMask; + UINT32 ulAddedValue; + + + ulRangeMask = 1; + ulLoop = TRUE; + i = 1; + + while ( ulLoop ) + { + + ulAddedValue = 2; + for ( j = 1; j < i; j++ ) + ulAddedValue *= 2; + + ulRangeMask = ulRangeMask + ulAddedValue; + + if ( ulRangeMask >= f_ulRange ) + ulLoop = FALSE; + + i++; + } + + while ( !ulWithinRange ) + { + ulBit0 = ((ulRandomSeed >> 19) & 0x1) ^ ((ulRandomSeed >> 16) & 0x1); + ulRandomSeed = ((ulRandomSeed << 1) & 0xFFFFF) | ulBit0; + + ulResult = ulRandomSeed & ulRangeMask; + + if ( ulResult <= f_ulRange ) + ulWithinRange = TRUE; + } + + return ulResult; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c new file mode 100644 index 0000000..05aff3b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c @@ -0,0 +1,1586 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of mixer + blocks in memories. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 42 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreate + +Description: This function creates a mixer copy event used to copy + information from one channel port to another channel port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a mixer copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventCreateDef +UINT32 Oct6100MixerCopyEventCreateDef( + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + f_pCopyEventCreate->pulCopyEventHndl = NULL; + + f_pCopyEventCreate->ulSourceChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulSourcePort = cOCT6100_INVALID_PORT; + + f_pCopyEventCreate->ulDestinationChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulDestinationPort = cOCT6100_INVALID_PORT; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100MixerCopyEventCreate +UINT32 Oct6100MixerCopyEventCreate( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventCreateSer( f_pApiInstance, f_pCopyEventCreate ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroy + +Description: This function destroys a mixer copy event used to copy + information from one channel port to another. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventDestroyDef +UINT32 Oct6100MixerCopyEventDestroyDef( + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100MixerCopyEventDestroy +UINT32 Oct6100MixerCopyEventDestroy( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventDestroySer( f_pApiInstance, f_pCopyEventDestroy ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetMixerSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pOpenChip User chip configuration. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetMixerSwSizes +UINT32 Oct6100ApiGetMixerSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate the API memory required for the resource entry lists. */ + f_pInstSizes->ulMixerEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT ); + + /* Calculate memory needed for mixers entry allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulMixerEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventAlloc, ulTempVar ) + + + f_pInstSizes->ulCopyEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_COPY_EVENT ); + + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulCopyEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventAlloc, ulTempVar ) + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerSwInit + +Description: Initializes all elements of the instance structure associated + to the mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This mixer is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerSwInit +UINT32 Oct6100ApiMixerSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pMixerEventList; + PVOID pMixerEventAlloc; + PVOID pCopyEventAlloc; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===================================================================*/ + /* Initialize the mixer event list. */ + mOCT6100_GET_MIXER_EVENT_LIST_PNT( pSharedInfo, pMixerEventList ); + + /* Initialize the mixer event allocation software to "all free". */ + Oct6100UserMemSet( pMixerEventList, 0x00, cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT )); + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pMixerEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1F; + + /* Now reserve the first entry as the first node. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_20; + } + + /* Check that we obtain the first event. */ + if ( ulTempVar != 0 ) + return cOCT6100_ERR_FATAL_21; + + /* Now reserve the tail entry. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_AA; + } + /* Check that we obtain the first event. */ + if ( ulTempVar != 1 ) + return cOCT6100_ERR_FATAL_AB; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the tail node. */ + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usNextEventPtr = cOCT6100_INVALID_INDEX; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Now reserve the entry used for channel recording if the feature is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + UINT32 ulAllocIndex; + + /* Reserve an entry to copy the desire SOUT signal to the SIN signal of the recording channel. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Reserve an entry to copy the saved SIN signal of the debugged channel into it's original location. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordSinEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Configure the SIN event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Configure the SOUT copy event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + } + + /* Initialize the copy event list. */ + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pCopyEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B4; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventAdd + +Description: This function adds a mixer event event to the list of events + based on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_usEventIndex Index of the event within the API's mixer event list. +f_usEventType Type of mixer event. +f_usDestinationChanIndex Index of the destination channel within the API's + channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerEventAdd +UINT32 Oct6100ApiMixerEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT16 usTempEventIndex; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get a pointer to the destination channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + /* Now insert the Sin copy event */ + if ( pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list before the point where the node needs to */ + /* be inserted is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + + /* This node will be the first one in the Sout copy section. */ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + + break; + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + /* Now insert the Sin copy event. */ + if ( pSharedInfo->MixerInfo.usFirstSinCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This is the first Sin copy event. We must find the event that comes before */ + /* the event we want to add. First let's check for a bridge event. */ + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* No event in the bridge section, now let's check in the Sout copy section. */ + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list then is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + + /* This node will be the first one in the Sin copy section. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSinCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSinCopyEventPtr; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + + break; + + default: + return cOCT6100_ERR_FATAL_AF; + + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /*=======================================================================*/ + /* Program the Copy event. */ + + /* Set the Copy event first. */ + pCurrentEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_COPY; + pCurrentEventEntry->usNextEventPtr = pTempEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pCurrentEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Modify the previous node. */ + + /* Set the last Sub-store entry. */ + pTempEventEntry->usNextEventPtr = f_usEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = f_usEventIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Save the destination channel index, needed when removing the event from the mixer. */ + pCurrentEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + + /* Mark the entry as reserved. */ + pCurrentEventEntry->fReserved = TRUE; + + /* Increment the event count on that particular destination channel */ + pDestinationEntry->usMixerEventCnt++; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventRemove + +Description: This function removes a mixer event event from the list of events based + on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex Index of event within the API's mixer event list. +f_usEventType Type of mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMixerEventRemove +UINT32 Oct6100ApiMixerEventRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_BURST_PARAMS BurstWriteParams; + tOCT6100_WRITE_PARAMS WriteParams; + BOOL fFirstSinCopyEvent = FALSE; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount = 0; + UINT16 ausWriteData[ 4 ] = { 0 }; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + BurstWriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstWriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + BurstWriteParams.pusWriteData = ausWriteData; + BurstWriteParams.ulWriteLength = 4; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get the pointer to the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCurrentEventEntry->usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B2; + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* This event was the only of the list.*/ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + fFirstSinCopyEvent = TRUE; + + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + else + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSinCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /* If we are not the first event of the Sin copy list. */ + if ( fFirstSinCopyEvent == FALSE ) + { + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B1; + } + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + /* This event was the only of the list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + default: + return cOCT6100_ERR_FATAL_B0; + + } + + /*=======================================================================*/ + /* Modify the previous event. */ + + pTempEventEntry->usNextEventPtr = pCurrentEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pTempEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the current event. */ + + BurstWriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstWriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Decrement the mixer event count active on that channel. */ + pDestinationEntry->usMixerEventCnt--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + + /* This index of this channel is not valid anymore! */ + pCurrentEventEntry->usDestinationChanIndex = cOCT6100_INVALID_INDEX; + + /* Mark this entry as free. */ + pCurrentEventEntry->fReserved = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreateSer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventCreateSer +UINT32 Oct6100MixerCopyEventCreateSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + UINT16 usCopyEventIndex = 0; + UINT16 usMixerEventIndex = 0; + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + UINT32 ulResult; + + /* Check the user's configuration of the copy event for errors. */ + ulResult = Oct6100ApiCheckCopyEventCreateParams( f_pApiInstance, + f_pCopyEventCreate, + &usSourceChanIndex, + &usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the copy event. */ + ulResult = Oct6100ApiReserveCopyEventCreateResources( f_pApiInstance, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteCopyEventCreateStructs( f_pApiInstance, + f_pCopyEventCreate, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateCopyEventCreateEntry( f_pApiInstance, + f_pCopyEventCreate, + usCopyEventIndex, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCopyEventCreateParams + +Description: Checks the user's parameter passed to the create + copy event function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_pusSourceChanIndex Pointer to the index of the input channel. +f_pusDestinationChanIndex Pointer to the index of the output channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckCopyEventCreateParams +UINT32 Oct6100ApiCheckCopyEventCreateParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + OUT PUINT16 f_pusSourceChanIndex, + OUT PUINT16 f_pusDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + UINT32 ulEntryOpenCnt; + + /* Obtain shared resources pointer. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_pCopyEventCreate->pulCopyEventHndl == NULL ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + if ( f_pCopyEventCreate->ulSourceChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( f_pCopyEventCreate->ulDestinationChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + if ( f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_SOURCE_PORT; + + if ( f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_DESTINATION_PORT; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + *f_pusSourceChanIndex = (UINT16)( f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSourceChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, *f_pusSourceChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulSourceChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSourceEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSourceEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( pSourceEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulSourcePort ) + return cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + *f_pusDestinationChanIndex = (UINT16)( f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusDestinationChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, *f_pusDestinationChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulDestinationChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pDestinationEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pDestinationEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + if ( pDestinationEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulDestinationPort ) + return cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventCreateResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusCopyEntryIndex Pointer to the index of the copy entry within the API's list. +f_pusCopyEventIndex Pointer to the index of the mixer copy event. +. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveCopyEventCreateResources +UINT32 Oct6100ApiReserveCopyEventCreateResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusCopyEntryIndex, + IN OUT PUINT16 f_pusCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already be allocated. */ + + ulResult = Oct6100ApiReserveCopyEventEntry( f_pApiInstance, + f_pusCopyEntryIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the source copy event for the first channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + f_pusCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel. */ + ulTempVar = Oct6100ApiReleaseCopyEventEntry ( f_pApiInstance, + *f_pusCopyEntryIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteCopyEventCreateStructs + +Description: Performs all the required structure writes to configure the + new copy event + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteCopyEventCreateStructs +UINT32 Oct6100ApiWriteCopyEventCreateStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, f_usSourceChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /*==============================================================================*/ + /* Configure the TSST control memory and add the Sin copy event if necessary. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + + if ( f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData |= pSourceEntry->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pSourceEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pSourceEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.usWriteData |= pSourceEntry->usExtraSinTsiMemIndex; + } + else + { + WriteParams.usWriteData |= pSourceEntry->usSinSoutTsiMemIndex; + } + + WriteParams.usWriteData |= pSourceEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + + if ( f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usRinRoutTsiMemIndex ); + } + else /* f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_SIN */ + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usSinSoutTsiMemIndex ); + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now insert the event into the event list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Increment the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt++; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateCopyEventCreateEntry + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_pCopyEventCreate Pointer to a create copy event structure. +f_usCopyEventIndex Index of the copy event within the API's event list. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateCopyEventCreateEntry +UINT32 Oct6100ApiUpdateCopyEventCreateEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + /* Save the channel info in the copy event. */ + pCopyEventEntry->usSourceChanIndex = f_usSourceChanIndex; + pCopyEventEntry->bySourcePort = (UINT8)( f_pCopyEventCreate->ulSourcePort & 0xFF ); + + pCopyEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + pCopyEventEntry->byDestinationPort = (UINT8)( f_pCopyEventCreate->ulDestinationPort & 0xFF ); + + pCopyEventEntry->usMixerEventIndex = f_usMixerEventIndex; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pCopyEventCreate->pulCopyEventHndl = cOCT6100_HNDL_TAG_COPY_EVENT | (pCopyEventEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usCopyEventIndex; + + /* Finally, mark the event as used. */ + pCopyEventEntry->fReserved = TRUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroySer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100MixerCopyEventDestroySer +UINT32 Oct6100MixerCopyEventDestroySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + UINT16 usCopyEventIndex; + UINT16 usMixerEventIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertCopyEventDestroyParams( f_pApiInstance, + f_pCopyEventDestroy, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateCopyEventStructs( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseCopyEventResources( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertCopyEventDestroyParams + +Description: + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. +f_pusCopyEventIndex Pointer to the index of the copy event in the API. +f_pusMixerEventIndex Pointer to the index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertCopyEventDestroyParams +UINT32 Oct6100ApiAssertCopyEventDestroyParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy, + IN OUT PUINT16 f_pusCopyEventIndex, + IN OUT PUINT16 f_pusMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_COPY_EVENT ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + *f_pusCopyEventIndex = (UINT16)( f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusCopyEventIndex >= cOCT6100_MAX_MIXER_EVENTS ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, *f_pusCopyEventIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventDestroy->ulCopyEventHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pCopyEventEntry->fReserved != TRUE ) + return cOCT6100_ERR_MIXER_EVENT_NOT_OPEN; + if ( ulEntryOpenCnt != pCopyEventEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the associated event. */ + *f_pusMixerEventIndex = pCopyEventEntry->usMixerEventIndex; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateCopyEventStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateCopyEventStructs +UINT32 Oct6100ApiInvalidateCopyEventStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Clear the Copy event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseCopyEventResources +UINT32 Oct6100ApiReleaseCopyEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pDestinationEntry; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + ulResult = Oct6100ApiReleaseCopyEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Relese the SIN copy event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B3; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, f_usMixerEventIndex ); + + /* Invalidate the entry. */ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCopyEventEntry->usDestinationChanIndex ); + + /* Decrement the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt--; + + /*=======================================================================*/ + + /* Mark the event entry as unused. */ + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->byEntryOpenCnt++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveMixerEventEntry + +Description: Reserves a free entry in the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveMixerEventEntry +UINT32 Oct6100ApiReserveMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_2B; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseMixerEventEntry + +Description: Release an entry from the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseMixerEventEntry +UINT32 Oct6100ApiReleaseMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pMixerEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2C; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetFreeMixerEventCnt + +Description: Retrieve the number of events left in the list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pulFreeEventCnt How many events left. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetFreeMixerEventCnt +UINT32 Oct6100ApiGetFreeMixerEventCnt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulFreeEventCnt ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulAllocatedEvents; + UINT32 ulAvailableEvents; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInfo( pMixerEventAlloc, &ulAllocatedEvents, &ulAvailableEvents ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E8; + + /* Return number of free events. */ + *f_pulFreeEventCnt = ulAvailableEvents; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventEntry + +Description: Reserves a free entry in the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveCopyEventEntry +UINT32 Oct6100ApiReserveCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pCopyEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_AD; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventEntry + +Description: Release an entry from the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseCopyEventEntry +UINT32 Oct6100ApiReleaseCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pCopyEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AE; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c new file mode 100644 index 0000000..e8a4199 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c @@ -0,0 +1,922 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close phasing TSSTs. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 46 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_phasing_tsst_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstOpen + +Description: This function opens a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstOpenDef +UINT32 Oct6100PhasingTsstOpenDef( + tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + f_pPhasingTsstOpen->pulPhasingTsstHndl = NULL; + + f_pPhasingTsstOpen->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pPhasingTsstOpen->ulStream = cOCT6100_INVALID_STREAM; + + f_pPhasingTsstOpen->ulPhasingLength = 88; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100PhasingTsstOpen +UINT32 Oct6100PhasingTsstOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100PhasingTsstOpenSer( f_pApiInstance, f_pPhasingTsstOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstClose + +Description: This function closes a phasing TSST + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstCloseDef +UINT32 Oct6100PhasingTsstCloseDef( + tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + f_pPhasingTsstClose->ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100PhasingTsstClose +UINT32 Oct6100PhasingTsstClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100PhasingTsstCloseSer( f_pApiInstance, f_pPhasingTsstClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPhasingTsstSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of Phasing TSSTs. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPhasingTsstSwSizes +UINT32 Oct6100ApiGetPhasingTsstSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API phasing TSST list. */ + f_pInstSizes->ulPhasingTsstList = f_pOpenChip->ulMaxPhasingTssts * sizeof( tOCT6100_API_PHASING_TSST ); + + if ( f_pOpenChip->ulMaxPhasingTssts > 0 ) + { + /* Calculate memory needed for Phasing TSST API memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxPhasingTssts, &f_pInstSizes->ulPhasingTsstAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_38; + } + else + { + f_pInstSizes->ulPhasingTsstAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPhasingTsstList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPhasingTsstAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiPhasingTsstSwInit + +Description: Initializes all elements of the instance structure associated + to phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiPhasingTsstSwInit +UINT32 Oct6100ApiPhasingTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_PHASING_TSST pPhasingTsstList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxPhasingTssts; + PVOID pPhasingTsstAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the phasing TSST API list. */ + ulMaxPhasingTssts = pSharedInfo->ChipConfig.usMaxPhasingTssts; + + /* Set all entries in the phasing TSST list to unused. */ + mOCT6100_GET_PHASING_TSST_LIST_PNT( pSharedInfo, pPhasingTsstList ) + + /* Clear the memory */ + Oct6100UserMemSet( pPhasingTsstList, 0x00, sizeof(tOCT6100_API_PHASING_TSST) * ulMaxPhasingTssts ); + + /* Initialize the phasing TSST allocation software to "all free". */ + if ( ulMaxPhasingTssts > 0 ) + { + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingTsstAlloc ) + + ulResult = OctapiLlmAllocInit( &pPhasingTsstAlloc, ulMaxPhasingTssts ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_39; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstOpenSer + +Description: Opens a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstOpenSer +UINT32 Oct6100PhasingTsstOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + UINT16 usPhasingIndex; + UINT16 usTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the phasing TSST for errors. */ + ulResult = Oct6100ApiCheckPhasingParams( f_pApiInstance, f_pPhasingTsstOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the phasing TSST. */ + ulResult = Oct6100ApiReservePhasingResources( f_pApiInstance, f_pPhasingTsstOpen, &usPhasingIndex, &usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the phasing TSST. */ + ulResult = Oct6100ApiWritePhasingStructs( f_pApiInstance, f_pPhasingTsstOpen, usPhasingIndex, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new phasing TSST entry in the API list. */ + ulResult = Oct6100ApiUpdatePhasingEntry( f_pApiInstance, f_pPhasingTsstOpen, usPhasingIndex, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPhasingParams + +Description: Checks the user's phasing TSST open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPhasingParams +UINT32 Oct6100ApiCheckPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPhasingTssts == 0 ) + return cOCT6100_ERR_PHASING_TSST_DISABLED; + + if ( f_pPhasingTsstOpen->pulPhasingTsstHndl == NULL ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /* Check the phasing length. */ + if ( f_pPhasingTsstOpen->ulPhasingLength > 240 || + f_pPhasingTsstOpen->ulPhasingLength < 2 ) + return cOCT6100_ERR_PHASING_TSST_PHASING_LENGTH; + + + + /* Check the input TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pPhasingTsstOpen->ulTimeslot, + f_pPhasingTsstOpen->ulStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_PHASING_TSST_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_PHASING_TSST_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReservePhasingResources + +Description: Reserves all resources needed for the new phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST configuration structure. +f_pusPhasingIndex Allocated entry in Phasing TSST API list. +f_pusTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReservePhasingResources +UINT32 Oct6100ApiReservePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the phasing TSST list. */ + ulResult = Oct6100ApiReservePhasingEntry( f_pApiInstance, + f_pusPhasingIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pPhasingTsstOpen->ulTimeslot, + f_pPhasingTsstOpen->ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + f_pusTsstIndex, + NULL ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the previously reserved entries. */ + ulTempVar = Oct6100ApiReleasePhasingEntry( f_pApiInstance, *f_pusPhasingIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + + return ulResult; + } + } + else + { + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWritePhasingStructs + +Description: Performs all the required structure writes to configure the + new phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST configuration structure. +f_usPhasingIndex Allocated entry in phasing TSST API list. +f_usTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWritePhasingStructs +UINT32 Oct6100ApiWritePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulPhasingTsstChariotMemIndex; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Configure the TSST control memory of the phasing TSST. */ + + /* Find the asociated entry in the chariot memory for the phasing TSST. */ + ulPhasingTsstChariotMemIndex = cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY + f_usPhasingIndex; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_INPUT_TSST; + WriteParams.usWriteData |= ulPhasingTsstChariotMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Write the phasing length of the TSST in the ADPCM / MIXER memory. */ + + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_PHASE_SIZE_BASE_ADD + ( f_usPhasingIndex * 2 ); + WriteParams.usWriteData = (UINT16)( f_pPhasingTsstOpen->ulPhasingLength ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdatePhasingEntry + +Description: Updates the new phasing TSST in the API phasing TSST list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pPhasingTsstOpen Pointer to phasing TSST open structure. +f_usPhasingIndex Allocated entry in phasing TSST API list. +f_usTsstIndex TSST memory index of the counter. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdatePhasingEntry +UINT32 Oct6100ApiUpdatePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_API_PHASING_TSST pPhasingTsstEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingTsstEntry, f_usPhasingIndex ) + + /* Copy the phasing TSST's configuration and allocated resources. */ + pPhasingTsstEntry->usTimeslot = (UINT16)( f_pPhasingTsstOpen->ulTimeslot & 0xFFFF ); + pPhasingTsstEntry->usStream = (UINT16)( f_pPhasingTsstOpen->ulStream & 0xFFFF ); + + pPhasingTsstEntry->usPhasingLength = (UINT16)( f_pPhasingTsstOpen->ulPhasingLength & 0xFFFF ); + + /* Store hardware related information. */ + pPhasingTsstEntry->usPhasingTsstIndex = f_usTsstIndex; + + /* Form handle returned to user. */ + *f_pPhasingTsstOpen->pulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsstEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usPhasingIndex; + pPhasingTsstEntry->usDependencyCnt = 0; /* Nobody is using the phasing TSST.*/ + + /* Finally, mark the phasing TSST as open. */ + pPhasingTsstEntry->fReserved = TRUE; + + /* Increment the number of phasing TSSTs opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPhasingTssts++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100PhasingTsstCloseSer + +Description: Closes a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100PhasingTsstCloseSer +UINT32 Oct6100PhasingTsstCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ) +{ + UINT16 usPhasingIndex; + UINT16 usTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertPhasingParams( f_pApiInstance, f_pPhasingTsstClose, &usPhasingIndex, &usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the phasing TSST. */ + ulResult = Oct6100ApiInvalidatePhasingStructs( f_pApiInstance, usTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the phasing TSST. */ + ulResult = Oct6100ApiReleasePhasingResources( f_pApiInstance, usPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pPhasingTsstClose->ulPhasingTsstHndl = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertPhasingParams + +Description: Validate the handle given by the user and verify the state of + the phasing TSST about to be closed. Also returns all + required information to deactivate the phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pPhasingTsstClose Pointer to phasing TSST close structure. +f_pusPhasingIndex Index of the phasing TSST structure in the API list. +f_pusTsstIndex Index of the entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertPhasingParams +UINT32 Oct6100ApiAssertPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pPhasingTsstClose->ulPhasingTsstHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_PHASING_TSST ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + *f_pusPhasingIndex = (UINT16)( f_pPhasingTsstClose->ulPhasingTsstHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusPhasingIndex >= pSharedInfo->ChipConfig.usMaxPhasingTssts ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the phasing TSST's list entry. */ + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingEntry, *f_pusPhasingIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pPhasingTsstClose->ulPhasingTsstHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pPhasingEntry->fReserved != TRUE ) + return cOCT6100_ERR_PHASING_TSST_NOT_OPEN; + if ( pPhasingEntry->usDependencyCnt != 0 ) + return cOCT6100_ERR_PHASING_TSST_ACTIVE_DEPENDENCIES; + if ( ulEntryOpenCnt != pPhasingEntry->byEntryOpenCnt ) + return cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE; + + /* Return info needed to close the phasing TSST and release all resources. */ + *f_pusTsstIndex = pPhasingEntry->usPhasingTsstIndex; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidatePhasingStructs + +Description: Closes a phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usTsstIndex Index of the entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidatePhasingStructs +UINT32 Oct6100ApiInvalidatePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleasePhasingResources + +Description: Release and clear the API entry associated to the phasing TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usPhasingIndex Index of the phasing TSST in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleasePhasingResources +UINT32 Oct6100ApiReleasePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingEntry, f_usPhasingIndex ); + + /* Release the entry in the phasing TSST list. */ + ulResult = Oct6100ApiReleasePhasingEntry( f_pApiInstance, f_usPhasingIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pPhasingEntry->usTimeslot, + pPhasingEntry->usStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); /* Release the TSST entry */ + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL; + } + } + else + { + return ulResult; + } + + /*=============================================================*/ + /* Update the phasing TSST's list entry. */ + + /* Mark the entry as closed. */ + pPhasingEntry->fReserved = FALSE; + pPhasingEntry->byEntryOpenCnt++; + + /* Decrement the number of phasing TSSTs opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPhasingTssts--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReservePhasingEntry + +Description: Reserves a phasing TSST API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusPhasingIndex Resulting index reserved in the phasing TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReservePhasingEntry +UINT32 Oct6100ApiReservePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pPhasingAlloc; + UINT32 ulResult; + UINT32 ulPhasingIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingAlloc ) + + ulResult = OctapiLlmAllocAlloc( pPhasingAlloc, &ulPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_PHASING_TSST_ALL_ENTRIES_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_3A; + } + + *f_pusPhasingIndex = (UINT16)( ulPhasingIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleasePhasingEntry + +Description: Releases the specified phasing TSST API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usPhasingIndex Index reserved in the phasing TSST API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleasePhasingEntry +UINT32 Oct6100ApiReleasePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pPhasingAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pPhasingAlloc ) + + ulResult = OctapiLlmAllocDealloc( pPhasingAlloc, f_usPhasingIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_3B; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c new file mode 100644 index 0000000..cf3affa --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c @@ -0,0 +1,3337 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to manage buffer playout. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 109 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_playout_buf_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoad + +Description: This function loads a playout buffer into external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer playout load structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadDef +UINT32 Oct6100BufferPlayoutLoadDef( + tPOCT6100_BUFFER_LOAD f_pBufferLoad ) +{ + f_pBufferLoad->pbyBufferPattern = NULL; + f_pBufferLoad->ulBufferSize = 128; + f_pBufferLoad->ulBufferPcmLaw = cOCT6100_PCM_U_LAW; + + f_pBufferLoad->pulBufferIndex = NULL; + f_pBufferLoad->pulPlayoutFreeMemSize = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoad +UINT32 Oct6100BufferPlayoutLoad( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD f_pBufferLoad ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadSer( f_pApiInstance, f_pBufferLoad, TRUE, cOCT6100_INVALID_INDEX ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoadBlockInit + +Description: This function allows the user to initialize loading a buffer + into external memory using blocks. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlockInit Pointer to buffer playout load block init structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadBlockInitDef +UINT32 Oct6100BufferPlayoutLoadBlockInitDef( + tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + f_pBufferLoadBlockInit->ulBufferSize = 128; + f_pBufferLoadBlockInit->ulBufferPcmLaw = cOCT6100_PCM_U_LAW; + + f_pBufferLoadBlockInit->pulBufferIndex = NULL; + f_pBufferLoadBlockInit->pulPlayoutFreeMemSize = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoadBlockInit +UINT32 Oct6100BufferPlayoutLoadBlockInit( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadBlockInitSer( f_pApiInstance, f_pBufferLoadBlockInit ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutLoadBlock + +Description: This function allows the user to load a buffer block into + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer playout load block structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutLoadBlockDef +UINT32 Oct6100BufferPlayoutLoadBlockDef( + tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + f_pBufferLoadBlock->ulBufferIndex = cOCT6100_INVALID_VALUE; + f_pBufferLoadBlock->ulBlockLength = cOCT6100_INVALID_VALUE; + f_pBufferLoadBlock->ulBlockOffset = cOCT6100_INVALID_VALUE; + + f_pBufferLoadBlock->pbyBufferPattern = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutLoadBlock +UINT32 Oct6100BufferPlayoutLoadBlock( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferLoadBlockSer( f_pApiInstance, f_pBufferLoadBlock ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutUnload + +Description: This function unloads a playout buffer from external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer playout unload structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutUnloadDef +UINT32 Oct6100BufferPlayoutUnloadDef( + tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ) +{ + f_pBufferUnload->ulBufferIndex = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutUnload +UINT32 Oct6100BufferPlayoutUnload( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferUnloadSer( f_pApiInstance, f_pBufferUnload, TRUE ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutAdd + +Description: This function adds a buffer to a port's playout list on the + selected channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutAddDef +UINT32 Oct6100BufferPlayoutAddDef( + tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + f_pBufferPlayoutAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutAdd->ulBufferIndex = cOCT6100_INVALID_VALUE; + + f_pBufferPlayoutAdd->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutAdd->ulMixingMode = cOCT6100_MIXING_MINUS_6_DB; + f_pBufferPlayoutAdd->lGainDb = 0; + + f_pBufferPlayoutAdd->fRepeat = FALSE; + f_pBufferPlayoutAdd->ulRepeatCount = cOCT6100_REPEAT_INFINITELY; + + f_pBufferPlayoutAdd->ulDuration = cOCT6100_INVALID_VALUE; + + f_pBufferPlayoutAdd->ulBufferLength = cOCT6100_AUTO_SELECT; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutAdd +UINT32 Oct6100BufferPlayoutAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutAddSer( f_pApiInstance, f_pBufferPlayoutAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStart + +Description: This function enables playout of the specified buffer on the + requested channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStartDef +UINT32 Oct6100BufferPlayoutStartDef( + tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ) +{ + f_pBufferPlayoutStart->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutStart->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutStart->fNotifyOnPlayoutStop = FALSE; + f_pBufferPlayoutStart->ulUserEventId = cOCT6100_INVALID_VALUE; + f_pBufferPlayoutStart->fAllowStartWhileActive = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutStart +UINT32 Oct6100BufferPlayoutStart( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutStartSer( f_pApiInstance, f_pBufferPlayoutStart, cOCT6100_BUFFER_PLAYOUT_EVENT_STOP ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStop + +Description: This function disables playout of a buffer on the specified + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStopDef +UINT32 Oct6100BufferPlayoutStopDef( + tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + f_pBufferPlayoutStop->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pBufferPlayoutStop->ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + f_pBufferPlayoutStop->fStopCleanly = TRUE; + f_pBufferPlayoutStop->pfAlreadyStopped = NULL; + f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = NULL; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100BufferPlayoutStop +UINT32 Oct6100BufferPlayoutStop( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100BufferPlayoutStopSer( f_pApiInstance, f_pBufferPlayoutStop ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetPlayoutBufferSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of playout buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetPlayoutBufferSwSizes +UINT32 Oct6100ApiGetPlayoutBufferSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate memory needed for playout buffer list. */ + f_pInstSizes->ulPlayoutBufList = f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER ); + + f_pInstSizes->ulPlayoutBufMemoryNodeList = 0; + + /* Calculate memory needed for playout buffer allocation software. */ + if ( f_pOpenChip->ulMaxPlayoutBuffers > 0 ) + { + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxPlayoutBuffers, &f_pInstSizes->ulPlayoutBufAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3C; + + f_pInstSizes->ulPlayoutBufMemoryNodeList = 2 * f_pOpenChip->ulMaxPlayoutBuffers * sizeof( tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE ); + } + else + { + f_pInstSizes->ulPlayoutBufAlloc = 0; + } + + /* Calculate memory needed for list and allocation software serialization. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufAlloc, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulPlayoutBufMemoryNodeList, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiPlayoutBufferSwInit + +Description: Initializes all elements of the instance structure associated + to playout buffers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiPlayoutBufferSwInit +UINT32 Oct6100ApiPlayoutBufferSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER pBufferList; + PVOID pBufferPlayoutAlloc; + UINT32 ulMaxBufferPlayout; + UINT32 ulResult, i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the maximum number of buffer playout. */ + ulMaxBufferPlayout = pSharedInfo->ChipConfig.usMaxPlayoutBuffers; + + /* Set all entries in the buffer playout list to unused. */ + mOCT6100_GET_BUFFER_LIST_PNT( pSharedInfo, pBufferList ) + + for ( i = 0; i < ulMaxBufferPlayout; i++ ) + { + pBufferList[ i ].fReserved = FALSE; + pBufferList[ i ].ulBufferSize = 0; + pBufferList[ i ].ulBufferBase = cOCT6100_INVALID_VALUE; + pBufferList[ i ].usDependencyCnt = 0; + pBufferList[ i ].byBufferPcmLaw = cOCT6100_PCM_U_LAW; + + } + + /* Initialize the buffer playout allocation software to "all free". */ + if ( ulMaxBufferPlayout > 0 ) + { + mOCT6100_GET_BUFFER_ALLOC_PNT( pSharedInfo, pBufferPlayoutAlloc ) + + ulResult = OctapiLlmAllocInit( &pBufferPlayoutAlloc, ulMaxBufferPlayout ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3D; + } + + /* Initialize the amount of free memory used by playout. */ + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadSer + +Description: Loads a buffer in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. The handle + identifying the buffer in all future function calls is + returned in this structure. + +f_fReserveListStruct Flag indicating if a list structure should be reserved + or if the structure has been reserved before. If this + is set, the f_ulBufIndex variable must also be set. + +f_ulBufIndex If the f_fReserveListStruct flag is set, this index + will identify the buffer playout list structure + that must be used to load the specified buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadSer +UINT32 Oct6100BufferLoadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, f_pBufferLoad, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the buffer. */ + ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, f_pBufferLoad, f_fReserveListStruct, f_ulBufIndex, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the buffer in external memory. */ + ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase, f_pBufferLoad->ulBufferSize, f_pBufferLoad->pbyBufferPattern ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new buffer's entry in the buffer list. */ + ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, f_pBufferLoad, ulBufferIndex, ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadBlockInitSer + +Description: Reserve resources for loading a buffer into external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlockInit Pointer to buffer configuration structure. The + handle identifying the buffer in all future + function calls is returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadBlockInitSer +UINT32 Oct6100BufferLoadBlockInitSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + tOCT6100_BUFFER_LOAD BufferLoad; + + Oct6100BufferPlayoutLoadDef( &BufferLoad ); + + /* Not to replicate the code, we use the BufferLoad functions directly. */ + BufferLoad.pulBufferIndex = f_pBufferLoadBlockInit->pulBufferIndex; + BufferLoad.pulPlayoutFreeMemSize = f_pBufferLoadBlockInit->pulPlayoutFreeMemSize; + BufferLoad.ulBufferPcmLaw = f_pBufferLoadBlockInit->ulBufferPcmLaw; + BufferLoad.ulBufferSize = f_pBufferLoadBlockInit->ulBufferSize; + BufferLoad.pbyBufferPattern = NULL; /* Must not check this for now */ + + /* Check the user's configuration of the buffer for errors, but do */ + /* not check if the buffer pointer is NULL. It is NULL for sure! */ + ulResult = Oct6100ApiCheckBufferParams( f_pApiInstance, &BufferLoad, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the buffer. */ + ulResult = Oct6100ApiReserveBufferResources( f_pApiInstance, &BufferLoad, TRUE, cOCT6100_INVALID_INDEX, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new buffer's entry in the buffer list. */ + ulResult = Oct6100ApiUpdateBufferEntry( f_pApiInstance, &BufferLoad, ulBufferIndex, ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferLoadBlockSer + +Description: Loads a buffer in external memory using blocks. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer block to be loaded into external + memory descriptor. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferLoadBlockSer +UINT32 Oct6100BufferLoadBlockSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ) +{ + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Check the user's configuration for errors. */ + ulResult = Oct6100ApiCheckBufferLoadBlockParams( f_pApiInstance, f_pBufferLoadBlock, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the buffer in external memory at the appropriate offset - must do some pointer arithmetic. */ + ulResult = Oct6100ApiWriteBufferInMemory( f_pApiInstance, ulBufferBase + f_pBufferLoadBlock->ulBlockOffset, + f_pBufferLoadBlock->ulBlockLength, f_pBufferLoadBlock->pbyBufferPattern + f_pBufferLoadBlock->ulBlockOffset ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBufferParams + +Description: Checks the user's buffer playout load configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. +f_fCheckBufferPtr Check if the buffer pointer is NULL or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBufferParams +UINT32 Oct6100ApiCheckBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fCheckBufferPtr ) +{ + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayout == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT; + + if ( f_pBufferLoad->pulBufferIndex == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + if( f_fCheckBufferPtr ) + { + if ( f_pBufferLoad->pbyBufferPattern == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN; + } + + if ( f_pBufferLoad->ulBufferSize < cOCT6100_MINIMUM_BUFFER_SIZE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL; + + if ( ( f_pBufferLoad->ulBufferSize % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + if ( f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_U_LAW && + f_pBufferLoad->ulBufferPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBufferLoadBlockParams + +Description: Checks the user's buffer playout load block configuration for + errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoadBlock Pointer to buffer block descriptor. +f_pulBufferBase Pointer to the base address of the buffer in external + memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBufferLoadBlockParams +UINT32 Oct6100ApiCheckBufferLoadBlockParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock, + OUT PUINT32 f_pulBufferBase ) +{ + /* Check for errors. */ + tPOCT6100_API_BUFFER pBufEntry; + + if ( f_pBufferLoadBlock->ulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_pBufferLoadBlock->ulBufferIndex ) + + if ( pBufEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + + if ( ( f_pBufferLoadBlock->ulBlockLength % 2 ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID; + + if ( ( f_pBufferLoadBlock->ulBlockOffset % 2 ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID; + + if ( f_pBufferLoadBlock->pbyBufferPattern == NULL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN; + + /* Check boundaries */ + if ( ( f_pBufferLoadBlock->ulBlockLength + f_pBufferLoadBlock->ulBlockOffset ) > pBufEntry->ulBufferSize ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + *f_pulBufferBase = pBufEntry->ulBufferBase; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufferResources + +Description: Reserves all resources needed for the new buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. + +f_fReserveListStruct Flag indicating if a list structure should be reserved + or if the structure has been reserved before. + +f_ulBufIndex If the f_fReserveListStruct flag is set, this index + will identifying the buffer playout list structure + that must be used to load the specified buffer. + +f_pulBufferIndex Allocated entry in buffer playout list. + +f_pulBufferBase Allocated external memory block for the buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufferResources +UINT32 Oct6100ApiReserveBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PUINT32 f_pulBufferBase ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the buffer list. */ + if ( f_fReserveListStruct == TRUE ) + { + ulResult = Oct6100ApiReserveBufPlayoutListEntry( f_pApiInstance, f_pulBufferIndex ); + } + else + { + *f_pulBufferIndex = f_ulBufIndex; + } + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Find a free block to store the buffer. */ + ulResult = Oct6100ApiReserveBufferPlayoutMemory( f_pApiInstance, f_pBufferLoad->ulBufferSize, f_pulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the list entry. */ + if ( f_fReserveListStruct == TRUE ) + { + ulTempVar = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, *f_pulBufferIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteBufferInMemory + +Description: Writes the buffer in external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulBufferBase Allocated external memory address for the buffer. + +f_ulBufferLength Length in bytes of the buffer to be copied in memory. + +f_pbyBuffer Address where the buffer should be copied from. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteBufferInMemory +UINT32 Oct6100ApiWriteBufferInMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferBase, + IN UINT32 f_ulBufferLength, + IN PUINT8 f_pbyBuffer ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + PUINT8 pbyPlayoutBuffer; + UINT32 ulByteCount = 0; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Write the buffer in external memory. */ + ulNumWrites = f_ulBufferLength / 2; + + BurstParams.ulWriteAddress = f_ulBufferBase; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyPlayoutBuffer = f_pbyBuffer; + + /* Check if we can maximize the bandwidth through the CPU port. */ + if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 ) + { + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x08ff; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyPlayoutBuffer [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyPlayoutBuffer [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + + } + + /* Make sure we revert back the changes made to the CPU bandwidth register. */ + if ( f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels == 0 ) + { + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBufferEntry + +Description: Updates the new buffer's entry in the buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pBufferLoad Pointer to buffer configuration structure. +f_ulBufferIndex Allocated entry in buffer playout list. +f_ulBufferBase Allocated external memory block for the buffer. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBufferEntry +UINT32 Oct6100ApiUpdateBufferEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN UINT32 f_ulBufferIndex, + IN UINT32 f_ulBufferBase ) +{ + tPOCT6100_API_BUFFER pBufEntry; + UINT32 ulBufferSize = f_pBufferLoad->ulBufferSize; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex ) + + /* Copy the buffer's configuration and allocated resources. */ + pBufEntry->ulBufferSize = f_pBufferLoad->ulBufferSize; + pBufEntry->byBufferPcmLaw = (UINT8)( f_pBufferLoad->ulBufferPcmLaw & 0xFF ); + pBufEntry->ulBufferBase = f_ulBufferBase; + + /* Update the entries flags. */ + pBufEntry->usDependencyCnt = 0; + + /* Mark the buffer as opened. */ + pBufEntry->fReserved = TRUE; + + /* Increment the number of buffer loaded into the chip.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers++; + + /* Refresh the amount of memory used by buffer playout. */ + + /* Reserved size is divisible by 64. */ + if ( ulBufferSize % 64 ) + ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) ); + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed += ulBufferSize; + + /* Return the buffer index to the user. */ + *f_pBufferLoad->pulBufferIndex = f_ulBufferIndex; + + /* Return the amount of free memory left in the chip. */ + /* Note that this value does not give the "fragmentation" state of the available memory. */ + /* This value only gives the amount of free memory */ + if( f_pBufferLoad->pulPlayoutFreeMemSize ) + *f_pBufferLoad->pulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferUnloadSer + +Description: Unloads a buffer from external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer unload structure. +f_fReleaseListStruct Whether to release the buffer playout list structure + or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferUnloadSer +UINT32 Oct6100BufferUnloadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + IN BOOL f_fReleaseListStruct ) +{ + UINT32 ulBufferIndex; + UINT32 ulBufferBase; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertBufferParams( f_pApiInstance, f_pBufferUnload, &ulBufferIndex, &ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the unloaded buffer. */ + ulResult = Oct6100ApiReleaseBufferResources( f_pApiInstance, ulBufferIndex, ulBufferBase, f_fReleaseListStruct ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertBufferParams + +Description: Checks the buffer playout unload configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferUnload Pointer to buffer unload structure. +f_pulBufferIndex Pointer to the index of the buffer in the API's buffers list. +f_pulBufferBase Pointer to the base address of the buffer in external memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertBufferParams +UINT32 Oct6100ApiAssertBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + OUT PUINT32 f_pulBufferIndex, + OUT PUINT32 f_pulBufferBase ) +{ + tPOCT6100_API_BUFFER pBufEntry; + + *f_pulBufferIndex = f_pBufferUnload->ulBufferIndex; + + if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, *f_pulBufferIndex ) + + /* Check for errors. */ + if ( pBufEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + if ( pBufEntry->usDependencyCnt != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES; + + /* Return all info needed to invalidate buffer. */ + *f_pulBufferBase = pBufEntry->ulBufferBase; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufferResources + +Description: Release resources needed by the buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulBufferIndex Allocated entry in buffer playout list. +f_ulBufferBase Allocated external memory block for the buffer. +f_fReleaseListStruct Free the list structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufferResources +UINT32 Oct6100ApiReleaseBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferIndex, + IN UINT32 f_ulBufferBase, + IN BOOL f_fReleaseListStruct ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BUFFER pBufEntry; + UINT32 ulResult; + UINT32 ulBufferSize; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Free the external memory reserved for the buffer. */ + ulResult = Oct6100ApiReleaseBufferPlayoutMemory( f_pApiInstance, f_ulBufferBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3E; + + /* Release the entry from the buffer list. */ + if ( f_fReleaseListStruct == TRUE ) + ulResult = Oct6100ApiReleaseBufPlayoutListEntry( f_pApiInstance, f_ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufEntry, f_ulBufferIndex ); + + /* Save buffer size before releasing that entry, will be needed to calculate the amount of */ + /* free memory left for the user. */ + ulBufferSize = pBufEntry->ulBufferSize; + + /* Flag the buffer entry as free. */ + pBufEntry->fReserved = FALSE; + + /* Decrement the number of buffer loaded into the chip. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberPlayoutBuffers--; + + /* Refresh the amount of memory used by buffer playout. */ + /* Reserved size is divisible by 64. */ + if ( ulBufferSize % 64 ) + ulBufferSize = ulBufferSize + ( 64 - ( ulBufferSize % 64 ) ); + f_pApiInstance->pSharedInfo->ChipStats.ulPlayoutMemUsed -= ulBufferSize; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutAddSer + +Description: This function adds a buffer to a channel buffer list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutAddSer +UINT32 Oct6100BufferPlayoutAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ) +{ + UINT32 ulBufferIndex; + UINT32 ulChannelIndex; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckPlayoutAddParams( f_pApiInstance, f_pBufferPlayoutAdd, &ulChannelIndex, &ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to activate buffer playout. */ + ulResult = Oct6100ApiWriteBufferAddStructs( f_pApiInstance, f_pBufferPlayoutAdd, ulChannelIndex, ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPlayoutAddParams + +Description: Check the validity of the channel and buffer requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. +f_pulChannelIndex Pointer to the channel index of the selected channel. +f_pulBufferIndex Pointer to the buffer index within the API's buffer list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPlayoutAddParams +UINT32 Oct6100ApiCheckPlayoutAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutAdd->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutAdd->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutAdd->fRepeat != TRUE && f_pBufferPlayoutAdd->fRepeat != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT; + + if ( f_pBufferPlayoutAdd->fRepeat == TRUE ) + { + if ( f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY ) + { + if ( f_pBufferPlayoutAdd->ulRepeatCount == 0x0 + || f_pBufferPlayoutAdd->ulRepeatCount > cOCT6100_REPEAT_MAX) + { + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT; + } + } + } + + if ( f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_0_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_6_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MINUS_12_DB && + f_pBufferPlayoutAdd->ulMixingMode != cOCT6100_MIXING_MUTE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING; + + if ( ( f_pBufferPlayoutAdd->lGainDb < -24 ) + || ( f_pBufferPlayoutAdd->lGainDb > 24 ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* Check if repeat flag has been used for this port. */ + if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) ) + || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check the buffer information. */ + + *f_pulBufferIndex = f_pBufferPlayoutAdd->ulBufferIndex; + if ( *f_pulBufferIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX; + + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, *f_pulBufferIndex ) + + if ( pBufferEntry->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN; + + /* Check if the play length is not larger then the currently uploaded buffer. */ + if ( ( f_pBufferPlayoutAdd->ulBufferLength > pBufferEntry->ulBufferSize ) && + ( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + + if( f_pBufferPlayoutAdd->ulBufferLength != cOCT6100_AUTO_SELECT ) + { + if ( f_pBufferPlayoutAdd->ulBufferLength < cOCT6100_MINIMUM_BUFFER_SIZE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL; + + if ( ( f_pBufferPlayoutAdd->ulBufferLength % cOCT6100_BUFFER_SIZE_GRANULARITY ) != 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE; + } + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteBufferAddStructs + +Description: Write the buffer playout event in the channel's port playout + circular buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutAdd Pointer to buffer playout add structure. +f_ulChannelIndex Index of the channel on which the buffer is to be added. +f_ulBufferIndex Index of the buffer structure within the API's buffer list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteBufferAddStructs +UINT32 Oct6100ApiWriteBufferAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulEventBuffer; + + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + + UINT32 ulWritePtr; + UINT32 ulReadPtr; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulEventIndex; + UINT32 ulMask; + + UINT32 ulRepeatCount = 0; + BOOL fRepeatCountSet = FALSE; + UINT32 ulDurationModulo = 0; + UINT32 ulEventsToCreate = 1; + UINT32 ulBufferDurationMs; + + UINT32 ulBufferLength; + UINT16 usTempData = 0; + + UINT16 usReadData; + UINT32 ulChipWritePtr; + UINT32 ulReadData; + UINT32 ulLoopCnt = 0; + BOOL fStillPlaying = TRUE; + BOOL fCheckHardStop = FALSE; + BOOL fOldBufferPlayoutVersion = FALSE; + + UINT32 aulWaitTime[ 2 ]; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex ); + + /* Select the buffer of interest. */ + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /*=======================================================================*/ + /* Calculate the repeat count. */ + + /* The buffer length is either the total buffer size or the value specified by the user */ + if ( f_pBufferPlayoutAdd->ulBufferLength == cOCT6100_AUTO_SELECT ) + { + ulBufferLength = pBufferEntry->ulBufferSize; + } + else + { + ulBufferLength = f_pBufferPlayoutAdd->ulBufferLength; + } + + if ( f_pBufferPlayoutAdd->ulDuration != cOCT6100_INVALID_VALUE ) + { + /* With duration and buffer length, we can find the number of times we must repeat playing this buffer. */ + ulBufferDurationMs = ulBufferLength / cOCT6100_SAMPLES_PER_MS; + ulRepeatCount = f_pBufferPlayoutAdd->ulDuration / ulBufferDurationMs; + fRepeatCountSet = TRUE; + + /* Check if buffer is larger then asked duration. */ + if ( ulRepeatCount != 0x0 ) + { + /* We might have to create more then 1 event to accomodate for the repeat-max limit. */ + ulEventsToCreate = ( ulRepeatCount / cOCT6100_REPEAT_MAX ) + 1; + } + else + { + /* No repeat event. Maybe only the duration modulo! */ + ulEventsToCreate = 0x0; + } + + /* Check if must create a second event for a buffer that cannot be played completely. */ + ulDurationModulo = f_pBufferPlayoutAdd->ulDuration % ulBufferDurationMs; + if ( ulDurationModulo != 0x0 ) + { + ulDurationModulo *= cOCT6100_SAMPLES_PER_MS; + if ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY ) + { + /* Round the modulo to be on a buffer size granularity. */ + /* This will round down. */ + ulDurationModulo = ( ulDurationModulo / cOCT6100_BUFFER_SIZE_GRANULARITY ) * cOCT6100_BUFFER_SIZE_GRANULARITY; + + /* If the event about to be created is smaller then the minimum buffer size, */ + /* round up to the minimum required by the hardware. */ + if ( ulDurationModulo < cOCT6100_MINIMUM_BUFFER_SIZE ) + ulDurationModulo = cOCT6100_MINIMUM_BUFFER_SIZE; + ulEventsToCreate++; + } + else + { + /* The modulo is too small to be played. Skip. */ + ulDurationModulo = 0; + } + } + } + else if ( f_pBufferPlayoutAdd->fRepeat == TRUE + && f_pBufferPlayoutAdd->ulRepeatCount != cOCT6100_REPEAT_INFINITELY ) + { + /* The repeat count is set directly from the user. */ + ulRepeatCount = f_pBufferPlayoutAdd->ulRepeatCount; + fRepeatCountSet = TRUE; + } + + /*=======================================================================*/ + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Read the read pointer. */ + ulAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Must read in memory directly since this value is changed by hardware. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulAddress, &ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Compare the pointers... Are they different? If so, there is something already in the list. */ + if ( ulReadPtr != ulWritePtr ) + { + /* Check if there is enough room for the playout events. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) ) + fCheckHardStop = TRUE; + } + else + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) ) + fCheckHardStop = TRUE; + + fOldBufferPlayoutVersion = TRUE; + } + + if ( fCheckHardStop == TRUE ) + { + /* Ok. From what was read, the list is full. But we might still have a chance if the hard-stop */ + /* version was used. In this case, some of the buffers in the list might */ + /* become free in a couple of milliseconds, so try to wait for this. */ + + if ( ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) ) + || ( ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) ) + { + /* Read the 'chip' write pointer in the hardware. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + while( fStillPlaying == TRUE ) + { + /* Read the read pointer until equals to the write pointer. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer.*/ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr == ulChipWritePtr ) + break; + + ulLoopCnt++; + if ( ulLoopCnt > cOCT6100_MAX_LOOP ) + { + return cOCT6100_ERR_FATAL_E7; + } + + aulWaitTime[ 0 ] = 100; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear hard-stop flag. */ + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* No hard stop for now. */ + pEchoChannel->fRinHardStop = FALSE; + } + else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + /* No hard stop for now. */ + pEchoChannel->fSoutHardStop = FALSE; + } + + /* Now check again if the event can be added... */ + if ( fOldBufferPlayoutVersion == FALSE ) + { + if ( (UINT8)( ( ulWritePtr - ulReadPtr ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ) ) >= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - (UINT8)ulEventsToCreate ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + else /* if ( fOldBufferPlayoutVersion == TRUE ) */ + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - ulReadPtr ) & 0x1F ) >= ( 0x20 - ulEventsToCreate ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + + /* Good, at least another buffer can be added! Add the buffer to the list. */ + } + else + { + /* Well the list is full! */ + return cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL; + } + } + } + + /*=======================================================================*/ + /* Write the events. */ + + for ( ulEventIndex = 0; ulEventIndex < ulEventsToCreate; ulEventIndex ++ ) + { + /* Set the playout event base address. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ))); + } + else + { + /* Old 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + (f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * (ulWritePtr & 0x1F)); + } + + /* EVENT BASE + 0 */ + /* Make sure the xIS and xHS bits are cleared. */ + ulTempData = 0; + + /* Set the repeat count. */ + if ( fRepeatCountSet == TRUE ) + { + if ( ( ulRepeatCount != 0x0 ) && ( ulRepeatCount <= cOCT6100_REPEAT_MAX ) ) + { + /* Use repeat count directly. */ + ulTempData |= ulRepeatCount; + + /* Will be used later when creating the duration modulo event. */ + ulRepeatCount = 0; + } + else if ( ulRepeatCount != 0x0 ) + { + /* Get ready for next event. */ + ulRepeatCount -= cOCT6100_REPEAT_MAX; + + /* Set maximum for this event. */ + ulTempData |= cOCT6100_REPEAT_MAX; + } + else + { + /* Duration modulo case. Nothing to set here. */ + } + } + else /* if ( fRepeatCountSet != TRUE ) */ + { + /* Repeat only once. */ + ulTempData |= 0x1; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* EVENT BASE + 4 */ + /* Set the buffer base address and playout configuration. */ + ulAddress += 4; + ulTempData = pBufferEntry->ulBufferBase & 0x07FFFFFF; + + /* Set play indefinitely or loop N times. */ + if ( ( fRepeatCountSet == FALSE ) && ( f_pBufferPlayoutAdd->fRepeat == TRUE ) ) + { + /* Repeat indefinitely. */ + ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET; + + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + pEchoChannel->fRinBufPlayoutRepeatUsed = TRUE; + else /* if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + pEchoChannel->fSoutBufPlayoutRepeatUsed = TRUE; + } + + /* Use loop N times feature. */ + ulTempData |= 0x1 << cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET; + + /* Set the law.*/ + ulTempData |= ( pBufferEntry->byBufferPcmLaw << cOCT6100_PLAYOUT_EVENT_LAW_OFFSET ); + + /* Set the mixing configuration.*/ + ulTempData |= f_pBufferPlayoutAdd->ulMixingMode << cOCT6100_PLAYOUT_EVENT_MIX_OFFSET; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + /* EVENT BASE + 8 */ + /* Set the buffer size and playout gain. */ + ulAddress += 4; + + /* Check if we are setting the duration modulo. This would be the last event and this */ + /* event is of a very specific size. */ + if ( ( fRepeatCountSet == TRUE ) + && ( ulEventIndex == ( ulEventsToCreate - 1 ) ) + && ( ulDurationModulo != 0x0 ) ) + { + /* The duration modulo variable contains all that is needed here. */ + ulBufferLength = ulDurationModulo; + } + ulTempData = ulBufferLength; + + /* Adjust playout gain. */ + if ( f_pBufferPlayoutAdd->lGainDb != 0 ) + { + /* Convert the dB value into OctFloat format. */ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pBufferPlayoutAdd->lGainDb ); + ulTempData |= ( usTempData & 0xFF00 ) << 16; + } + else + { + ulTempData |= cOCT6100_PLAYOUT_GAIN; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* EVENT BASE + 0xC */ + ulAddress += 4; + ulTempData = ( ulBufferLength - 1 ) & 0xFFFFFFC0; /* Must be multiple of 64 bytes */ + + /* Adjust playout gain. */ + if ( f_pBufferPlayoutAdd->lGainDb != 0 ) + { + ulTempData |= ( usTempData & 0xFF ) << 24; + } + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulAddress, ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Next event. */ + ulWritePtr++; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Increment the write pointer to make it point to the next empty entry. */ + + if ( f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pEchoChannel->ulRinBufWritePtr = ( pEchoChannel->ulRinBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + /* Remember that a buffer was added on the rin port. */ + pEchoChannel->fRinBufAdded = TRUE; + } + else /* f_pBufferPlayoutAdd->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + pEchoChannel->ulSoutBufWritePtr = ( pEchoChannel->ulSoutBufWritePtr + ulEventsToCreate ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + /* Remember that a buffer was added on the sout port. */ + pEchoChannel->fSoutBufAdded = TRUE; + } + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStartSer + +Description: Starts buffer playout on a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. + +f_ulPlayoutStopEventType Playout stop event type to be generated if required. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStartSer +UINT32 Oct6100BufferPlayoutStartSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulPlayoutStopEventType ) +{ + UINT32 ulBufferIndex = 0; + UINT32 ulChannelIndex; + BOOL fNotifyOnPlayoutStop; + UINT32 ulUserEventId; + BOOL fAddToCurrentlyPlayingList; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiCheckPlayoutStartParams( f_pApiInstance, f_pBufferPlayoutStart, &ulChannelIndex, &ulBufferIndex, &fNotifyOnPlayoutStop, &ulUserEventId, &fAddToCurrentlyPlayingList ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to activate buffer playout. */ + ulResult = Oct6100ApiWriteChanPlayoutStructs( f_pApiInstance, f_pBufferPlayoutStart, ulChannelIndex, ulBufferIndex, fNotifyOnPlayoutStop, ulUserEventId, fAddToCurrentlyPlayingList, f_ulPlayoutStopEventType ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPlayoutStartParams + +Description: Check the validity of the channel and buffer requested. + Check the validity of the flags requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. +f_pulChannelIndex Pointer to the channel index of the selected channel. +f_pulBufferIndex Pointer to the buffer index within the API's buffer list. +f_pfNotifyOnPlayoutStop Pointer to the notify on playout stop flag. +f_pulUserEventId Pointer to the user event id specified. +f_pfAllowStartIfActive Pointer to the add to currently playing list flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPlayoutStartParams +UINT32 Oct6100ApiCheckPlayoutStartParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PBOOL f_pfNotifyOnPlayoutStop, + OUT PUINT32 f_pulUserEventId, + OUT PBOOL f_pfAllowStartIfActive ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutStart->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutStart->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop != FALSE + && f_pBufferPlayoutStart->fNotifyOnPlayoutStop != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP; + + if ( f_pBufferPlayoutStart->fAllowStartWhileActive != FALSE + && f_pBufferPlayoutStart->fAllowStartWhileActive != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutStart->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutStart->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* The channel cannot be in POWER_DOWN or HT_FREEZE to start the playout. */ + if ( ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + || ( pEchoChannel->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE; + + /* The channel's NLP must be enabled for playout to occur. */ + if ( pEchoChannel->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check if the user activated the buffer playout events. */ + + if ( f_pBufferPlayoutStart->fNotifyOnPlayoutStop == TRUE + && f_pApiInstance->pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED; + + /*=====================================================================*/ + + /*=====================================================================*/ + /* Check if there is actually a buffer added in the list. */ + + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pEchoChannel->fRinBufAdded == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY; + } + else /* if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + if ( pEchoChannel->fSoutBufAdded == FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY; + } + + /*=====================================================================*/ + + /* Return the requested information. */ + *f_pfNotifyOnPlayoutStop = f_pBufferPlayoutStart->fNotifyOnPlayoutStop; + *f_pulUserEventId = f_pBufferPlayoutStart->ulUserEventId; + *f_pfAllowStartIfActive = f_pBufferPlayoutStart->fAllowStartWhileActive; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChanPlayoutStructs + +Description: Write the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStart Pointer to buffer playout start structure. +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulBufferIndex Index of the buffer within the API's buffer list. +f_fNotifyOnPlayoutStop Flag for the notify on playout stop. +f_ulUserEventId User event id passed to the user when a playout event is generated. +f_fAllowStartIfActive Add to currently playing list flag. +f_ulPlayoutStopEventType Playout stop event type to be generated if required. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChanPlayoutStructs +UINT32 Oct6100ApiWriteChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex, + IN BOOL f_fNotifyOnPlayoutStop, + IN UINT32 f_ulUserEventId, + IN BOOL f_fAllowStartIfActive, + IN UINT32 f_ulPlayoutStopEventType ) +{ + tPOCT6100_API_BUFFER pBufferEntry; + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + + UINT32 ulResult; + + UINT32 ulWritePtr; + UINT32 ulChipWritePtr; + PUINT32 pulSkipPtr; + UINT32 ulWritePtrBytesOfst; + UINT32 ulSkipPtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulSkipPtrBitOfst; + UINT32 ulWritePtrFieldSize; + UINT32 ulSkipPtrFieldSize; + + UINT32 ulIgnoreBytesOfst; + UINT32 ulIgnoreBitOfst; + UINT32 ulIgnoreFieldSize; + + UINT32 ulHardSkipBytesOfst; + UINT32 ulHardSkipBitOfst; + UINT32 ulHardSkipFieldSize; + + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulReadData; + UINT32 ulReadPtr; + UINT32 ulLoopCnt = 0; + + UINT16 usReadData; + + BOOL fBufferPlayoutStopDetected; + BOOL fWriteSkipPtr = FALSE; + BOOL fStillPlaying = TRUE; + + UINT32 aulWaitTime[ 2 ]; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBufferEntry, f_ulBufferIndex ); + + /* First off, check for buffer playout events, if requested for this channel/port. */ + /* At the same time, if requested, check that the playout has stopped for this channel/port. */ + if ( ( ( pEchoChannel->fRinBufPlaying == TRUE ) + && ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE ) || ( f_fAllowStartIfActive == FALSE ) ) + && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) ) + || ( ( ( pEchoChannel->fSoutBufPlaying == TRUE ) || ( f_fAllowStartIfActive == FALSE ) ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE ) + && ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) ) + { + /* Buffer playout might still be going on for this channel/port. */ + ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, + f_ulChannelIndex, + f_pBufferPlayoutStart->ulPlayoutPort, + pEchoChannel->fRinBufPlayoutNotifyOnStop, + &fBufferPlayoutStopDetected ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the user requested to only start if playout is over. Return an error if */ + /* buffer playout is still going on on this channel/port. */ + if ( ( f_fAllowStartIfActive == FALSE ) && ( fBufferPlayoutStopDetected == FALSE ) ) + { + /* No go! User should wait for the current list to stop, or call the */ + /* Oct6100BufferPlayoutStop function. */ + return cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE; + } + } + + /* Select the buffer of interest. */ + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + pulSkipPtr = &pEchoChannel->ulRinBufSkipPtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4; + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4; + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4; + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + pulSkipPtr = &pEchoChannel->ulSoutBufSkipPtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4; + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4; + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4; + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Check if we must wait for stop to complete before starting a new list. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) && ( pEchoChannel->fRinHardStop == TRUE ) ) + || ( ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) && ( pEchoChannel->fSoutHardStop == TRUE ) ) ) + { + /* Read the read pointer. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulReadData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulChipWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + while( fStillPlaying == TRUE ) + { + /* Read the read pointer until equals to the write pointer. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( ulReadPtr == ulChipWritePtr ) + break; + + ulLoopCnt++; + if( ulLoopCnt > cOCT6100_MAX_LOOP ) + { + return cOCT6100_ERR_FATAL_E6; + } + + aulWaitTime[ 0 ] = 100; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Check if must clear the skip bit. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* Make sure the skip bit is cleared to start playout! */ + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, pEchoChannel, ulAddress, &ulTempData, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + /* Cleared! */ + ulTempData &= ( ~ulMask ); + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the hard skip bit is cleared to start playout! */ + ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulHardSkipBitOfst, &ulMask ); + + /* Cleared! */ + ulTempData &= ( ~ulMask ); + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Write the skip and write pointer to activate buffer playout. */ + + /* Update the skip pointer. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE ) + || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) ) + { + /* Old 31 events image. */ + if ( ( ( ulWritePtr - *pulSkipPtr ) & 0x7F ) > 63 ) + { + *pulSkipPtr = ( ulWritePtr - 63 ) & 0x7F; + fWriteSkipPtr = TRUE; + } + } + else + { + /* No need to update the skip pointer, a bit needs to be set when skipping. */ + /* fWriteSkipPtr set to FALSE from variable declaration. */ + } + + if ( fWriteSkipPtr == TRUE ) + { + /*=======================================================================*/ + /* Fetch and modify the skip pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= *pulSkipPtr << ulSkipPtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + } + + + /*=======================================================================*/ + /* Fetch and modify the write pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulWritePtr << ulWritePtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now update the state of the channel stating that the buffer playout is activated. */ + + /* Select the buffer of interest.*/ + if ( f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the global ports active stat must be incremented. */ + if ( pEchoChannel->fRinBufPlaying == FALSE ) + { + /* Increment the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++; + } + + pEchoChannel->fRinBufPlaying = TRUE; + /* Keep the new notify on event flag. */ + pEchoChannel->fRinBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF ); + /* Keep the specified user event id. */ + pEchoChannel->ulRinUserBufPlayoutEventId = f_ulUserEventId; + /* Keep type of event to be generated. */ + pEchoChannel->byRinPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF ); + /* No hard stop for now. */ + pEchoChannel->fRinHardStop = FALSE; + /* No buffer added in the rin list for now. */ + pEchoChannel->fRinBufAdded = FALSE; + /* Buffer playout is active on this channel. */ + pEchoChannel->fBufPlayoutActive = TRUE; + } + else /* f_pBufferPlayoutStart->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the global ports active stat must be incremented. */ + if ( pEchoChannel->fSoutBufPlaying == FALSE ) + { + /* Increment the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts++; + } + + pEchoChannel->fSoutBufPlaying = TRUE; + /* Keep the new notify on event flag. */ + pEchoChannel->fSoutBufPlayoutNotifyOnStop = (UINT8)( f_fNotifyOnPlayoutStop & 0xFF ); + /* Keep the specified user event id. */ + pEchoChannel->ulSoutUserBufPlayoutEventId = f_ulUserEventId; + /* Keep type of event to be generated. */ + pEchoChannel->bySoutPlayoutStopEventType = (UINT8)( f_ulPlayoutStopEventType & 0xFF ); + /* No hard stop for now. */ + pEchoChannel->fSoutHardStop = FALSE; + /* No buffer added in the sout list for now. */ + pEchoChannel->fSoutBufAdded = FALSE; + /* Buffer playout is active on this channel. */ + pEchoChannel->fBufPlayoutActive = TRUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100BufferPlayoutStopSer + +Description: Stops buffer playout on a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100BufferPlayoutStopSer +UINT32 Oct6100BufferPlayoutStopSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ) +{ + UINT32 ulChannelIndex; + UINT16 usEchoMemIndex; + UINT32 ulResult; + + /* Check the user's configuration of the buffer for errors. */ + ulResult = Oct6100ApiAssertPlayoutStopParams( + f_pApiInstance, + f_pBufferPlayoutStop, + &ulChannelIndex, + &usEchoMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to deactivate buffer playout. */ + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + f_pBufferPlayoutStop, + ulChannelIndex, + usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertPlayoutStopParams + +Description: Check the validity of the channel and buffer requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. +f_pulChannelIndex Pointer to the channel index on which playout is to be stopped. +f_pusEchoMemIndex Pointer to the echo mem index on which playout is to be stopped. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertPlayoutStopParams +UINT32 Oct6100ApiAssertPlayoutStopParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT16 f_pusEchoMemIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxPlayoutBuffers == 0 ) + return cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED; + + if ( f_pBufferPlayoutStop->ulChannelHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + if ( f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pBufferPlayoutStop->ulPlayoutPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT; + + if ( f_pBufferPlayoutStop->fStopCleanly != TRUE && f_pBufferPlayoutStop->fStopCleanly != FALSE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pBufferPlayoutStop->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pBufferPlayoutStop->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID; + + /* Return echo memory index. */ + *f_pusEchoMemIndex = pEchoChannel->usEchoMemIndex; + + /* Check if buffer playout is active for the selected port. */ + if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + && ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufAdded == FALSE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED; + + if ( ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) + && ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufAdded == FALSE ) ) + return cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED; + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateChanPlayoutStructs + +Description: Write the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pBufferPlayoutStop Pointer to buffer playout stop structure. +f_ulChannelIndex Index of the channel within the API's channel list. +f_usEchoMemIndex Index of the echo channel in hardware memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateChanPlayoutStructs +UINT32 Oct6100ApiInvalidateChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex, + IN UINT16 f_usEchoMemIndex + + ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + + UINT32 ulResult; + + UINT32 ulWritePtrBytesOfst; + UINT32 ulWritePtrBitOfst; + UINT32 ulWritePtrFieldSize; + UINT32 ulSkipPtrBytesOfst; + UINT32 ulSkipPtrBitOfst; + UINT32 ulSkipPtrFieldSize; + UINT32 ulIgnoreBytesOfst; + UINT32 ulIgnoreBitOfst; + UINT32 ulIgnoreFieldSize; + UINT32 ulHardSkipBytesOfst; + UINT32 ulHardSkipBitOfst; + UINT32 ulHardSkipFieldSize; + UINT32 ulReadPtrBytesOfst; + UINT32 ulReadPtrBitOfst; + UINT32 ulReadPtrFieldSize; + + UINT32 ulSkipPtr; + UINT32 ulWritePtr; + UINT32 ulReadPtr = 0; + UINT32 ulCurrentPtr; + + UINT32 ulPlayoutBaseAddress; + UINT32 ulAddress; + UINT32 ulTempData; + UINT32 ulMask; + UINT32 ulReadData; + + UINT16 usReadData; + BOOL fCheckStop = FALSE; + + UINT32 ulEventBuffer; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex ); + + /* Select the port of interest. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulWritePtr = pEchoChannel->ulRinBufWritePtr; + ulSkipPtr = ulWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize; + + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.usDwordOffset * 4; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byBitOffset; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst.byFieldSize; + + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.usDwordOffset * 4; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byBitOffset; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst.byFieldSize; + + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.usDwordOffset * 4; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byBitOffset; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulWritePtr = pEchoChannel->ulSoutBufWritePtr; + ulSkipPtr = ulWritePtr; + + ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4; + ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset; + ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize; + + ulSkipPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.usDwordOffset * 4; + ulSkipPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byBitOffset; + ulSkipPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst.byFieldSize; + + ulIgnoreBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.usDwordOffset * 4; + ulIgnoreBitOfst = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byBitOffset; + ulIgnoreFieldSize = pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst.byFieldSize; + + ulHardSkipBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.usDwordOffset * 4; + ulHardSkipBitOfst = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byBitOffset; + ulHardSkipFieldSize = pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst.byFieldSize; + + ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4; + ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset; + ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize; + } + + /* Set the playout feature base address. */ + ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Check if something is currently playing. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pEchoChannel->fRinBufPlaying == TRUE ) + { + /* Check if we are stopping it or if it stopped by itself. */ + fCheckStop = TRUE; + } + else + { + /* Not playing! */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + { + if ( pEchoChannel->fSoutBufPlaying == TRUE ) + { + /* Check if we are stopping it or if it stopped by itself. */ + fCheckStop = TRUE; + } + else + { + /* Not playing! */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + + if ( ( fCheckStop == TRUE ) || ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) ) + { + /* Read the read pointer. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulReadPtrBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulReadPtrBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask ); + + /* Store the read pointer. */ + ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst; + + /* Playout has finished when the read pointer reaches the write pointer. */ + if ( f_pBufferPlayoutStop->pfAlreadyStopped != NULL ) + { + if ( ulReadPtr != ulWritePtr ) + *f_pBufferPlayoutStop->pfAlreadyStopped = FALSE; + else /* if ( ulReadPtr == ulWritePtr ) */ + *f_pBufferPlayoutStop->pfAlreadyStopped = TRUE; + } + } + + /* If the skip bits are located in the event itself, the playout is stopped by setting the */ + /* skip pointer to the hardware chip write pointer. Read it directly from the NLP configuration. */ + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + if ( ulReadPtr != ulWritePtr ) + { + /* Get the write pointer in the chip. */ + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulReadData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + /* Store the write pointer. */ + ulWritePtr = ( ulReadData & ulMask ) >> ulWritePtrBitOfst; + ulSkipPtr = ulWritePtr; + } + } + + /* Check if must clear repeat bit. */ + if ( ( ( pEchoChannel->fRinBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) ) + || ( ( pEchoChannel->fSoutBufPlayoutRepeatUsed == TRUE ) && ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) ) ) + { + if ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + || ( ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + && ( ulWritePtr != ulReadPtr ) ) ) + { + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + } + + /* Set the playout event base address. */ + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ))); + } + else + { + /* Old 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + (cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ( ( ulWritePtr - 1 ) & 0x1F)); + } + + /* EVENT BASE + 4 */ + /* Playout configuration. */ + ulAddress += 4; + + ReadParams.ulReadAddress = ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read-clear-write the new repeat bit. */ + usReadData &= 0x7FFF; + + WriteParams.ulWriteAddress = ulAddress; + WriteParams.usWriteData = usReadData; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Write the skip to the value of the write pointer to stop buffer playout. */ + + /*=======================================================================*/ + /* First set the ignore skip clean bit if required. */ + + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == FALSE ) + || ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == FALSE ) ) + { + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Check if the skip need to be clean or not. */ + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + ulTempData |= 0x1 << ulIgnoreBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Fetch and modify the write pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulWritePtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, pEchoChannel, ulAddress, &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulWritePtr << ulWritePtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Fetch and modify the skip pointer. */ + + ulAddress = ulPlayoutBaseAddress + ulSkipPtrBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulSkipPtrFieldSize, ulSkipPtrBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + ulTempData |= ulSkipPtr << ulSkipPtrBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* If in the new buffer playout case, things are in a different order. */ + + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) + { + if ( ( pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip == TRUE ) ) + { + ulAddress = ulPlayoutBaseAddress + ulHardSkipBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulHardSkipFieldSize, ulHardSkipBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Check if the skip need to be clean or not. */ + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + ulTempData |= 0x1 << ulHardSkipBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now is the appropriate time to skip! */ + ulAddress = ulPlayoutBaseAddress + ulIgnoreBytesOfst; + + ulResult = oct6100_retrieve_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + &ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + mOCT6100_CREATE_FEATURE_MASK( ulIgnoreFieldSize, ulIgnoreBitOfst, &ulMask ); + + ulTempData &= ( ~ulMask ); + + /* Set the skip bit. */ + ulTempData |= 0x1 << ulIgnoreBitOfst; + + ulResult = oct6100_save_nlp_conf_dword(f_pApiInstance, + pEchoChannel, + ulAddress, + ulTempData); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* The API must set the skip bit in all the events that are queued. */ + + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + if ( fCheckStop == TRUE ) + { + if ( ulReadPtr != ulWritePtr ) + { + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst; + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + ulEventBuffer = pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst; + } + + for ( ulCurrentPtr = ulReadPtr; ulCurrentPtr != ulWritePtr; ) + { + /* Set the playout event base address. */ + + /* 127 or 31 events image. */ + ulAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + ulEventBuffer + ( cOCT6100_PLAYOUT_EVENT_MEM_SIZE * ulCurrentPtr ); + ulCurrentPtr++; + ulCurrentPtr &= ( pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents - 1 ); + + /* EVENT BASE + 0 playout configuration. */ + WriteParams.ulWriteAddress = ulAddress; + + /* Set skip bit + hard-skip bit. */ + WriteParams.usWriteData = 0x8000; + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /*=======================================================================*/ + /* If stop immediatly, wait the stop before leaving the function. */ + + if ( f_pBufferPlayoutStop->fStopCleanly == FALSE ) + { + /* Remember that an "hard stop" was used for the next start. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + pEchoChannel->fRinHardStop = TRUE; + else /* if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT ) */ + pEchoChannel->fSoutHardStop = TRUE; + } + + /*=======================================================================*/ + /* Update the channel entry to set the playing flag to FALSE. */ + + /* Select the port of interest. */ + if ( f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the global ports active stat must be decremented. */ + if ( pEchoChannel->fRinBufPlaying == TRUE ) + { + /* Decrement the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + } + + pEchoChannel->fRinBufPlaying = FALSE; + + /* Return user information. */ + if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL ) + *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fRinBufPlayoutNotifyOnStop; + + /* Make sure no new event is recorded for this channel/port. */ + pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE; + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + pEchoChannel->ulRinBufSkipPtr = ulSkipPtr; + pEchoChannel->ulRinBufWritePtr = ulWritePtr; + } + else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */ + pEchoChannel->ulRinBufSkipPtr = pEchoChannel->ulRinBufWritePtr; + + /* The repeat flag can now be used. */ + pEchoChannel->fRinBufPlayoutRepeatUsed = FALSE; + + /* For sure, all buffers have now been cleared on the Rin port. */ + pEchoChannel->fRinBufAdded = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fSoutBufPlaying == FALSE ) + && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + else /* f_pBufferPlayoutStop->ulPlayoutPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the global ports active stat must be decremented. */ + if ( pEchoChannel->fSoutBufPlaying == TRUE ) + { + /* Decrement the number of active buffer playout ports. */ + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--; + } + + pEchoChannel->fSoutBufPlaying = FALSE; + + /* Return user information. */ + if ( f_pBufferPlayoutStop->pfNotifyOnPlayoutStop != NULL ) + *f_pBufferPlayoutStop->pfNotifyOnPlayoutStop = pEchoChannel->fSoutBufPlayoutNotifyOnStop; + + /* Make sure no new event is recorded for this channel/port. */ + pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE; + if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == TRUE ) + { + pEchoChannel->ulSoutBufSkipPtr = ulSkipPtr; + pEchoChannel->ulSoutBufWritePtr = ulWritePtr; + } + else /* if ( pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents == FALSE ) */ + pEchoChannel->ulSoutBufSkipPtr = pEchoChannel->ulSoutBufWritePtr; + + /* The repeat flag can now be used. */ + pEchoChannel->fSoutBufPlayoutRepeatUsed = FALSE; + + /* For sure, all buffers have now been cleared on the Sout port. */ + pEchoChannel->fSoutBufAdded = FALSE; + + /* Clear optimization flag if possible. */ + if ( ( pEchoChannel->fRinBufPlaying == FALSE ) + && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) ) + { + /* Buffer playout is no more active on this channel. */ + pEchoChannel->fBufPlayoutActive = FALSE; + } + } + + /*=======================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBufPlayoutListEntry + +Description: Reserves a free entry in the Buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pulBufferIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBufPlayoutListEntry +UINT32 Oct6100ApiReserveBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulBufferIndex ) +{ + PVOID pBufPlayoutAlloc; + UINT32 ulResult; + + mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc ) + + ulResult = OctapiLlmAllocAlloc( pBufPlayoutAlloc, f_pulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN; + else + return cOCT6100_ERR_FATAL_40; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBufPlayoutListEntry + +Description: Release an entry from the Buffer playout list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulBufferIndex List entry to be freed. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBufPlayoutListEntry +UINT32 Oct6100ApiReleaseBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferIndex ) +{ + PVOID pBufPlayoutAlloc; + UINT32 ulResult; + + mOCT6100_GET_BUFFER_ALLOC_PNT( f_pApiInstance->pSharedInfo, pBufPlayoutAlloc ) + + ulResult = OctapiLlmAllocDealloc( pBufPlayoutAlloc, f_ulBufferIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_41; + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c new file mode 100644 index 0000000..8afb2f9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c @@ -0,0 +1,1598 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the routines used for remote debugging. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 35 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_largmath.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_debug_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" + +#include "octrpc/rpc_protocol.h" +#include "octrpc/oct6100_rpc_protocol.h" + +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_chip_open_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_remote_debug_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100RemoteDebug + +Description: This function interprets the remote debugging packets received + by the user’s software. Commands contained in the packet are + executed by the API. In addition, a response packet is + constructed and returned by the function. It is the responsibility + of the user’s software to transmit the response packet back to + the source of the debugging packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pRemoteDebug Pointer to a remote debug structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100RemoteDebugDef +UINT32 Oct6100RemoteDebugDef( + tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ) +{ + f_pRemoteDebug->pulReceivedPktPayload = NULL; + f_pRemoteDebug->ulReceivedPktLength = 0; + f_pRemoteDebug->pulResponsePktPayload = NULL; + f_pRemoteDebug->ulMaxResponsePktLength = 0; + f_pRemoteDebug->ulResponsePktLength = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100RemoteDebug +UINT32 Oct6100RemoteDebug( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ) +{ + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + tPOCTRPC_INTERFACE_HEADER pInterfaceHeader; + tPOCTRPC_COMMAND_HEADER pRspCmndHeader; + PUINT32 pulRcvPktPayload; + PUINT32 pulRspPktPayload; + UINT32 ulPktLengthDword; + UINT32 ulSessionIndex; + UINT32 ulChecksum; + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pRemoteDebug->pulReceivedPktPayload == NULL ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_PAYLOAD; + if ( f_pRemoteDebug->pulResponsePktPayload == NULL ) + return cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_PAYLOAD; + if ( f_pRemoteDebug->ulReceivedPktLength < cOCTRPC_MIN_PACKET_BYTE_LENGTH ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pRemoteDebug->ulReceivedPktLength > cOCTRPC_MAX_PACKET_BYTE_LENGTH ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pRemoteDebug->ulMaxResponsePktLength < f_pRemoteDebug->ulReceivedPktLength ) + return cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_LENGTH; + if ( (f_pRemoteDebug->ulReceivedPktLength % 4) != 0 ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxRemoteDebugSessions == 0 ) + return cOCT6100_ERR_REMOTEDEBUG_DISABLED; + + /* Set response length as received length. */ + f_pRemoteDebug->ulResponsePktLength = f_pRemoteDebug->ulReceivedPktLength; + + /* Typecast the packet payload to local pointers. */ + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pRemoteDebug->pulReceivedPktPayload; + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pRemoteDebug->pulReceivedPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + /* Get local pointer to received and response packet payloads. */ + pulRcvPktPayload = f_pRemoteDebug->pulReceivedPktPayload; + pulRspPktPayload = f_pRemoteDebug->pulResponsePktPayload; + + /* Get the length of the packet in UINT32s. */ + ulPktLengthDword = f_pRemoteDebug->ulReceivedPktLength / 4; + + /* Check the endian detection field to determine if the payload must be */ + /* swapped to account for different endian formats. */ + ulResult = Oct6100ApiCheckEndianDetectField( pOgrdtpHeader, ulPktLengthDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check the packet's length. */ + if ( pOgrdtpHeader->ulPktByteSize != f_pRemoteDebug->ulReceivedPktLength ) + return cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH; + + /* Perform the sum of each word in the packet and compare to checksum. */ + Oct6100ApiCalculateChecksum( pulRcvPktPayload, ulPktLengthDword, &ulChecksum ); + if ( ulChecksum != pOgrdtpHeader->ulChecksum ) + return cOCT6100_ERR_REMOTEDEBUG_CHECKSUM; + + /* Check if the packet's session number has a corresponding entry in the API table. + If not then close an entry which has timed out, and allocate the entry to the + new session number. */ + ulResult = Oct6100ApiCheckSessionNum( f_pApiInstance, pOgrdtpHeader, &ulSessionIndex ); + if ( ulResult == cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, cOCT6100_INVALID_VALUE, cOCTRPC_RDBGERR_ALL_SESSIONS_OPEN, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( ulResult == cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, TRUE, FALSE, FALSE, FALSE, ulSessionIndex, cOCT6100_INVALID_VALUE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( ulResult != cOCT6100_ERR_OK ) + { + return ulResult; + } + + /* Check if an echo packet. If so then there's no need to check the rest of + the packet. Simply copy the packet back to the output buffer, enter the + protocol number supported by this API compilation, and recalculate the + checksum. If the packet is not an echo packet and the protocol version + does not correspond to this compiled version then return the supported + protocol version. */ + if ( pOgrdtpHeader->ulRpcProtocolNum == cOCTRPC_ECHO_PROTOCOL ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, TRUE, FALSE, FALSE, ulSessionIndex, cOCT6100_INVALID_VALUE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( pOgrdtpHeader->ulRpcProtocolNum != cOCTRPC_PROTOCOL_V1_1 ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, TRUE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_PROTOCOL_NUMBER, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + else if ( f_pRemoteDebug->ulReceivedPktLength <= cOCTRPC_FIRST_COMMAND_BYTE_OFFSET ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_NO_COMMAND_HEADER, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + + + /* Check the packet's RPC interface type and version. If either does not match then + return the packet with the supported interface type and version of this compilation. */ + if ( pInterfaceHeader->ulInterfaceVersion != cOCTRPC_INTERFACE_VERSION ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, TRUE, TRUE, ulSessionIndex, cOCTRPC_RDBGERR_INTERFACE_VERSION, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + if ( pInterfaceHeader->ulInterfaceType != cOCTRPC_OCT6100_INTERFACE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, TRUE, TRUE, ulSessionIndex, cOCTRPC_RDBGERR_INTERFACE_TYPE, cOCT6100_INVALID_VALUE, ulChecksum ); + return cOCT6100_ERR_OK; + } + + /* Check each command header to make sure the indicated command and length agree. If + there is an error in the packet's commands then the response packet will be + constructed by the function. */ + ulResult = Oct6100ApiCheckPktCommands( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulSessionIndex, ulPktLengthDword, ulChecksum ); + if ( ulResult == cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR ) + return cOCT6100_ERR_OK; + + /* The packet's fields are valid. Each command must now be extracted and executed. */ + Oct6100ApiExecutePktCommands( f_pApiInstance, pulRcvPktPayload, ulPktLengthDword ); + + pRspCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pulRspPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + + /* Verify if the new method of using the protocol is the selected case. */ + /* All commands have been executed. Calculate the packet's new checksum + and copy the packet to user provided buffer for response packet. */ + Oct6100ApiCalculateChecksum( pulRcvPktPayload, ulPktLengthDword, &ulChecksum ); + + /* Send response packet. */ + Oct6100ApiFormResponsePkt( f_pApiInstance, pulRcvPktPayload, pulRspPktPayload, ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, ulSessionIndex, cOCTRPC_RDBGERR_OK, cOCT6100_INVALID_VALUE, ulChecksum ); + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetRemoteDebugSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of remote debugging. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetRemoteDebugSwSizes +UINT32 Oct6100ApiGetRemoteDebugSwSizes( + IN tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Memory needed for remote debugging sessions. */ + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 0 ) + { + f_pInstSizes->ulRemoteDebugList = f_pChipOpen->ulMaxRemoteDebugSessions * sizeof( tOCT6100_API_REMOTE_DEBUG_SESSION ); + + ulResult = octapi_bt0_get_size( f_pChipOpen->ulMaxRemoteDebugSessions, 4, 4, &f_pInstSizes->ulRemoteDebugTree ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_41; + + f_pInstSizes->ulRemoteDebugPktCache = cOCTRPC_MAX_PACKET_BYTE_LENGTH * f_pChipOpen->ulMaxRemoteDebugSessions; + f_pInstSizes->ulRemoteDebugDataBuf = cOCTRPC_MAX_PACKET_BYTE_LENGTH * 4; + } + else + { + f_pInstSizes->ulRemoteDebugList = 0; + f_pInstSizes->ulRemoteDebugTree = 0; + f_pInstSizes->ulRemoteDebugPktCache = 0; + f_pInstSizes->ulRemoteDebugDataBuf = 0; + } + + /* Round off the size. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugTree, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugPktCache, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulRemoteDebugDataBuf, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRemoteDebuggingSwInit + +Description: Initializes all portions of the API instance associated to + remote debugging. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRemoteDebuggingSwInit +UINT32 Oct6100ApiRemoteDebuggingSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pSessionTree; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->RemoteDebugInfo.ulNumSessionsOpen = 0; + pSharedInfo->RemoteDebugInfo.ulMaxSessionsOpen = pSharedInfo->ChipConfig.usMaxRemoteDebugSessions; + pSharedInfo->RemoteDebugInfo.ulSessionListHead = cOCT6100_INVALID_VALUE; + pSharedInfo->RemoteDebugInfo.ulSessionListTail = cOCT6100_INVALID_VALUE; + + if ( pSharedInfo->ChipConfig.usMaxRemoteDebugSessions > 0 ) + { + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_init( ( ( PVOID* )&pSessionTree ), pSharedInfo->ChipConfig.usMaxRemoteDebugSessions, 4, 4 ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_42; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckEndianDetectField + +Description: Checks the endian field of a packet and performs a swap of + the packet data if deemed necessary. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulPktLengthDword Length of the packet in dwords. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckEndianDetectField +UINT32 Oct6100ApiCheckEndianDetectField( + IN OUT tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + IN UINT32 f_ulPktLengthDword ) +{ + PUINT32 pulPktPayload; + UINT32 ulBytePositionW = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionX = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionY = cOCT6100_INVALID_VALUE; + UINT32 ulBytePositionZ = cOCT6100_INVALID_VALUE; + UINT32 ulTempVar; + UINT32 i; + + /* Bytes in dword are labeled as Z Y X W. */ + + /* Only swap if necessary. */ + if ( f_pOgrdtpHeader->ulEndianDetect != cOCTRPC_ENDIAN_DETECT ) + { + /* Find the position of each byte. */ + for ( i = 0; i < 4; i++ ) + { + ulTempVar = (f_pOgrdtpHeader->ulEndianDetect >> (8 * i)) & 0xFF; + switch ( ulTempVar ) + { + case cOCTRPC_ENDIAN_DETECT_BYTE_W: + ulBytePositionW = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_X: + ulBytePositionX = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_Y: + ulBytePositionY = i * 8; + break; + case cOCTRPC_ENDIAN_DETECT_BYTE_Z: + ulBytePositionZ = i * 8; + break; + default: + return cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET; + } + } + + /* Make sure all bytes of the endian detect field were found. */ + if ( ulBytePositionW == cOCT6100_INVALID_VALUE || + ulBytePositionX == cOCT6100_INVALID_VALUE || + ulBytePositionY == cOCT6100_INVALID_VALUE || + ulBytePositionZ == cOCT6100_INVALID_VALUE ) + return cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET; + + /* Swap the bytes of each dword of the packet. */ + pulPktPayload = ( PUINT32 )f_pOgrdtpHeader; + for ( i = 0; i < f_ulPktLengthDword; i++ ) + { + ulTempVar = pulPktPayload[ i ]; + pulPktPayload[ i ] = ((ulTempVar >> ulBytePositionZ) & 0xFF) << 24; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionY) & 0xFF) << 16; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionX) & 0xFF) << 8; + pulPktPayload[ i ] |= ((ulTempVar >> ulBytePositionW) & 0xFF) << 0; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateChecksum + +Description: Calculates the checksum of the given packet payload. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pulPktPayload Pointer to the payload of the packet. +f_ulPktLengthDword Length of the packet in dwords. +f_pulChecksum Pointer to the checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCalculateChecksum +VOID Oct6100ApiCalculateChecksum( + IN PUINT32 f_pulPktPayload, + IN UINT32 f_ulPktLengthDword, + OUT PUINT32 f_pulChecksum ) +{ + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + UINT32 i; + + for ( i = 0, *f_pulChecksum = 0; i < f_ulPktLengthDword; i++ ) + { + *f_pulChecksum += (f_pulPktPayload[ i ] >> 16) & 0xFFFF; + *f_pulChecksum += (f_pulPktPayload[ i ] >> 0) & 0xFFFF; + } + + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pulPktPayload; + *f_pulChecksum -= (pOgrdtpHeader->ulChecksum >> 16) & 0xFFFF; + *f_pulChecksum -= (pOgrdtpHeader->ulChecksum >> 0) & 0xFFFF; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiFormResponsePkt + +Description: Modifies the values of the indicated receive packet, update + the checksum field, and copy the receive packet to the + response packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_pulRspPktPayload Pointer to the payload of the response packet. +f_ulPktLengthDword Length of the packet in dwords. +f_fRetryPktResponse Flag indicating if the received packet was a retry packet. +f_fReplaceProtocolNum Flag indicating if the protocol number must be replaced. +f_fReplaceInterfaceType Flag indicating if the interface type must be replaced. +f_fReplaceInterfaceVersion Flag indicating if the interface version must be replaced. +f_ulSessionIndex Index of the remote debug session within the API' session list. +f_ulParsingErrorValue Parsing error value. +f_ulPayloadDwordIndex Index in the packet where the payload starts. +f_ulChecksum Checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiFormResponsePkt +VOID Oct6100ApiFormResponsePkt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulPktLengthDword, + IN BOOL f_fRetryPktResponse, + IN BOOL f_fReplaceProtocolNum, + IN BOOL f_fReplaceInterfaceType, + IN BOOL f_fReplaceInterfaceVersion, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulParsingErrorValue, + IN UINT32 f_ulPayloadDwordIndex, + IN UINT32 f_ulChecksum ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCTRPC_OGRDTP_HEADER pOgrdtpHeader; + tPOCTRPC_INTERFACE_HEADER pInterfaceHeader; + PUINT32 pulPktCache; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Typecast pointer to OGRDTP packet header. */ + pOgrdtpHeader = ( tPOCTRPC_OGRDTP_HEADER )f_pulRcvPktPayload; + + /* Check if a response to a retry packet. */ + if ( f_fRetryPktResponse == TRUE ) + { + mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, f_ulSessionIndex ) + + Oct6100UserMemCopy( f_pulRspPktPayload, pulPktCache, f_ulPktLengthDword * 4 ); + return; + } + + /* Replace all packet header fields which must be changed. */ + if ( f_ulParsingErrorValue != cOCT6100_INVALID_VALUE ) + { + f_ulChecksum -= (pOgrdtpHeader->ulParsingError >> 16) & 0xFFFF; + f_ulChecksum -= (pOgrdtpHeader->ulParsingError >> 0) & 0xFFFF; + + pOgrdtpHeader->ulParsingError = f_ulParsingErrorValue; + + f_ulChecksum += (pOgrdtpHeader->ulParsingError >> 16) & 0xFFFF; + f_ulChecksum += (pOgrdtpHeader->ulParsingError >> 0) & 0xFFFF; + } + + if ( f_fReplaceProtocolNum == TRUE ) + { + f_ulChecksum -= (pOgrdtpHeader->ulRpcProtocolNum >> 16) & 0xFFFF; + f_ulChecksum -= (pOgrdtpHeader->ulRpcProtocolNum >> 0) & 0xFFFF; + + pOgrdtpHeader->ulRpcProtocolNum = cOCTRPC_PROTOCOL_V1_1; + + f_ulChecksum += (pOgrdtpHeader->ulRpcProtocolNum >> 16) & 0xFFFF; + f_ulChecksum += (pOgrdtpHeader->ulRpcProtocolNum >> 0) & 0xFFFF; + } + + if ( f_fReplaceInterfaceType == TRUE ) + { + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pulRcvPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + f_ulChecksum -= (pInterfaceHeader->ulInterfaceType >> 16) & 0xFFFF; + f_ulChecksum -= (pInterfaceHeader->ulInterfaceType >> 0) & 0xFFFF; + + pInterfaceHeader->ulInterfaceType = cOCTRPC_OCT6100_INTERFACE; + + f_ulChecksum += (pInterfaceHeader->ulInterfaceType >> 16) & 0xFFFF; + f_ulChecksum += (pInterfaceHeader->ulInterfaceType >> 0) & 0xFFFF; + } + + if ( f_fReplaceInterfaceVersion == TRUE ) + { + pInterfaceHeader = ( tPOCTRPC_INTERFACE_HEADER )(f_pulRcvPktPayload + (sizeof( tOCTRPC_OGRDTP_HEADER ) / 4)); + + f_ulChecksum -= (pInterfaceHeader->ulInterfaceVersion >> 16) & 0xFFFF; + f_ulChecksum -= (pInterfaceHeader->ulInterfaceVersion >> 0) & 0xFFFF; + + pInterfaceHeader->ulInterfaceVersion = cOCTRPC_INTERFACE_VERSION; + + f_ulChecksum += (pInterfaceHeader->ulInterfaceVersion >> 16) & 0xFFFF; + f_ulChecksum += (pInterfaceHeader->ulInterfaceVersion >> 0) & 0xFFFF; + } + + if ( f_ulPayloadDwordIndex != cOCT6100_INVALID_VALUE ) + { + f_pulRcvPktPayload += f_ulPayloadDwordIndex; + + f_ulChecksum -= (*f_pulRcvPktPayload >> 16) & 0xFFFF; + f_ulChecksum -= (*f_pulRcvPktPayload >> 0) & 0xFFFF; + + *f_pulRcvPktPayload = cOCTRPC_UNKNOWN_COMMAND_NUM; + + f_ulChecksum += (*f_pulRcvPktPayload >> 16) & 0xFFFF; + f_ulChecksum += (*f_pulRcvPktPayload >> 0) & 0xFFFF; + + f_pulRcvPktPayload -= f_ulPayloadDwordIndex; + } + + /* Replace checksum. */ + pOgrdtpHeader->ulChecksum = f_ulChecksum; + + /* Copy the modified receive packet payload to the response packet. */ + Oct6100UserMemCopy( f_pulRspPktPayload, f_pulRcvPktPayload, f_ulPktLengthDword * 4 ); + + /* Copy the response packet to the session's packet cache. */ + if ( f_ulSessionIndex != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, f_ulSessionIndex ) + + Oct6100UserMemCopy( pulPktCache, f_pulRspPktPayload, f_ulPktLengthDword * 4 ); + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckPktCommands + +Description: Checks the commands contained in the packet for errors in size. + Also checks for unknown commands. If an error is encountered + then the function will construct the response packet. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_pulRspPktPayload Pointer to the payload of the response packet. +f_ulPktLengthDword Length of the packet in dwords. +f_ulSessionIndex Index of the remote debug session within the API' session list. +f_ulChecksum Checksum of the packet. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckPktCommands +UINT32 Oct6100ApiCheckPktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulPktLengthDword, + IN UINT32 f_ulChecksum ) +{ + tPOCTRPC_COMMAND_HEADER pCmndHeader; + UINT32 ulNumDwordsLeft; + UINT32 ulNumDwordsNeeded = 0; + UINT32 ulRpcCmndSizeDword; + BOOL fCmndIdentified; + BOOL fCmndHeaderPresent; + + pCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(f_pulRcvPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + ulNumDwordsLeft = f_ulPktLengthDword - ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4); + ulRpcCmndSizeDword = sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + fCmndIdentified = TRUE; + + while ( ulNumDwordsLeft != 0 ) + { + if ( ulNumDwordsLeft < ulRpcCmndSizeDword ) + { + fCmndHeaderPresent = FALSE; + } + else + { + fCmndHeaderPresent = TRUE; + + switch ( pCmndHeader->ulRpcCommandNum ) + { + case cOCT6100_RPC_READ_WORD: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_READ_WORD ) / 4; + } + break; + case cOCT6100_RPC_READ_BURST: + { + tPOCT6100_RPC_READ_BURST pBurstHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_READ_BURST ) - sizeof( UINT32 )) / 4; + pBurstHeader = ( tPOCT6100_RPC_READ_BURST )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += (pBurstHeader->ulBurstLength + 1) / 2; + } + break; + case cOCT6100_RPC_WRITE_WORD: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_WORD ) / 4; + } + break; + case cOCT6100_RPC_WRITE_SMEAR: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_SMEAR ) / 4; + } + break; + case cOCT6100_RPC_WRITE_INC: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_WRITE_INC ) / 4; + } + break; + case cOCT6100_RPC_READ_ARRAY: + { + tPOCT6100_RPC_READ_ARRAY pArrayHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_READ_ARRAY ) - sizeof( UINT32 )) / 4; + pArrayHeader = ( tPOCT6100_RPC_READ_ARRAY )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += pArrayHeader->ulArrayLength; + ulNumDwordsNeeded += (pArrayHeader->ulArrayLength + 1) / 2; + } + break; + case cOCT6100_RPC_WRITE_BURST: + { + tPOCT6100_RPC_WRITE_BURST pBurstHeader; + + ulNumDwordsNeeded = (sizeof( tOCT6100_RPC_WRITE_BURST ) - sizeof( UINT32 )) / 4; + pBurstHeader = ( tPOCT6100_RPC_WRITE_BURST )(( PUINT32 )pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + ulNumDwordsNeeded += (pBurstHeader->ulBurstLength + 1) / 2; + } + break; + case cOCT6100_RPC_SET_HOT_CHANNEL: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_SET_HOT_CHANNEL ) / 4; + } + break; + case cOCT6100_RPC_GET_DEBUG_CHAN_INDEX: + { + ulNumDwordsNeeded = sizeof( tOCT6100_RPC_GET_DEBUG_CHAN_INDEX ) / 4; + } + break; + case cOCT6100_RPC_API_DISCONNECT: + { + /* There is no parameter to the disconnect command. */ + ulNumDwordsNeeded = 0; + } + break; + default: + fCmndIdentified = FALSE; + } + + ulNumDwordsNeeded += sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + } + + if ( fCmndHeaderPresent != TRUE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_PACKET_LENGTH, cOCT6100_INVALID_VALUE, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + if ( fCmndIdentified != TRUE ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_COMMAND_NUMBER, f_ulPktLengthDword - ulNumDwordsLeft, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + + if ( ulNumDwordsNeeded != (pCmndHeader->ulCommandByteSize / 4) || + ulNumDwordsNeeded > ulNumDwordsLeft ) + { + Oct6100ApiFormResponsePkt( f_pApiInstance, f_pulRcvPktPayload, f_pulRspPktPayload, f_ulPktLengthDword, FALSE, FALSE, FALSE, FALSE, f_ulSessionIndex, cOCTRPC_RDBGERR_INVALID_COMMAND_LENGTH, cOCT6100_INVALID_VALUE, f_ulChecksum ); + return cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR; + } + + pCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pCmndHeader + ulNumDwordsNeeded); + ulNumDwordsLeft -= ulNumDwordsNeeded; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExecutePktCommands + +Description: Executes the commands contained in the received packet. The + received packet payload buffer is modified but NOT copied to + the response packet buffer. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulRcvPktPayload Pointer to the payload of the received packet. +f_ulPktLengthDword Length of the packet in dwords. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExecutePktCommands +VOID Oct6100ApiExecutePktCommands( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN UINT32 f_ulPktLengthDword ) +{ + tPOCTRPC_COMMAND_HEADER pReqCmndHeader; + tPOCTRPC_OGRDTP_HEADER pReqPktHeader; + UINT32 ulNumDwordsLeft; + UINT32 ulRpcCmndSizeDword; + + pReqPktHeader = ( tPOCTRPC_OGRDTP_HEADER )(f_pulRcvPktPayload); + pReqCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )f_pulRcvPktPayload + ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4)); + ulNumDwordsLeft = f_ulPktLengthDword - ((sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) / 4); + ulRpcCmndSizeDword = sizeof( tOCTRPC_COMMAND_HEADER ) / 4; + + while ( ulNumDwordsLeft != 0 ) + { + /* Switch on command number. */ + switch ( pReqCmndHeader->ulRpcCommandNum ) + { + case cOCT6100_RPC_READ_WORD: + Oct6100ApiRpcReadWord( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_READ_BURST: + Oct6100ApiRpcReadBurst( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_READ_ARRAY: + Oct6100ApiRpcReadArray( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_WORD: + Oct6100ApiRpcWriteWord( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_SMEAR: + Oct6100ApiRpcWriteSmear( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_WRITE_BURST: + Oct6100ApiRpcWriteBurst( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_SET_HOT_CHANNEL: + Oct6100ApiRpcSetHotChannel( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_GET_DEBUG_CHAN_INDEX: + Oct6100ApiRpcGetDebugChanIndex( f_pApiInstance, pReqCmndHeader ); + break; + case cOCT6100_RPC_API_DISCONNECT: + Oct6100ApiRpcDisconnect( f_pApiInstance, pReqCmndHeader, pReqPktHeader->ulDebugSessionNum ); + break; + default: + pReqCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INVALID_RPC_COMMAND_NUM; + break; + } + + /* Insert the result of the operation in the command header. */ + if ( pReqCmndHeader->ulFunctionResult != cOCT6100_ERR_OK ) + break; + + /* Decrement the number of DWORDs left in the packet. */ + ulNumDwordsLeft -= pReqCmndHeader->ulCommandByteSize / 4; + + /* Point to the next command in the packet. */ + pReqCmndHeader = ( tPOCTRPC_COMMAND_HEADER )(( PUINT32 )pReqCmndHeader + (pReqCmndHeader->ulCommandByteSize / 4)); + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckSessionNum + +Description: Checks if there is a session list entry open for the session + number received. If not, a free one is reserved if one is + available. If none are free, one which has timed-out is + released. If none are timed out then an error is returned. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pOgrdtpHeader Pointer to the header of the packet. +f_pulSessionIndex Pointer to the remote debugging session within the + API's session list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckSessionNum +UINT32 Oct6100ApiCheckSessionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + OUT PUINT32 f_pulSessionIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_REMOTE_DEBUG_INFO pRemoteDebugInfo; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionEntry; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionLink; + tOCT6100_GET_TIME GetTime; + PVOID pSessionTree; + PUINT32 pulTreeData; + UINT32 ulNewSessionIndex; + UINT32 aulTimeDiff[ 2 ]; + UINT32 ulResult; + UINT16 usNegative; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context of GetTime. */ + GetTime.pProcessContext = f_pApiInstance->pProcessContext; + + /* Get the current system time. */ + ulResult = Oct6100UserGetTime( &GetTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get a local pointer to the remote debugging info. */ + pRemoteDebugInfo = &pSharedInfo->RemoteDebugInfo; + + /* Check if the session number has an associated session list entry. */ + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_query_node( pSessionTree, ( ( PVOID )(&f_pOgrdtpHeader->ulDebugSessionNum) ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Return session index. */ + *f_pulSessionIndex = *pulTreeData; + + /* A session list entry is associated, so update the entries last packet time, + transaction number and packet retry number, and position in the linked list. */ + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, *pulTreeData, pSessionEntry ) + + pSessionEntry->aulLastPktTime[ 0 ] = GetTime.aulWallTimeUs[ 0 ]; + pSessionEntry->aulLastPktTime[ 1 ] = GetTime.aulWallTimeUs[ 1 ]; + pSessionEntry->ulPktRetryNum = f_pOgrdtpHeader->ulPktRetryNum; + + /* Remove the node from its current place in the linked-list and add it to the end. */ + if ( pRemoteDebugInfo->ulSessionListTail != *pulTreeData ) + { + /* Obtain local pointer to the session list entry to be moved. */ + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, *pulTreeData, pSessionEntry ) + + /* Update link of previous session in list. */ + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = pSessionEntry->ulForwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + /* Update link of next session in list. */ + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionLink ) + pSessionLink->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Place session at the end of the list. */ + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + pRemoteDebugInfo->ulSessionListTail = *pulTreeData; + + if ( pRemoteDebugInfo->ulSessionListHead == cOCT6100_INVALID_VALUE ) + { + pRemoteDebugInfo->ulSessionListHead = *pulTreeData; + } + else + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = *pulTreeData; + } + } + + /* Check if packet should be interpreted based on transaction number. */ + if ( f_pOgrdtpHeader->ulPktRetryNum != 0 && + pSessionEntry->ulTransactionNum == f_pOgrdtpHeader->ulTransactionNum && + pSessionEntry->ulPktByteSize == f_pOgrdtpHeader->ulPktByteSize ) + return cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED; + + /* Update transaction number since packet will be interpreted. */ + pSessionEntry->ulTransactionNum = f_pOgrdtpHeader->ulTransactionNum; + pSessionEntry->ulPktByteSize = f_pOgrdtpHeader->ulPktByteSize; + + return cOCT6100_ERR_OK; + } + else if ( ulResult == OCTAPI_BT0_KEY_NOT_IN_TREE ) + { + /* If there is a free entry in the session list then seize it. Else, try to + find an entry which has timed out. If there are none then return an error. */ + if ( pRemoteDebugInfo->ulNumSessionsOpen < pRemoteDebugInfo->ulMaxSessionsOpen ) + { + ulNewSessionIndex = pRemoteDebugInfo->ulNumSessionsOpen; + } + else /* ( pRemoteDebugInfo->ulNumSessionsOpen == pRemoteDebugInfo->ulMaxSessionsOpen ) */ + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pRemoteDebugInfo->ulSessionListHead, pSessionEntry ) + + ulResult = octapi_lm_subtract( GetTime.aulWallTimeUs, 1, pSessionEntry->aulLastPktTime, 1, aulTimeDiff, 1, &usNegative ); + if ( ulResult != cOCT6100_ERR_OK || usNegative != FALSE ) + return cOCT6100_ERR_FATAL_43; + + /* If there are no session list entries available then return the packet with + a parsing error. */ + if ( aulTimeDiff[ 1 ] == 0 && aulTimeDiff[ 0 ] < (cOCTRPC_SESSION_TIMEOUT * 1000000) ) + return cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN; + + ulNewSessionIndex = pRemoteDebugInfo->ulSessionListHead; + + /* Remove old session index. */ + ulResult = octapi_bt0_remove_node( pSessionTree, ( ( PVOID )&pSessionEntry->ulSessionNum ) ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_44; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = pSessionEntry->ulForwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionLink ) + pSessionLink->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Decrement number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen--; + } + + /* Add new session. */ + ulResult = octapi_bt0_add_node( pSessionTree, ( ( PVOID )&f_pOgrdtpHeader->ulDebugSessionNum ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_45; + *pulTreeData = ulNewSessionIndex; + + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulNewSessionIndex, pSessionEntry ) + + pSessionEntry->aulLastPktTime[ 0 ] = GetTime.aulWallTimeUs[ 0 ]; + pSessionEntry->aulLastPktTime[ 1 ] = GetTime.aulWallTimeUs[ 1 ]; + pSessionEntry->ulSessionNum = f_pOgrdtpHeader->ulDebugSessionNum; + pSessionEntry->ulTransactionNum = f_pOgrdtpHeader->ulTransactionNum; + pSessionEntry->ulPktRetryNum = f_pOgrdtpHeader->ulPktRetryNum; + + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + pRemoteDebugInfo->ulSessionListTail = ulNewSessionIndex; + if ( pRemoteDebugInfo->ulSessionListHead == cOCT6100_INVALID_VALUE ) + pRemoteDebugInfo->ulSessionListHead = ulNewSessionIndex; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionLink ) + pSessionLink->ulForwardLink = ulNewSessionIndex; + } + + *f_pulSessionIndex = ulNewSessionIndex; + + /* Increment number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen++; + + return cOCT6100_ERR_OK; + } + else + { + return cOCT6100_ERR_FATAL_46; + } +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadWord + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_WORD command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadWord +VOID Oct6100ApiRpcReadWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_WORD pReadCommand; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get pointer to command arguments. */ + pReadCommand = ( tPOCT6100_RPC_READ_WORD )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + ReadParams.ulReadAddress = pReadCommand->ulAddress; + + /* Supply memory for read data. */ + ReadParams.pusReadData = &usReadData; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + + usReadData &= 0xFFFF; + + /* Return read data and result. */ + pReadCommand->ulReadData = (usReadData << 16) | usReadData; + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadBurst + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_BURST command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadBurst +VOID Oct6100ApiRpcReadBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_BURST pBurstCommand; + tOCT6100_READ_BURST_PARAMS BurstParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + UINT32 i; + PUINT16 pusReadData; + UINT32 ulNumWordsToRead; + + /* Get local pointer to remote debugging read data buffer. */ + mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( f_pApiInstance->pSharedInfo, pusReadData ) + + /* Get pointer to command arguments. */ + pBurstCommand = ( tPOCT6100_RPC_READ_BURST )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + BurstParams.ulReadAddress = pBurstCommand->ulAddress; + + + /* Supply memory for read data. */ + BurstParams.pusReadData = pusReadData; + + ulNumWordsToRead = pBurstCommand->ulBurstLength; + while( ulNumWordsToRead > 0) + { + if ( ulNumWordsToRead <= f_pApiInstance->pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulReadLength = ulNumWordsToRead; + else + BurstParams.ulReadLength = f_pApiInstance->pSharedInfo->ChipConfig.usMaxRwAccesses; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + { + f_pCmndHeader->ulFunctionResult = ulResult; + return; + } + + BurstParams.ulReadAddress += BurstParams.ulReadLength * 2; + BurstParams.pusReadData += BurstParams.ulReadLength; + + /* Update the number of dword to read. */ + ulNumWordsToRead -= BurstParams.ulReadLength; + } + + /* Return read data. */ + ulTempVar = (pBurstCommand->ulBurstLength + 1) / 2; + for ( i = 0; i < ulTempVar; i++ ) + { + pBurstCommand->aulReadData[ i ] = (*pusReadData & 0xFFFF) << 16; + pusReadData++; + pBurstCommand->aulReadData[ i ] |= (*pusReadData & 0xFFFF) << 0; + pusReadData++; + } + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcReadArray + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_READ_ARRAY command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcReadArray +VOID Oct6100ApiRpcReadArray( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_READ_ARRAY pArrayCommand; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 i; + PUINT32 pulAddressArray; + PUINT32 pulDataArray; + UINT16 usReadData; + + + /* Get pointer to command arguments. */ + pArrayCommand = ( tPOCT6100_RPC_READ_ARRAY )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Supply memory for read data. */ + ReadParams.pusReadData = &usReadData; + + /* Get pointers to array of addresses and data. */ + pulAddressArray = pArrayCommand->aulArrayData; + pulDataArray = pArrayCommand->aulArrayData + pArrayCommand->ulArrayLength; + + for ( i = 0; i < pArrayCommand->ulArrayLength; i++ ) + { + /* Copy parameters from packet payload to local read structure. */ + ReadParams.ulReadAddress = pulAddressArray[ i ]; + + /* Perform read access. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + break; + + /* Return read data. */ + if ( (i % 2) == 0 ) + pulDataArray[ i / 2 ] = (usReadData & 0xFFFF) << 16; + else /* ( (i % 2) == 1 ) */ + pulDataArray[ i / 2 ] |= (usReadData & 0xFFFF) << 0; + } + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteWord + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_WORD command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteWord +VOID Oct6100ApiRpcWriteWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_WORD pWriteCommand; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get pointer to command arguments. */ + pWriteCommand = ( tPOCT6100_RPC_WRITE_WORD )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set some read structure parameters. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + WriteParams.ulWriteAddress = pWriteCommand->ulAddress; + WriteParams.usWriteData = (UINT16)pWriteCommand->ulWriteData; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteSmear + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_SMEAR command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteSmear +VOID Oct6100ApiRpcWriteSmear( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_SMEAR pSmearCommand; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + + /* Get pointer to command arguments. */ + pSmearCommand = ( tPOCT6100_RPC_WRITE_SMEAR )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set the smear structure parameters. */ + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + SmearParams.ulWriteAddress = pSmearCommand->ulAddress; + SmearParams.usWriteData = (UINT16)pSmearCommand->ulWriteData; + SmearParams.ulWriteLength = pSmearCommand->ulSmearLength; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcWriteBurst + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_WRITE_BURST command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcWriteBurst +VOID Oct6100ApiRpcWriteBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_WRITE_BURST pBurstCommand; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT32 ulResult; + UINT32 ulTempVar; + UINT32 i, j; + PUINT16 pusWriteData; + + /* Get local pointer to remote debugging write data buffer. */ + mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( f_pApiInstance->pSharedInfo, pusWriteData ) + + /* Get pointer to command arguments. */ + pBurstCommand = ( tPOCT6100_RPC_WRITE_BURST )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + ulTempVar = (pBurstCommand->ulBurstLength + 1) / 2; + for ( i = 0, j = 0; i < ulTempVar; i++ ) + { + pusWriteData[ j++ ] = (UINT16)((pBurstCommand->aulWriteData[ i ] >> 16) & 0xFFFF); + pusWriteData[ j++ ] = (UINT16)((pBurstCommand->aulWriteData[ i ] >> 0) & 0xFFFF); + } + + /* Set some structure parameters. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Copy parameters from packet payload to local read structure. */ + BurstParams.ulWriteAddress = pBurstCommand->ulAddress; + BurstParams.ulWriteLength = pBurstCommand->ulBurstLength; + BurstParams.pusWriteData = pusWriteData; + + /* Perform write access. */ + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcSetHotChannel + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_SET_HOT_CHANNEL command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcSetHotChannel +VOID Oct6100ApiRpcSetHotChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_SET_HOT_CHANNEL pHotChanCommand; + tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + + pHotChanCommand = ( tPOCT6100_RPC_SET_HOT_CHANNEL )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Verify if the hot channel index is valid. */ + if ( pHotChanCommand->ulHotChannel >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + { + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INVALID_HOT_CHAN_INDEX; + return; + } + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, pHotChanCommand->ulHotChannel ); + + DebugSelectChannel.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pHotChanCommand->ulHotChannel; + + /* The PCM law parameter is now obsolete. */ + /* The instance knows the law of the channel being recorded! */ + + /* Call the function. */ + ulResult = Oct6100DebugSelectChannelSer( f_pApiInstance, &DebugSelectChannel, FALSE ); + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcGetDebugChanIndex + +Description: Checks the provided portion of an OCTRPC packet and interprets + it as an cOCT6100_RPC_GET_DEBUG_CHAN_INDEX command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcGetDebugChanIndex +VOID Oct6100ApiRpcGetDebugChanIndex( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ) +{ + tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX pDebugChanCommand; + + pDebugChanCommand = ( tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX )(( PUINT32 )f_pCmndHeader + (sizeof( tOCTRPC_COMMAND_HEADER ) / 4)); + + /* Set the debug channel index of the structure. */ + pDebugChanCommand->ulDebugChanIndex = f_pApiInstance->pSharedInfo->DebugInfo.usRecordMemIndex; + + /* Return result. */ + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRpcDisconnect + +Description: Destroy the current session. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCmndHeader Pointer to RPC command structure. +f_ulSessionNumber Session number of the current remote debugging session. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRpcDisconnect +VOID Oct6100ApiRpcDisconnect( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader, + IN UINT32 f_ulSessionNumber ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_REMOTE_DEBUG_INFO pRemoteDebugInfo; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionEntry; + tPOCT6100_API_REMOTE_DEBUG_SESSION pSessionTempEntry; + PVOID pSessionTree; + UINT32 ulResult; + PUINT32 pulTreeData; + UINT32 ulSessionIndex; + + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_OK; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get a local pointer to the remote debugging info. */ + pRemoteDebugInfo = &pSharedInfo->RemoteDebugInfo; + + /* Check if the session number has an associated session list entry. */ + mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pSessionTree ) + + ulResult = octapi_bt0_query_node( pSessionTree, ( ( PVOID )(&f_ulSessionNumber) ), ( ( PVOID* )&pulTreeData ) ); + if ( ulResult != cOCT6100_ERR_OK ) + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_REMOTEDEBUG_INAVLID_SESSION_NUMBER; + + /* Return session index. */ + ulSessionIndex= *pulTreeData; + + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulSessionIndex, pSessionEntry ); + + /* Clear the entry of the session. */ + pSessionEntry->aulLastPktTime[ 0 ] = 0; + pSessionEntry->aulLastPktTime[ 1 ] = 0; + pSessionEntry->ulSessionNum = cOCT6100_INVALID_VALUE; + pSessionEntry->ulTransactionNum = cOCT6100_INVALID_VALUE; + pSessionEntry->ulPktRetryNum = cOCT6100_INVALID_VALUE; + + /* Update the other entry before removing the node. */ + pSessionEntry->ulBackwardLink = pRemoteDebugInfo->ulSessionListTail; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + if ( pSessionEntry->ulBackwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulBackwardLink, pSessionTempEntry ); + pSessionTempEntry->ulForwardLink = pSessionEntry->ulForwardLink; + } + else /* pSessionEntry->ulBackwardLink == cOCT6100_INVALID_VALUE */ + { + pRemoteDebugInfo->ulSessionListHead = pSessionEntry->ulForwardLink; + } + + if ( pSessionEntry->ulForwardLink != cOCT6100_INVALID_VALUE ) + { + mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, pSessionEntry->ulForwardLink, pSessionTempEntry ); + pSessionTempEntry->ulBackwardLink = pSessionEntry->ulBackwardLink; + } + else /* pSessionEntry->ulForwardLink == cOCT6100_INVALID_VALUE */ + { + pRemoteDebugInfo->ulSessionListTail = pSessionEntry->ulBackwardLink; + } + + /* Invalidate the pointer. */ + pSessionEntry->ulBackwardLink = cOCT6100_INVALID_VALUE; + pSessionEntry->ulForwardLink = cOCT6100_INVALID_VALUE; + + /* Remove the session. */ + ulResult = octapi_bt0_remove_node( pSessionTree, ( ( PVOID )&f_ulSessionNumber ) ); + if ( ulResult != cOCT6100_ERR_OK ) + f_pCmndHeader->ulFunctionResult = cOCT6100_ERR_FATAL_47; + + /* Increment number of open sessions. */ + pRemoteDebugInfo->ulNumSessionsOpen--; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c new file mode 100644 index 0000000..ab2dd70 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c @@ -0,0 +1,2056 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to read information allowing the + API to know where all the features supported by this API version are + located in the chip's external memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 113 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_tlv_priv.h" + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProcessTlvRegion + +Description: This function will read and interpret the TLV memory of the chip + to obtain memory offsets and features available of the image + loaded into the chip. + + The API will read this region until it finds a TLV type of 0 with + a length of 0. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProcessTlvRegion +UINT32 Oct6100ApiProcessTlvRegion( + tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulResult; + + UINT32 ulTlvTypeField; + UINT32 ulTlvLengthField; + UINT32 ulTlvWritingTimeoutCount = 0; + UINT32 ulConditionFlag = TRUE; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Set the address of the first TLV type. */ + ReadParams.ulReadAddress = cOCT6100_TLV_BASE; + ReadParams.ulReadAddress += 2; + + /* Wait for the TLV configuration to be configured in memory. */ + while ( ulConditionFlag ) + { + /* Read the TLV write done flag. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData & 0x1 ) + break; + + ulTlvWritingTimeoutCount++; + if ( ulTlvWritingTimeoutCount == 0x100000 ) + return cOCT6100_ERR_TLV_TIMEOUT; + } + + /*======================================================================*/ + /* Read the first 16 bits of the TLV type. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now, read the TLV field length. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField = usReadData << 16; + + /* Read the last word of the TLV length. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField |= usReadData; + + /* Modify the address to point at the TLV value field. */ + ReadParams.ulReadAddress += 2; + + /*======================================================================*/ + + /* Read the TLV value until the end of TLV region is reached. */ + while( !((ulTlvTypeField == 0) && (ulTlvLengthField == 0)) ) + { + ulResult = Oct6100ApiInterpretTlvEntry( f_pApiInstance, + ulTlvTypeField, + ulTlvLengthField, + ReadParams.ulReadAddress ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the address to after the TLV value. */ + ReadParams.ulReadAddress += ulTlvLengthField; + + /*======================================================================*/ + /* Read the first 16 bits of the TLV type. */ + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvTypeField |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now, read the TLV field length. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField = usReadData << 16; + + /* Read the last word of the TLV length. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulTlvLengthField |= usReadData; + + ReadParams.ulReadAddress += 2; + + /*======================================================================*/ + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInterpretTlvEntry + +Description: This function will interpret a TLV entry from the chip. All + known TLV types by the API are exhaustively listed here. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulTlvFieldType Type of the TLV field to interpret. +f_ulTlvFieldLength Byte length of the TLV field. +f_ulTlvValueAddress Address where the data of the TLV block starts. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInterpretTlvEntry +UINT32 Oct6100ApiInterpretTlvEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTlvFieldType, + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulTlvValueAddress ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 usReadData; + UINT32 i; + UINT32 ulTempValue = 0; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Find out how to interpret the TLV value according to the TLV type. */ + switch( f_ulTlvFieldType ) + { + case cOCT6100_TLV_TYPE_VERSION_NUMBER: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VERSION_NUMBER, + cOCT6100_TLV_MAX_LENGTH_VERSION_NUMBER ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ReadParams.ulReadAddress = f_ulTlvValueAddress; + + for( i = 0; i < (f_ulTlvFieldLength/2); i++ ) + { + /* Perform the actual read. */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->ImageInfo.szVersionNumber[ (i * 2) ] = (UINT8)((usReadData >> 8) & 0xFF); + f_pApiInstance->pSharedInfo->ImageInfo.szVersionNumber[ (i * 2) + 1 ] = (UINT8)((usReadData >> 0) & 0xFF); + + /* Modify the address. */ + ReadParams.ulReadAddress += 2; + } + } + break; + + case cOCT6100_TLV_TYPE_CUSTOMER_PROJECT_ID: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CUSTOMER_PROJECT_ID, + cOCT6100_TLV_MAX_LENGTH_CUSTOMER_PROJECT_ID ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Perform the actual read. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->ImageInfo.ulBuildId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH0_MAIN_BASE_ADDRESS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH0_MAIN_BASE_ADDRESS, + cOCT6100_TLV_MAX_LENGTH_CH0_MAIN_BASE_ADDRESS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase &= 0x0FFFFFFF; + + /* Modify the base address to incorporate the external memory offset. */ + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase += cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_IO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_IO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_IO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_ZCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_ZCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_XCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_XCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSinCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_YCB_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_MAIN_YCB_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_SIZE, + cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutCBMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_FREE_MEM_BASE_ADDRESS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_FREE_MEM_BASE_ADDRESS, + cOCT6100_TLV_MAX_LENGTH_FREE_MEM_BASE_ADDRESS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress &= 0x0FFFFFFF; + + } + break; + + case cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_CH_ROOT_CONF_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CH_ROOT_CONF_OFFSET, + cOCT6100_TLV_MAX_LENGTH_CH_ROOT_CONF_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemOfst ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_SIZE, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainRinPlayoutMemSize ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_OFFSET: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_OFFSET, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_SIZE, + cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainSoutPlayoutMemSize ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZWP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZWP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZWP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZIS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZIS, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZIS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinIgnoreSkipCleanOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_ZSP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZSP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZSP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinSkipPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YWP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YWP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YWP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YIS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YIS, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YIS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutIgnoreSkipCleanOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RW_YSP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YSP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YSP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutSkipPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RO_ZRP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_ZRP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_ZRP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_POA_BOFF_RO_YRP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_YRP, + cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_YRP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst ); + } + break; + + case cOCT6100_TLV_TYPE_CNR_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNR_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNR_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_ANR_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ANR_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_HZ_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HZ_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_HZ_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fRinDcOffsetRemoval = TRUE; + break; + + case cOCT6100_TLV_TYPE_HX_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HX_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_HX_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fSinDcOffsetRemoval = TRUE; + break; + + case cOCT6100_TLV_TYPE_LCA_Z_CONF_BOFF_RW_GAIN: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN, + cOCT6100_TLV_MAX_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinLevelControlOfst ); + } + break; + + case cOCT6100_TLV_TYPE_LCA_Y_CONF_BOFF_RW_GAIN: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN, + cOCT6100_TLV_MAX_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutLevelControlOfst ); + } + break; + + case cOCT6100_TLV_TYPE_CNA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ComfortNoiseModeOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fComfortNoise = TRUE; + break; + + case cOCT6100_TLV_TYPE_NOA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NOA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_NOA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpControlFieldOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fNlpControl = TRUE; + break; + + case cOCT6100_TLV_TYPE_VFA_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VFA_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_VFA_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.VadControlFieldOfst ); + } + /* Set flag indicating that the feature is present.*/ + f_pApiInstance->pSharedInfo->ImageInfo.fSilenceSuppression = TRUE; + break; + + case cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_TAIL_DISP: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP, + cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchTailDisplOfst ); + } + break; + + case cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_INST: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST, + cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchBootInstructionOfst ); + } + break; + + case cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_RESULT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT, + cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchBootResultOfst ); + } + break; + + case cOCT6100_TLV_TYPE_TDM_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TDM_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TDM_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneDisablerControlOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fToneDisabler = TRUE; + break; + + case cOCT6100_TLV_TYPE_DIS_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DIS_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_DIS_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.TailDisplEnableOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fTailDisplacement = TRUE; + break; + + case cOCT6100_TLV_TYPE_NT_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NT_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_NT_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpTrivialFieldOfst ); + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_INDEX_VALUE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_INDEX_VALUE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_INDEX_VALUE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + f_pApiInstance->pSharedInfo->DebugInfo.usRecordMemIndex = (UINT16)( ulTempValue & 0xFFFF ); + + break; + + case cOCT6100_TLV_TYPE_ADPCM_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ADPCM_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ADPCM_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + if ( ulTempValue == 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm = FALSE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm = TRUE; + + break; + + case cOCT6100_TLV_TYPE_CONFERENCING_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CONFERENCING_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CONFERENCING_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + if ( ulTempValue == 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fConferencing = FALSE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fConferencing = TRUE; + + break; + + case cOCT6100_TLV_TYPE_TONE_DETECTOR_PROFILE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE, + cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->ImageInfo.ulToneProfileNumber ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_TAIL_DISPLACEMENT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_DISPLACEMENT, + cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_DISPLACEMENT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulTailDispTempValue; + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTailDispTempValue ); + + ulTailDispTempValue += 1; /* Convert the value into milliseconds.*/ + ulTailDispTempValue *= 16; /* value was given in multiple of 16 ms. */ + + if ( ulTailDispTempValue >= 128 ) + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailDisplacement = (UINT16)( ulTailDispTempValue - 128 ); + else + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + + } + + break; + + case cOCT6100_TLV_TYPE_AEC_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_AEC_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fAecEnabled = TRUE; + + /* Acoustic echo cancellation available! */ + f_pApiInstance->pSharedInfo->ImageInfo.fAcousticEcho = TRUE; + + break; + + case cOCT6100_TLV_TYPE_PCM_LEAK_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_PCM_LEAK_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_PCM_LEAK_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PcmLeakFieldOfst ); + } + + f_pApiInstance->pSharedInfo->ImageInfo.fNonLinearityBehaviorA = TRUE; + break; + + case cOCT6100_TLV_TYPE_DEFAULT_ERL_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEFAULT_ERL_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_DEFAULT_ERL_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DefaultErlFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fDefaultErl = TRUE; + + break; + + case cOCT6100_TLV_TYPE_TONE_REM_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneRemovalFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fToneRemoval = TRUE; + + break; + + + + case cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT, + cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fMaxEchoPoint = TRUE; + + break; + + case cOCT6100_TLV_TYPE_NLP_CONV_CAP_CONF_BOFF_RW: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.NlpConvCapFieldOfst ); + } + + /* Set the flag. */ + f_pApiInstance->pSharedInfo->ImageInfo.fNonLinearityBehaviorB = TRUE; + + break; + + case cOCT6100_TLV_TYPE_MATRIX_EVENT_SIZE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_EVENT_SIZE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_EVENT_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugEventSize ); + } + + break; + + case cOCT6100_TLV_TYPE_CNR_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CNR_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_CNR_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fConferencingNoiseReduction = (UINT8)( ulTempValue & 0xFF ); + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fConferencingNoiseReduction == TRUE ) + { + /* Set flag indicating that the dominant speaker feature is present. */ + f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled = TRUE; + } + } + + break; + + case cOCT6100_TLV_TYPE_MAX_TAIL_LENGTH_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength = (UINT16)( ulTempValue & 0xFFFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_NUMBER_OF_CHANNELS: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_NUMBER_OF_CHANNELS, + cOCT6100_TLV_MAX_LENGTH_MAX_NUMBER_OF_CHANNELS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels = (UINT16)( ulTempValue & 0xFFFF ); + } + + break; + + case cOCT6100_TLV_TYPE_PLAYOUT_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_PLAYOUT_ENABLE, + cOCT6100_TLV_MAX_LENGTH_PLAYOUT_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Set flag indicating that the feature is present. */ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayout = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_DOMINANT_SPEAKER_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DominantSpeakerFieldOfst ); + } + + break; + + case cOCT6100_TLV_TYPE_TAIL_DISP_CONF_BOFF_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fPerChannelTailDisplacement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ANR_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ANR_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MUSIC_PROTECTION_RW_ENABLE: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fMusicProtection = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_AEC_DEFAULT_ERL_BOFF: + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecDefaultErlFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAecDefaultErl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_ALC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinAutoLevelControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_ALC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutAutoLevelControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_HLC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinHighLevelCompensation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_HLC_TARGET_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutHighLevelCompensation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ALC_HLC_STATUS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE, + cOCT6100_TLV_MAX_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AlcHlcStatusOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAlcHlcStatus = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Z_PLAYOUT_HARD_SKIP_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutRinHardSkipOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_Y_PLAYOUT_HARD_SKIP_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PlayoutSoutHardSkipOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AFT_FIELD_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AFT_FIELD_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_AFT_FIELD_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AftControlOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAftControl = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_VOICE_DETECTED_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_VOICE_DETECTED_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_VOICE_DETECTED_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSinVoiceDetectedStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_GAIN_APPLIED_RIN_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_GAIN_APPLIED_SOUT_STAT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MAX_ADAPT_ALE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_ADAPT_ALE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_MAX_ADAPT_ALE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AdaptiveAleOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fListenerEnhancement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_RIN_ANR_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_ANR_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_ANR_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAnrOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRoutNoiseReduction = TRUE; + } + + break; + case cOCT6100_TLV_TYPE_RIN_ANR_VALUE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_ANR_VALUE_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_ANR_VALUE_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinAnrValOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRoutNoiseReductionLevel = TRUE; + } + + break; + case cOCT6100_TLV_TYPE_RIN_MUTE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RIN_MUTE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_RIN_MUTE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinMuteOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinMute = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_SIN_MUTE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_SIN_MUTE_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_SIN_MUTE_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SinMuteOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSinMute = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_NUMBER_PLAYOUT_EVENTS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NUMBER_PLAYOUT_EVENTS, + cOCT6100_TLV_MAX_LENGTH_NUMBER_PLAYOUT_EVENTS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_ANR_SNR_IMPROVEMENT_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AnrSnrEnhancementOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAnrSnrEnhancement = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ANR_AGRESSIVITY_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ANR_AGRESSIVITY_BOFF_RW, + cOCT6100_TLV_MAX_LENGTH_ANR_AGRESSIVITY_BOFF_RW ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_CHAN_TAIL_LENGTH_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_TAIL_LENGTH_BOFF, + cOCT6100_TLV_MAX_LENGTH_CHAN_TAIL_LENGTH_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fPerChannelTailLength = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_CHAN_VQE_TONE_DISABLING_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_CHAN_VQE_TONE_DIS_BOFF, + cOCT6100_TLV_MAX_LENGTH_CHAN_VQE_TONE_DIS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AF_TAIL_DISP_VALUE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_TAIL_DISP_VALUE_BOFF, + cOCT6100_TLV_MAX_LENGTH_AF_TAIL_DISP_VALUE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAfTailDisplacement = TRUE; + } + + break; + + + case cOCT6100_TLV_TYPE_POUCH_COUNTER_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_POUCH_COUNTER_BOFF, + cOCT6100_TLV_MAX_LENGTH_POUCH_COUNTER_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.PouchCounterFieldOfst ); + + f_pApiInstance->pSharedInfo->DebugInfo.fPouchCounter = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_AEC_TAIL_LENGTH_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AEC_TAIL_BOFF, + cOCT6100_TLV_MAX_LENGTH_AEC_TAIL_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.AecTailLengthFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fAecTailLength = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress ); + + /* Mask the upper bits set by the firmware. */ + f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress &= 0x0FFFFFFF; + + /* Modify the base address to incorporate the external memory offset. */ + f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixBaseAddress += cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_STATS_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_DEBUG_CHAN_LITE_STATS_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_HOT_CHANNEL_SELECT_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_TIMESTAMP_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_TIMESTAMP_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_TIMESTAMP_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_MATRIX_WP_DWORD_BASE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MATRIX_WP_DWORD_BASE, + cOCT6100_TLV_MAX_LENGTH_MATRIX_WP_DWORD_BASE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulMatrixWpBaseAddress ); + } + + break; + + case cOCT6100_TLV_TYPE_AF_WRITE_PTR_BYTE_OFFSET: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_WRITE_PTR_BYTE_OFFSET, + cOCT6100_TLV_MAX_LENGTH_AF_WRITE_PTR_BYTE_OFFSET ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulAfWritePtrByteOffset ); + } + + break; + + case cOCT6100_TLV_TYPE_RECORDED_PCM_EVENT_BYTE_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_IS_ISR_CALLED_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IS_ISR_CALLED_BOFF, + cOCT6100_TLV_MAX_LENGTH_IS_ISR_CALLED_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.IsIsrCalledFieldOfst ); + + f_pApiInstance->pSharedInfo->DebugInfo.fIsIsrCalledField = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_MUSIC_PROTECTION_ENABLE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF, + cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.MusicProtectionFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fMusicProtectionConfiguration = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_ENABLE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION, + cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fIdleCodeDetection = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION_BOFF, + cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_IMAGE_TYPE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_IMAGE_TYPE, + cOCT6100_TLV_MAX_LENGTH_IMAGE_TYPE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + /* Check if read image type value is what's expected. */ + if ( ( ulTempValue != cOCT6100_IMAGE_TYPE_WIRELINE ) + && ( ulTempValue != cOCT6100_IMAGE_TYPE_COMBINED ) ) + return cOCT6100_ERR_FATAL_E9; + + f_pApiInstance->pSharedInfo->ImageInfo.byImageType = (UINT8)( ulTempValue & 0xFF ); + } + + break; + + case cOCT6100_TLV_TYPE_MAX_WIRELINE_CHANNELS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_MAX_WIRELINE_CHANNELS, + cOCT6100_TLV_MAX_LENGTH_MAX_WIRELINE_CHANNELS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + } + + break; + + case cOCT6100_TLV_TYPE_AF_EVENT_CB_SIZE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_AF_EVENT_CB_BYTE_SIZE, + cOCT6100_TLV_MAX_LENGTH_AF_EVENT_CB_BYTE_SIZE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->DebugInfo.ulAfEventCbByteSize ); + } + + break; + + case cOCT6100_TLV_TYPE_BUFFER_PLAYOUT_SKIP_IN_EVENTS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS, + cOCT6100_TLV_MAX_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + f_pApiInstance->pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_ZZ_ENERGY_CHAN_STATS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF, + cOCT6100_TLV_MAX_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fRinEnergyStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_YY_ENERGY_CHAN_STATS_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_YY_ENERGY_CHAN_STATS_BOFF, + cOCT6100_TLV_MAX_LENGTH_YY_ENERGY_CHAN_STATS_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fSoutEnergyStat = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE, + cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehavior = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + + } + + break; + + case cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE_BOFF: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF, + cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiTlvReadBitOffsetStruct( f_pApiInstance, + f_ulTlvValueAddress, + &f_pApiInstance->pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst ); + + f_pApiInstance->pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = TRUE; + } + + break; + + case cOCT6100_TLV_TYPE_SOUT_NOISE_BLEACHING: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_SOUT_NOISE_BLEACHING, + cOCT6100_TLV_MAX_LENGTH_SOUT_NOISE_BLEACHING ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fSoutNoiseBleaching = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + + } + + break; + + case cOCT6100_TLV_TYPE_NLP_STATISTICS: + + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_NLP_STATISTICS, + cOCT6100_TLV_MAX_LENGTH_NLP_STATISTICS ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulTlvValueAddress, + &ulTempValue ); + + if ( ulTempValue != 0 ) + f_pApiInstance->pSharedInfo->ImageInfo.fSinLevel = TRUE; + else + f_pApiInstance->pSharedInfo->ImageInfo.fSinLevel = FALSE; + + } + + break; + + default: + /* Unknown TLV type field... check default length and nothing else. */ + ulResult = Oct6100ApiTlvCheckLengthField( f_ulTlvFieldLength, + cOCT6100_TLV_MIN_LENGTH_DEFAULT, + cOCT6100_TLV_MAX_LENGTH_DEFAULT ); + break; + } + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTlvCheckLengthField + +Description: This function validates the TLV length field. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulTlvFieldLength Length field read from the TLV. +f_ulMinLengthValue Minimum value supported for the TLV. +f_ulMaxLengthValue Maximum value supported for the TLV. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTlvCheckLengthField +UINT32 Oct6100ApiTlvCheckLengthField( + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulMinLengthValue, + IN UINT32 f_ulMaxLengthValue ) +{ + /* Check if the value is too small. */ + if ( f_ulTlvFieldLength < f_ulMinLengthValue ) + return ( cOCT6100_ERR_FATAL_59 ); + + /* Check if the value is too big. */ + if ( f_ulTlvFieldLength > f_ulMaxLengthValue ) + return ( cOCT6100_ERR_FATAL_5A ); + + /* Check if the value is dword aligned. */ + if ( ( f_ulTlvFieldLength % 4 ) != 0 ) + return ( cOCT6100_ERR_OPEN_INVALID_TLV_LENGTH ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTlvReadBitOffsetStruct + +Description: This function extracts a bit offset structure from the TLV. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulAddress Address where the read the TLV information. +f_pBitOffsetStruct Pointer to a bit offset stucture. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTlvReadBitOffsetStruct +UINT32 Oct6100ApiTlvReadBitOffsetStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT tPOCT6100_TLV_OFFSET f_pBitOffsetStruct ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + UINT32 ulResult; + UINT32 ulOffsetValue; + UINT32 ulSizeValue; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*======================================================================*/ + /* Read the first 16 bits of the TLV field. */ + + ReadParams.ulReadAddress = f_ulAddress; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulOffsetValue = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulOffsetValue |= usReadData; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read the first 16 bits of the TLV field. */ + + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulSizeValue = usReadData << 16; + + /* Read the last word of the TLV type. */ + ReadParams.ulReadAddress += 2; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save data. */ + ulSizeValue |= usReadData; + + /*======================================================================*/ + + /* Set the structure fields. */ + f_pBitOffsetStruct->usDwordOffset = (UINT16)(ulOffsetValue / 32); + f_pBitOffsetStruct->byBitOffset = (UINT8) (32 - (ulOffsetValue % 32) - ulSizeValue); + f_pBitOffsetStruct->byFieldSize = (UINT8) (ulSizeValue); + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c new file mode 100644 index 0000000..6d9c82b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c @@ -0,0 +1,1088 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to enable and disable tone detection on + an echo channel. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 51 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_events_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_events_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_events_priv.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionEnable + +Description: This function enables the generation of event for a selected + tone on the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detection enable structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionEnableDef +UINT32 Oct6100ToneDetectionEnableDef( + tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + f_pToneDetectEnable->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pToneDetectEnable->ulToneNumber = cOCT6100_INVALID_TONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ToneDetectionEnable +UINT32 Oct6100ToneDetectionEnable( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ToneDetectionEnableSer( f_pApiInstance, f_pToneDetectEnable ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionDisable + +Description: This function disables the detection of a tone for a specific + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tone detection disable structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionDisableDef +UINT32 Oct6100ToneDetectionDisableDef( + tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + f_pToneDetectDisable->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pToneDetectDisable->ulToneNumber = cOCT6100_INVALID_VALUE; + f_pToneDetectDisable->fDisableAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ToneDetectionDisable +UINT32 Oct6100ToneDetectionDisable( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ToneDetectionDisableSer( f_pApiInstance, f_pToneDetectDisable ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionEnableSer + +Description: Activate the detection of a tone on the specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detect enable structure. This structure + contains, among other things, the tone ID to enable + and the channel handle where detection should be + enabled. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionEnableSer +UINT32 Oct6100ToneDetectionEnableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ) +{ + UINT32 ulChanIndex; + UINT32 ulExtToneChanIndex; + UINT32 ulToneEventNumber = 0; + + UINT32 ulResult; + + /* Check the user's configuration of the tone detection for errors. */ + ulResult = Oct6100ApiCheckToneEnableParams( + f_pApiInstance, + f_pToneDetectEnable, + &ulChanIndex, + &ulToneEventNumber, + + &ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write to all resources needed to enable tone detection. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + + ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel entry to indicate that a new tone has been activated. */ + ulResult = Oct6100ApiUpdateChanToneDetectEntry( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckToneEnableParams + +Description: Check the validity of the channel and tone requested. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectEnable Pointer to tone detection enable structure. +f_pulChannelIndex Pointer to the channel index. +f_pulToneEventNumber Pointer to the Index of the tone associated to the requested tone. +f_pulExtToneChanIndex Pointer to the index of the extended channel index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckToneEnableParams +UINT32 Oct6100ApiCheckToneEnableParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + + OUT PUINT32 f_pulExtToneChanIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + UINT32 i; + + /*=====================================================================*/ + /* Check the channel handle. */ + + if ( (f_pToneDetectEnable->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pToneDetectEnable->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pToneDetectEnable->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + /* Set the extended tone detection info if it is activated on the channel. */ + *f_pulExtToneChanIndex = pEchoChannel->usExtToneChanIndex; + + /*=====================================================================*/ + /* Check the tone information. */ + + /* Find out if the tone is present in the build. */ + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + if ( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID == f_pToneDetectEnable->ulToneNumber ) + { + *f_pulToneEventNumber = i; + break; + } + } + + /* Check if tone is present. */ + if ( i == cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE; + + /* Check if the requested tone is actually detected. */ + if ((( pEchoChannel->aulToneConf[ *f_pulToneEventNumber / 32 ] >> ( 31 - ( *f_pulToneEventNumber % 32 ))) & 0x1) == 1 ) + return cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED; + + + + /*=====================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteToneDetectEvent + +Description: Write the tone detection event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Event number of the tone to be activated. +f_ulExtToneChanIndex Index of the extended tone detection channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteToneDetectEvent +UINT32 Oct6100ApiWriteToneDetectEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + + IN UINT32 f_ulExtToneChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Read the current event config about to be modified. */ + + ReadParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + /* Set the tone event in the channel main memory for the requested direction. */ + + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData |= ( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 ))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + /* Also program the extended channel if one is present. */ + + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Read the current event config about to be modified. */ + ReadParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the tone event in the channel main memory for the requested direction. */ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData |= ( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 ))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateChanToneDetectEntry + +Description: Update the echo channel entry to store the info about the tone + being configured to generate detection events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Enabled tone event number. +f_ulExtToneChanIndex Index of the extended tone detection channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateChanToneDetectEntry +UINT32 Oct6100ApiUpdateChanToneDetectEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulToneEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulChannelIndex ); + + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry |= ( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 ))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + + /* Configure also the extended channel if necessary. */ + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulExtToneChanIndex ); + + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry |= ( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 ))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + + /* Check for the SS tone events that could have been generated before. */ + if ( f_ulExtToneChanIndex == cOCT6100_INVALID_INDEX ) + { + BOOL fSSTone; + UINT32 ulResult; + + ulResult = Oct6100ApiIsSSTone( f_pApiInstance, pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID, &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Is this a signaling system tone? */ + if ( fSSTone == TRUE ) + { + /* Check if must generate an event for the last detected SS tone. */ + if ( ( pEchoChanEntry->ulLastSSToneDetected != cOCT6100_INVALID_INDEX ) + && ( pEchoChanEntry->ulLastSSToneDetected == pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID ) ) + { + /* Must write an event for this. */ + tPOCT6100_API_TONE_EVENT pSoftEvent; + + /* If enough space. */ + if ( ( ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr ) && + ( ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0 ) ) + { + /* Form the event for this captured tone. */ + mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent ) + pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr; + + pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex; + pSoftEvent->ulUserChanId = pEchoChanEntry->ulUserChanId; + pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ f_ulToneEventNumber ].ulToneID; + pSoftEvent->ulTimestamp = pEchoChanEntry->ulLastSSToneTimestamp; + pSoftEvent->ulExtToneDetectionPort = cOCT6100_INVALID_VALUE; + pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT; + + /* Update the control variables of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++; + if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize ) + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + + /* Set the interrupt manager such that the user knows that some tone events */ + /* are pending in the software Q. */ + pSharedInfo->IntrptManage.fToneEventsPending = TRUE; + } + else + { + /* Set the overflow flag of the buffer. */ + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++; + } + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ToneDetectionDisableSer + +Description: Disable the generation of events for a selected tone on the + specified channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tOCT6100_TONE_DETECTION_DISABLE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ToneDetectionDisableSer +UINT32 Oct6100ToneDetectionDisableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ) +{ + UINT32 ulChanIndex; + UINT32 ulExtToneChanIndex; + UINT32 ulToneEventNumber = 0; + UINT32 ulResult; + BOOL fDisableAll; + + + /* Check the user's configuration of the tone detection disable structure for errors. */ + ulResult = Oct6100ApiAssertToneDetectionParams( + f_pApiInstance, + f_pToneDetectDisable, + &ulChanIndex, + &ulToneEventNumber, + &ulExtToneChanIndex, + + &fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event to detect the specified tone. */ + ulResult = Oct6100ApiClearToneDetectionEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex, + + fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the channel structure to indicate that the tone is no longer detected. */ + ulResult = Oct6100ApiReleaseToneDetectionEvent( + f_pApiInstance, + ulChanIndex, + ulToneEventNumber, + ulExtToneChanIndex, + fDisableAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertToneDetectionParams + +Description: Check the validity of the tone detection disable command. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pToneDetectDisable Pointer to tone detection disable structure. +f_pulChannelIndex Pointer to the channel index +f_pulToneEventNumber Pointer to the tone event number. +f_pulExtToneChanIndex Pointer to the extended channel index. +f_pfDisableAll Pointer to the flag specifying whether all tones + should be disabled. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertToneDetectionParams +UINT32 Oct6100ApiAssertToneDetectionParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + OUT PUINT32 f_pulExtToneChanIndex, + + OUT PBOOL f_pfDisableAll ) +{ + tPOCT6100_API_CHANNEL pEchoChannel; + UINT32 ulEntryOpenCnt; + UINT32 i; + + /*=====================================================================*/ + /* Check the echo channel handle. */ + + if ( (f_pToneDetectDisable->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + *f_pulChannelIndex = f_pToneDetectDisable->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK; + if ( *f_pulChannelIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, *f_pulChannelIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pToneDetectDisable->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pEchoChannel->fReserved != TRUE ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pEchoChannel->byEntryOpenCnt ) + return cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID; + + /* Return the extended channel index. */ + *f_pulExtToneChanIndex = pEchoChannel->usExtToneChanIndex; + + /* Check the disable all flag. */ + if ( f_pToneDetectDisable->fDisableAll != TRUE && f_pToneDetectDisable->fDisableAll != FALSE ) + return cOCT6100_ERR_TONE_DETECTION_DISABLE_ALL; + + /*=====================================================================*/ + /* Check the tone information. */ + + /* Find out if the tone is present in the build. */ + if ( f_pToneDetectDisable->fDisableAll == FALSE ) + { + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + if ( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID == f_pToneDetectDisable->ulToneNumber ) + { + *f_pulToneEventNumber = i; + break; + } + } + + /* Check if tone is present. */ + if ( i == cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE; + + + + /* Check if the requested tone is actually detected. */ + if ((( pEchoChannel->aulToneConf[ *f_pulToneEventNumber / 32 ] >> ( 31 - ( *f_pulToneEventNumber % 32 ))) & 0x1) == 0 ) + return cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED; + } + + + /*=====================================================================*/ + + /* Return the disable all flag as requested. */ + *f_pfDisableAll = f_pToneDetectDisable->fDisableAll; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearToneDetectionEvent + +Description: Clear the buffer playout event in the channel main structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Tone event number to be deactivated. +f_ulExtToneChanIndex Index of the extended tone detection channel. +f_fDisableAll Clear all activated tones. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearToneDetectionEvent +UINT32 Oct6100ApiClearToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + + IN BOOL f_fDisableAll ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + UINT32 ulToneEventBaseAddress; + UINT16 usReadData; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Read the current event config about to be modified. */ + + ulToneEventBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulChannelIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulToneEventBaseAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + + /* Check if must disable all tone events or not. */ + if ( f_fDisableAll == FALSE ) + { + ReadParams.ulReadAddress = ulToneEventBaseAddress; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event in the channel main memory.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData &= (~( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 )))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events in the channel main memory. */ + SmearParams.ulWriteLength = 4; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteAddress = ulToneEventBaseAddress; + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* Also program the extended channel if one is present. */ + + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + ulToneEventBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_ulExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulToneEventBaseAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + + /* Check if must disable all tone events or not. */ + if ( f_fDisableAll == FALSE ) + { + /* Read the current event config about to be modified. */ + ReadParams.ulReadAddress = ulToneEventBaseAddress; + ReadParams.ulReadAddress += (f_ulToneEventNumber / 16) * 2; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear the event in the channel main memory.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + WriteParams.usWriteData = usReadData; + WriteParams.usWriteData &= (~( 0x1 << ( 15 - ( f_ulToneEventNumber % 16 )))); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events in the channel main memory.*/ + SmearParams.ulWriteLength = 4; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteAddress = ulToneEventBaseAddress; + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseToneDetectionEvent + +Description: Clear the entry made for this tone in the channel tone + enable array. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulChannelIndex Index of the channel within the API's channel list. +f_ulToneEventNumber Tone event number to be deactivated. +f_ulExtToneChanIndex Index of the extended tone detection channel. +f_fDisableAll Release all activated tones. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseToneDetectionEvent +UINT32 Oct6100ApiReleaseToneDetectionEvent ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + IN BOOL f_fDisableAll ) +{ + tPOCT6100_API_CHANNEL pEchoChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulToneEntry; + UINT32 ulResult; + UINT32 ulToneEventNumber; + BOOL fSSTone; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulChannelIndex ); + + /* Check if must release all tone events. */ + if ( f_fDisableAll == FALSE ) + { + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry &= (~( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 )))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events. */ + Oct6100UserMemSet( pEchoChanEntry->aulToneConf, 0x00, sizeof( pEchoChanEntry->aulToneConf ) ); + } + + /* Configure also the extended channel if necessary. */ + if ( f_ulExtToneChanIndex != cOCT6100_INVALID_INDEX ) + { + /* Update the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChanEntry, f_ulExtToneChanIndex ); + + /* Check if must release all tone events. */ + if ( f_fDisableAll == FALSE ) + { + /* Set the corresponding bit in the channel array. */ + ulToneEntry = pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ]; + + /* Modify the entry. */ + ulToneEntry &= (~( 0x1 << ( 31 - ( f_ulToneEventNumber % 32 )))); + + /* Copy back the new value. */ + pEchoChanEntry->aulToneConf[ f_ulToneEventNumber / 32 ] = ulToneEntry; + } + else /* if ( f_fDisableAll == TRUE ) */ + { + /* Clear all events. */ + Oct6100UserMemSet( pEchoChanEntry->aulToneConf, 0x00, sizeof( pEchoChanEntry->aulToneConf ) ); + } + } + + /* Re-enable the SS7 tones */ + for ( ulToneEventNumber = 0; ulToneEventNumber < cOCT6100_MAX_TONE_EVENT; ulToneEventNumber++ ) + { + /* Check if the current tone is a SS tone. */ + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Write to all resources needed to activate tone detection on this SS tone. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + f_ulChannelIndex, + ulToneEventNumber, + + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsSSTone + +Description: Check if specified tone number is a special signaling + system tone. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulToneEventNumber Tone event number to be checked against. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIsSSTone +UINT32 Oct6100ApiIsSSTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fSSTone ) +{ + *f_fSSTone = FALSE; + + switch( f_ulToneEventNumber ) + { + case cOCT6100_TONE_SIN_SYSTEM7_2000 : + case cOCT6100_TONE_SIN_SYSTEM7_1780 : + case cOCT6100_TONE_ROUT_G168_2100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR : + case cOCT6100_TONE_ROUT_G168_1100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SOUT_G168_2100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR : + case cOCT6100_TONE_SOUT_G168_1100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SIN_SYSTEM5_2400 : + case cOCT6100_TONE_SIN_SYSTEM5_2600 : + case cOCT6100_TONE_SIN_SYSTEM5_2400_2600 : + *f_fSSTone = TRUE; + break; + default: + break; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiIsSSTone + +Description: Check if specified tone number is a 2100 special signaling + system tone. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulToneEventNumber Tone event number to be checked against. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiIs2100Tone +UINT32 Oct6100ApiIs2100Tone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fIs2100Tone ) +{ + *f_fIs2100Tone = FALSE; + + switch( f_ulToneEventNumber ) + { + case cOCT6100_TONE_ROUT_G168_2100GB_ON : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE : + case cOCT6100_TONE_SOUT_G168_2100GB_ON : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A : + case cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B : + case cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE : + *f_fIs2100Tone = TRUE; + break; + default: + break; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c new file mode 100644 index 0000000..e885aa4 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c @@ -0,0 +1,1023 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close TSI connections + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 38 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_tsi_cnct_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctOpen + +Description: This function opens a TSI connection between two TDM timeslots. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctOpenDef +UINT32 Oct6100TsiCnctOpenDef( + tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + f_pTsiCnctOpen->pulTsiCnctHndl = NULL; + + f_pTsiCnctOpen->ulInputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pTsiCnctOpen->ulInputStream = cOCT6100_INVALID_STREAM; + f_pTsiCnctOpen->ulOutputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pTsiCnctOpen->ulOutputStream = cOCT6100_INVALID_STREAM; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100TsiCnctOpen +UINT32 Oct6100TsiCnctOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100TsiCnctOpenSer( f_pApiInstance, f_pTsiCnctOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctClose + +Description: This function closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctCloseDef +UINT32 Oct6100TsiCnctCloseDef( + tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + f_pTsiCnctClose->ulTsiCnctHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100TsiCnctClose +UINT32 Oct6100TsiCnctClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100TsiCnctCloseSer( f_pApiInstance, f_pTsiCnctClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetTsiCnctSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management the TSI memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetTsiCnctSwSizes +UINT32 Oct6100ApiGetTsiCnctSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API TSI connection list. */ + f_pInstSizes->ulTsiCnctList = f_pOpenChip->ulMaxTsiCncts * sizeof( tOCT6100_API_TSI_CNCT ); + + if ( f_pOpenChip->ulMaxTsiCncts > 0 ) + { + /* Calculate memory needed for TSI memory allocation. */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxTsiCncts, &f_pInstSizes->ulTsiCnctAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_48; + } + else + { + f_pInstSizes->ulTsiCnctAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiCnctList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsiCnctAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTsiCnctSwInit + +Description: Initializes all elements of the instance structure associated + to the TSI memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTsiCnctSwInit +UINT32 Oct6100ApiTsiCnctSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_TSI_CNCT pChannelsTsiList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxTsiChannels; + PVOID pTsiChannelsAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the TSI connections API list. */ + ulMaxTsiChannels = pSharedInfo->ChipConfig.usMaxTsiCncts; + + mOCT6100_GET_TSI_CNCT_LIST_PNT( pSharedInfo, pChannelsTsiList ) + + /* Clear the memory. */ + Oct6100UserMemSet( pChannelsTsiList, 0x00, sizeof(tOCT6100_API_TSI_CNCT) * ulMaxTsiChannels ); + + /* Set all entries in the TSI connections list to unused. */ + if ( ulMaxTsiChannels > 0 ) + { + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChannelsAlloc ) + + ulResult = OctapiLlmAllocInit( &pTsiChannelsAlloc, ulMaxTsiChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_49; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctOpenSer + +Description: Opens a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to a tOCT6100_TSI_CNCT_OPEN structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctOpenSer +UINT32 Oct6100TsiCnctOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + UINT16 usTsiChanIndex; + UINT16 usTsiMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the TSI connection open structure for errors. */ + ulResult = Oct6100ApiCheckTsiParams( f_pApiInstance, f_pTsiCnctOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the TSI connection. */ + ulResult = Oct6100ApiReserveTsiResources( f_pApiInstance, f_pTsiCnctOpen, &usTsiChanIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the TSI connection. */ + ulResult = Oct6100ApiWriteTsiStructs( f_pApiInstance, f_pTsiCnctOpen, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the TSI connection entry in the API list. */ + ulResult = Oct6100ApiUpdateTsiEntry( f_pApiInstance, f_pTsiCnctOpen, usTsiChanIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckTsiParams + +Description: Checks the user's TSI connection open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckTsiParams +UINT32 Oct6100ApiCheckTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxTsiCncts == 0 ) + return cOCT6100_ERR_TSI_CNCT_DISABLED; + + if ( f_pTsiCnctOpen->pulTsiCnctHndl == NULL ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /* Check the input TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_TSI_CNCT_INPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_TSI_CNCT_INPUT_STREAM; + } + else + { + return ulResult; + } + } + + /* Check the output TDM streams, timeslots component for errors. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + cOCT6100_NUMBER_TSSTS_1, + f_pTsiCnctOpen->ulOutputTimeslot, + f_pTsiCnctOpen->ulOutputStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_TSI_CNCT_OUTPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_TSI_CNCT_OUTPUT_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiResources + +Description: Reserves all resources needed for the new TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to tsi channel configuration structure. +f_pusTsiChanIndex Allocated entry in TSI channel list. +f_pusTsiMemIndex Allocated entry in the TSI control memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiResources +UINT32 Oct6100ApiReserveTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + BOOL fTsiChanEntry = FALSE; + BOOL fTsiMemEntry = FALSE; + BOOL fInputTsst = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the TSI connection list. */ + ulResult = Oct6100ApiReserveTsiCnctEntry( f_pApiInstance, f_pusTsiChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiChanEntry = TRUE; + + /* Find a TSI memory entry. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, f_pusTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiMemEntry = TRUE; + + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + f_pusInputTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fInputTsst = TRUE; + + /* Reserve the output TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pTsiCnctOpen->ulOutputTimeslot, + f_pTsiCnctOpen->ulOutputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + f_pusOutputTsstIndex, + NULL ); + } + } + else + { + /* Return an error other then a fatal. */ + ulResult = cOCT6100_ERR_TSI_CNCT_NO_MORE_TSI_AVAILABLE; + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if( fTsiChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiCnctEntry( f_pApiInstance, *f_pusTsiChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, *f_pusTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fInputTsst == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + f_pTsiCnctOpen->ulInputTimeslot, + f_pTsiCnctOpen->ulInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteTsiStructs + +Description: Performs all the required structure writes to configure the + new TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to tsi connection open structure. +f_usTsiMemIndex Allocated entry in the TSI control memory. +f_usInputTsstIndex TSST memory index of the input samples. +f_usOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteTsiStructs +UINT32 Oct6100ApiWriteTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Configure the TSST control memory.*/ + + /* Set the input TSST control entry.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usInputTsstIndex, + f_usTsiMemIndex, + cOCT6100_PCM_U_LAW ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry. */ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usOutputTsstIndex, + cOCT6100_ADPCM_IN_LOW_BITS, + 1, + f_usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateTsiEntry + +Description: Updates the new TSI connection in the TSI connection list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTsiCnctOpen Pointer to TSI connection open configuration structure. +f_usTsiMemIndex Allocated entry in TSI chariot memory. +f_usTsiChanIndex Allocated entry in the TSI channel list. +f_usInputTsstIndex TSST control memory index of the input TSST. +f_usOutputTsstIndex TSST control memory index of the output TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateTsiEntry +UINT32 Oct6100ApiUpdateTsiEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_API_TSI_CNCT pTsiCnctEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new TSI connection's list entry. */ + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnctEntry, f_usTsiChanIndex ) + + /* Copy the TSI's configuration and allocated resources. */ + pTsiCnctEntry->usInputTimeslot = (UINT16)( f_pTsiCnctOpen->ulInputTimeslot & 0xFFFF ); + pTsiCnctEntry->usInputStream = (UINT16)( f_pTsiCnctOpen->ulInputStream & 0xFFFF ); + + pTsiCnctEntry->usOutputTimeslot = (UINT16)( f_pTsiCnctOpen->ulOutputTimeslot & 0xFFFF ); + pTsiCnctEntry->usOutputStream = (UINT16)( f_pTsiCnctOpen->ulOutputStream & 0xFFFF ); + + /* Store hardware related information. */ + pTsiCnctEntry->usTsiMemIndex = f_usTsiMemIndex; + pTsiCnctEntry->usInputTsstIndex = f_usInputTsstIndex; + pTsiCnctEntry->usOutputTsstIndex = f_usOutputTsstIndex; + + /* Form handle returned to user. */ + *f_pTsiCnctOpen->pulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnctEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usTsiChanIndex; + + /* Finally, mark the connection as opened. */ + pTsiCnctEntry->fReserved = TRUE; + + /* Increment the number of TSI connection opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberTsiCncts++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100TsiCnctCloseSer + +Description: Closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100TsiCnctCloseSer +UINT32 Oct6100TsiCnctCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ) +{ + UINT16 usTsiChanIndex; + UINT16 usTsiMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertTsiParams( f_pApiInstance, f_pTsiCnctClose, &usTsiChanIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the TSI channel. */ + ulResult = Oct6100ApiInvalidateTsiStructs( f_pApiInstance, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the TSI connection. */ + ulResult = Oct6100ApiReleaseTsiResources( f_pApiInstance, usTsiChanIndex, usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pTsiCnctClose->ulTsiCnctHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertTsiParams + +Description: Validate the handle given by the user and verify the state of + the TSI connection about to be closed. + Also returns all required information to deactivate the connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pTsiCnctClose Pointer to TSI connection close structure. +f_pusTsiChanIndex Index of the TSI connection structure in the API list. +f_pusTsiMemIndex Index of the TSI entry within the TSI chariot memory +f_pusInputTsstIndex Index of the input entry in the TSST control memory. +f_pusOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertTsiParams +UINT32 Oct6100ApiAssertTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSI_CNCT pTsiEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pTsiCnctClose->ulTsiCnctHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_TSI_CNCT ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + *f_pusTsiChanIndex = (UINT16)( f_pTsiCnctClose->ulTsiCnctHndl & cOCT6100_HNDL_INDEX_MASK ); + + if ( *f_pusTsiChanIndex >= pSharedInfo->ChipConfig.usMaxTsiCncts ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pTsiEntry, *f_pusTsiChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pTsiCnctClose->ulTsiCnctHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pTsiEntry->fReserved != TRUE ) + return cOCT6100_ERR_TSI_CNCT_NOT_OPEN; + if ( ulEntryOpenCnt != pTsiEntry->byEntryOpenCnt ) + return cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE; + + /* Return info needed to close the channel and release all resources. */ + *f_pusInputTsstIndex = pTsiEntry->usInputTsstIndex; + *f_pusOutputTsstIndex = pTsiEntry->usOutputTsstIndex; + *f_pusTsiMemIndex = pTsiEntry->usTsiMemIndex; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateTsiStructs + +Description: This function closes a TSI connection. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usInputTsstIndex Index of the input entry in the TSST control memory. +f_usOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateTsiStructs +UINT32 Oct6100ApiInvalidateTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==================================================================================*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usInputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usOutputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiResources + +Description: Release and clear the API entry associated to the TSI channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usTsiChanIndex Index of the TSI connection in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiResources +UINT32 Oct6100ApiReleaseTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSI_CNCT pTsiEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pTsiEntry, f_usTsiChanIndex ); + + /* Release the entry in the TSI connection list. */ + ulResult = Oct6100ApiReleaseTsiCnctEntry( f_pApiInstance, f_usTsiChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, f_usTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the input entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTsiEntry->usInputTimeslot, + pTsiEntry->usInputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the output TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTsiEntry->usOutputTimeslot, + pTsiEntry->usOutputStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + } + } + } + + /* Check if an error occured while releasing the reserved resources. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult >= cOCT6100_ERR_FATAL ) + return ulResult; + else + return cOCT6100_ERR_FATAL_4A; + } + + /*=============================================================*/ + /* Update the TSI connection's list entry. */ + + /* Mark the connection as closed. */ + pTsiEntry->fReserved = FALSE; + pTsiEntry->byEntryOpenCnt++; + + /* Decrement the number of TSI connection opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberTsiCncts--; + + /*=============================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsiCnctEntry + +Description: Reserves one of the TSI connection API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusTsiChanIndex Resulting index reserved in the TSI channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsiCnctEntry +UINT32 Oct6100ApiReserveTsiCnctEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiChanAlloc; + UINT32 ulResult; + UINT32 ulTsiIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pTsiChanAlloc, &ulTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_TSI_CNCT_ALL_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_4B; + } + + *f_pusTsiChanIndex = (UINT16)( ulTsiIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsiCnctEntry + +Description: Releases the specified TSI connection API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsiChanIndex Index reserved in the TSI channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsiCnctEntry +UINT32 Oct6100ApiReleaseTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsiChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pTsiChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsiChanAlloc, f_usTsiChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_4C; + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c new file mode 100644 index 0000000..d3235a1 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c @@ -0,0 +1,572 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of TSST + control structures in internal memory. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 39 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_tsst_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_tsst_priv.h" + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetTsstSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of TSSTs. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetTsstSwSizes +UINT32 Oct6100ApiGetTsstSwSizes( + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine amount of TSST needed for TSST allocation table. */ + f_pInstSizes->ulTsstAlloc = 4096 / 8; + + /* Calculate the API memory required for the TSST entry list. */ + f_pInstSizes->ulTsstEntryList = cOCT6100_MAX_TSSTS * sizeof( tOCT6100_API_TSST_ENTRY ); + + /* Calculate memory needed for TSST entry allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_TSSTS, &f_pInstSizes->ulTsstEntryAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstAlloc, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstEntryList, ulTempVar ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulTsstEntryAlloc, ulTempVar ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiTsstSwInit + +Description: Initializes all elements of the instance structure associated + to the TSST control entries. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiTsstSwInit +UINT32 Oct6100ApiTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSST_ENTRY pTsstList; + PUINT32 pulTsstAlloc; + PVOID pTsstListAlloc; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the TSST allocation table to "all free". */ + mOCT6100_GET_TSST_ALLOC_PNT( pSharedInfo, pulTsstAlloc ); + Oct6100UserMemSet( pulTsstAlloc, 0x00, 512 ); + + /* Initialize all the TSST list entries. */ + mOCT6100_GET_TSST_LIST_PNT( pSharedInfo, pTsstList ); + Oct6100UserMemSet( pTsstList, 0xFF, cOCT6100_MAX_TSSTS * sizeof(tOCT6100_API_TSST_ENTRY) ); + + /* Initialize the allocation list to manage the TSST entries.*/ + mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pTsstListAlloc ) + + ulResult = OctapiLlmAllocInit( &pTsstListAlloc, cOCT6100_MAX_TSSTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4E; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiValidateTsst + +Description: Validates a timeslot, stream combination. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulStream Stream component of the TDM TSST. +f_ulNumTssts Number of TSST required. +f_ulDirection Direction of the TSST (Input or Output). + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiValidateTsst +UINT32 Oct6100ApiValidateTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulNumTssts, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulDirection ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Check the TDM streams, timeslots component for errors. */ + if ( f_ulTimeslot == cOCT6100_UNASSIGNED && + f_ulStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_TSST_TIMESLOT; + + if ( f_ulTimeslot != cOCT6100_UNASSIGNED && + f_ulStream == cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_TSST_STREAM; + + if ( f_ulStream >= pChipConfig->byMaxTdmStreams ) + return cOCT6100_ERR_TSST_STREAM; + + /* Check timeslot value based on the frequenccy of the selected stream. */ + switch ( pChipConfig->aulTdmStreamFreqs[ f_ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + if ( f_ulTimeslot >= 32 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + if ( f_ulTimeslot >= 64 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + if ( f_ulTimeslot >= 128 ) + return cOCT6100_ERR_TSST_TIMESLOT; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + if ( f_ulTimeslot >= 256 ) + return cOCT6100_ERR_TSST_TIMESLOT; + + /* Check the stream value based on the direction. */ + if ( f_ulDirection == cOCT6100_INPUT_TSST && f_ulStream >= 16 ) + { + return cOCT6100_ERR_TSST_STREAM; + } + else if( f_ulDirection == cOCT6100_OUTPUT_TSST && f_ulStream < 16 ) + { + return cOCT6100_ERR_TSST_STREAM; + } + + break; + default: + return cOCT6100_ERR_FATAL_DC; + } + + /* Stream must be odd if two TSSTs are required. */ + if ( f_ulNumTssts == 2 && ( ( f_ulStream & 0x1) != 0x1 ) ) + return cOCT6100_ERR_TSST_STREAM; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsst + +Description: Reserves a TSST, only one TSI entry can access a TSST at any one + time. + If the pointer f_pulTsstListIndex is set to NULL, no TSST list + entry will be reserved. + + The index in TSST control memory returned is based on the frequency + of the streams where the TSST is located and on the direction of + the TSST ( input or output ). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulNumTssts Number of TSSTs required. +f_ulStream Stream component of the TDM TSST. +f_ulDirection Whether the TSST in and input TSST or output TSST. +f_pusTsstMemIndex Index of the resulting TSST in the TSST control memory. +f_pusTsstListIndex Index in the TSST list of the current entry. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsst +UINT32 Oct6100ApiReserveTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + OUT PUINT16 f_pusTsstMemIndex, + OUT PUINT16 f_pusTsstListIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pTsstListAlloc; + PUINT32 pulTsstAlloc; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulStream; + UINT32 ulTimeslot; + + /* Get local pointer to shared portion of API instance structure. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc ); + + /*==================================================================================*/ + /* Now make the proper conversion to obtain the TSST value. */ + + /* Save the timeslot and stream value received. */ + ulStream = f_ulStream; + ulTimeslot = f_ulTimeslot; + + /* Set the TSST index associated to this stream, timeslot combination. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.aulTdmStreamFreqs[ f_ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + if ( f_ulDirection == cOCT6100_INPUT_TSST ) + { + ulStream = f_ulStream + ( f_ulTimeslot % 2 ) * 16; + ulTimeslot = f_ulTimeslot / 2; + } + else /* f_ulDirection == cOCT6100_OUTPUT_TSST */ + { + ulStream = ( f_ulStream - 16 ) + ( f_ulTimeslot % 2 ) * 16; + + if ( f_ulStream < 28 && ((f_ulTimeslot % 2) == 1) ) + { + ulTimeslot = ((f_ulTimeslot / 2) + 4) % 128; + } + else + { + ulTimeslot = f_ulTimeslot / 2 ; + } + } + + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 + ulStream ); + break; + + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 + ulStream ); + break; + + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 * 2 ); + if ( f_ulDirection == cOCT6100_OUTPUT_TSST ) + { + *f_pusTsstMemIndex = (UINT16)( *f_pusTsstMemIndex + ulStream ); + } + else /* if ( f_ulDirection == cOCT6100_INPUT_TSST ) */ + { + *f_pusTsstMemIndex = (UINT16)( ( 1 * 32 + ulStream ) + *f_pusTsstMemIndex ); + } + break; + + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + *f_pusTsstMemIndex = (UINT16)( ulTimeslot * 32 * 4 ); + if ( f_ulDirection == cOCT6100_OUTPUT_TSST ) + { + *f_pusTsstMemIndex = (UINT16)( ulStream + *f_pusTsstMemIndex ); + } + else /* if ( f_ulDirection == cOCT6100_INPUT_TSST ) */ + { + *f_pusTsstMemIndex = (UINT16)( ( 3 * 32 + ulStream ) + *f_pusTsstMemIndex ); + } + break; + + default: + ulResult = cOCT6100_ERR_FATAL_8B; + } + /*======================================================================*/ + + + /*======================================================================*/ + /* First reserve the TSST. */ + + /* Get local pointer to TSST's entry in allocation table. */ + switch ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + ulTimeslot *= 4; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + ulTimeslot *= 2; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + ulTimeslot *= 1; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + ulTimeslot *= 1; + break; + default: + return cOCT6100_ERR_FATAL_DD; + } + + /* Check if entry is already reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ulStream) & 0x1) == 0x1 ) + return cOCT6100_ERR_TSST_TSST_RESERVED; + + /* Check and reserve the associated TSST if required. */ + if ( f_ulNumTsst == 2 ) + { + /* Check if entry is already reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> (ulStream - 1) ) & 0x1) == 0x1 ) + return cOCT6100_ERR_TSST_ASSOCIATED_TSST_RESERVED; + + /* The entry is free, it won't anymore. */ + pulTsstAlloc[ ulTimeslot ] |= (0x1 << (ulStream - 1)); + } + + /* The entry is free, it won't anymore.*/ + pulTsstAlloc[ ulTimeslot ] |= (0x1 << ulStream); + + /*======================================================================*/ + + + /*======================================================================*/ + /* Now reserve a TSST entry if requested. */ + + if ( f_pusTsstListIndex != NULL && ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulTsstListIndex; + + /* Reserve a TSST entry in the API TSST list. */ + mOCT6100_GET_TSST_LIST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pTsstListAlloc ); + + ulResult = OctapiLlmAllocAlloc( pTsstListAlloc, &ulTsstListIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + ulResult = cOCT6100_ERR_TSST_ALL_TSSTS_ARE_OPENED; + else + ulResult = cOCT6100_ERR_FATAL_52; + } + + *f_pusTsstListIndex = (UINT16)( ulTsstListIndex & 0xFFFF ); + } + /*======================================================================*/ + + + /*======================================================================*/ + /* Check the result of the TSST list reservation. */ + + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release the previously reserved TSST. */ + if ( f_ulNumTsst == 2 ) + { + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << (ulStream - 1) ); + + } + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << ulStream); + } + + /*======================================================================*/ + + return ulResult; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsst + +Description: Releases a TSST. + + If f_usTsstListIndex is set to cOCT6100_INVALID_INDEX, the API + will assume that no TSST list entry was reserved for this TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This tsst is used to keep + the present state of the chip and all its resources. + +f_ulNumTssts Number of TSSTs to be released. +f_ulStream Stream component of the TDM TSST. +f_ulTimeslot Timeslot component of the TDM TSST. +f_ulDirection Whether the TSST is an input TSST or output TSST. +f_usTsstListIndex Index in the TSST list of the current entry. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsst +UINT32 Oct6100ApiReleaseTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + IN UINT16 f_usTsstListIndex) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PUINT32 pulTsstAlloc; + PVOID pTsstListAlloc; + UINT32 ulResult; + UINT32 ulStream; + UINT32 ulTimeslot; + + /* Get local pointer to shared portion of API instance structure. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_usTsstListIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pTsstListAlloc ) + + ulResult = OctapiLlmAllocDealloc( pTsstListAlloc, f_usTsstListIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_53; + } + } + + mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc ); + + /*==================================================================================*/ + /* Now make the proper conversion to obtain the TSST value. */ + + /* Save the timeslot and stream value received. */ + ulStream = f_ulStream; + ulTimeslot = f_ulTimeslot; + + /* Set the TSST index associated to this stream, timeslot combination. */ + if ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ f_ulStream / 4 ] == cOCT6100_TDM_STREAM_FREQ_16MHZ ) + { + if ( f_ulDirection == cOCT6100_INPUT_TSST ) + { + ulStream = f_ulStream + ( f_ulTimeslot % 2 ) * 16; + ulTimeslot = f_ulTimeslot / 2; + } + else /* f_ulDirection == cOCT6100_OUTPUT_TSST */ + { + ulStream = ( f_ulStream - 16 ) + ( f_ulTimeslot % 2 ) * 16; + + if ( f_ulStream < 28 && ((f_ulTimeslot % 2) == 1) ) + { + ulTimeslot = ((f_ulTimeslot / 2) + 4) % 128; + } + else + { + ulTimeslot = f_ulTimeslot / 2 ; + } + } + } + + /* Get local pointer to TSST's entry in allocation table. */ + switch ( pSharedInfo->ChipConfig.aulTdmStreamFreqs[ ulStream / 4 ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + ulTimeslot *= 4; + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + ulTimeslot *= 2; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + ulTimeslot *= 1; + break; + case cOCT6100_TDM_STREAM_FREQ_16MHZ: + ulTimeslot *= 1; + break; + default: + return cOCT6100_ERR_FATAL_DE; + } + + /* Check if entry is actualy reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ulStream) & 0x1) != 0x1 ) + return cOCT6100_ERR_FATAL_55; + + /*==================================================================================*/ + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << ulStream); + + /* Check and release the associated TSST if required. */ + if ( f_ulNumTsst == 2 ) + { + /* Check if entry is actualy reserved. */ + if ( ((pulTsstAlloc[ ulTimeslot ] >> ( ulStream - 1)) & 0x1) != 0x1 ) + return cOCT6100_ERR_FATAL_54; + + /* Clear the entry. */ + pulTsstAlloc[ ulTimeslot ] &= ~(0x1 << (ulStream - 1)); + + } + + return cOCT6100_ERR_OK; +} +#endif diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c new file mode 100644 index 0000000..9d0e317 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c @@ -0,0 +1,508 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_user.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions provided by the user. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 28 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_errors.h" + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserGetTime + +Description: Returns the system time in us. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pTime Pointer to structure in which the time is returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserGetTime +UINT32 Oct6100UserGetTime( + IN OUT tPOCT6100_GET_TIME f_pTime ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserMemSet + +Description: Sets f_ulLength bytes pointed to by f_pAddress to f_ulPattern. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pAddress Address in host memory where data should be set. +f_ulPattern Pattern to apply at the address. This value will never + exceed 0xFF. +f_ulLength Length in bytes to set. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserMemSet +UINT32 Oct6100UserMemSet( + IN PVOID f_pAddress, + IN UINT32 f_ulPattern, + IN UINT32 f_ulLength ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserMemCopy + +Description: Copy f_ulLength bytes from f_pSource to f_pDestination. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pDestination Host data destination address. +f_pSource Host data source address. +f_ulLength Length in bytes to copy. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserMemCopy +UINT32 Oct6100UserMemCopy( + IN PVOID f_pDestination, + IN const void *f_pSource, + IN UINT32 f_ulLength ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserCreateSerializeObject + +Description: Creates a serialization object. The serialization object is + seized via the Oct6100UserSeizeSerializeObject function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreate Pointer to structure in which the serialization object's + handle is returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserCreateSerializeObject +UINT32 Oct6100UserCreateSerializeObject( + IN OUT tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDestroySerializeObject + +Description: Destroys the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pDestroy Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDestroySerializeObject +UINT32 Oct6100UserDestroySerializeObject( + IN tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserSeizeSerializeObject + +Description: Seizes the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSeize Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserSeizeSerializeObject +UINT32 Oct6100UserSeizeSerializeObject( + IN tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserReleaseSerializeObject + +Description: Releases the indicated serialization object. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pRelease Pointer to structure containing the handle of the + serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserReleaseSerializeObject +UINT32 Oct6100UserReleaseSerializeObject( + IN tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteApi + +Description: Performs a write access to the chip. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pWriteParams Pointer to structure containing the Params to the + write function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteApi +UINT32 Oct6100UserDriverWriteApi( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteOs + +Description: Performs a write access to the chip. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pWriteParams Pointer to structure containing the Params to the + write function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteOs +UINT32 Oct6100UserDriverWriteOs( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ) +{ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteSmearApi + +Description: Performs a series of write accesses to the chip. The same data + word is written to a series of addresses. The writes begin at + the start address, and the address is incremented by the + indicated amount for each subsequent write. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSmearParams Pointer to structure containing the parameters to the + write smear function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteSmearApi +UINT32 Oct6100UserDriverWriteSmearApi( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteSmearOs + +Description: Performs a series of write accesses to the chip. The same data + word is written to a series of addresses. The writes begin at + the start address, and the address is incremented by the + indicated amount for each subsequent write. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pSmearParams Pointer to structure containing the parameters to the + write smear function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteSmearOs +UINT32 Oct6100UserDriverWriteSmearOs( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteBurstApi + +Description: Performs a series of write accesses to the chip. An array of + data words is written to a series of consecutive addresses. + The writes begin at the start address with element 0 of the + provided array as the data word. The address is incremented by + two for each subsequent write. This function is accessible only + from the API code entity (i.e. not from the APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + write burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteBurstApi +UINT32 Oct6100UserDriverWriteBurstApi( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverWriteBurstOs + +Description: Performs a series of write accesses to the chip. An array of + data words is written to a series of consecutive addresses. + The writes begin at the start address with element 0 of the + provided array as the data word. The address is incremented by + two for each subsequent write. This function is accessible only + from the API code entity (i.e. not from the APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + write burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverWriteBurstOs +UINT32 Oct6100UserDriverWriteBurstOs( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadApi + +Description: Performs a read access to the chip. This function is accessible + only from the API code entity (i.e. not from the APIMI code + entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pReadParams Pointer to structure containing the parameters to the + read function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadApi +UINT32 Oct6100UserDriverReadApi( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadOs + +Description: Performs a read access to the chip. This function is accessible + only from the APIMI code entity (i.e. not from the API code + entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pReadParams Pointer to structure containing the parameters to the + read function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadOs +UINT32 Oct6100UserDriverReadOs( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadBurstApi + +Description: Performs a burst of read accesses to the chip. The first read + is performed at the start address, and the address is + incremented by two for each subsequent read. The data is + retunred in an array provided by the user. This function is + accessible only from the API code entity (i.e. not from the + APIMI code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + read burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadBurstApi +UINT32 Oct6100UserDriverReadBurstApi( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ) +{ + + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100UserDriverReadBurstOs + +Description: Performs a burst of read accesses to the chip. The first read + is performed at the start address, and the address is + incremented by two for each subsequent read. The data is + retunred in an array provided by the user. This function is + accessible only from the APIMI code entity (i.e. not from the + API code entity). + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pBurstParams Pointer to structure containing the parameters to the + read burst function. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100UserDriverReadBurstOs +UINT32 Oct6100UserDriverReadBurstOs( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ) +{ + + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c new file mode 100644 index 0000000..a93db97 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c @@ -0,0 +1,116 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mask_interrupts.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the mask interrupts function. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "oct6100api/oct6100_apimi.h" +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_defines.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100InterruptMask + +Description: The function is used to mask out the interrupt pin of the chip. + This function is used when a deferred procedure call treats the + interrupt (new interrupts must not be generated until the + signaled interrupt is treated). Which chip is to have its + interrupts masked is determined by the mask structure, + f_pInterruptMask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pInterruptMask Pointer to the interrupt masking structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100InterruptMaskDef( + OUT tPOCT6100_INTERRUPT_MASK f_pInterruptMask ) +{ + f_pInterruptMask->ulUserChipIndex = cOCT6100_INVALID_VALUE; + f_pInterruptMask->pProcessContext = NULL; + + + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100InterruptMask( + IN tPOCT6100_INTERRUPT_MASK f_pInterruptMask ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 result; + UINT16 usReadData; + + /* Determine if the chip's interrupt pin is active.*/ + ReadParams.ulReadAddress = 0x210; + ReadParams.pusReadData = &usReadData; + ReadParams.pProcessContext = f_pInterruptMask->pProcessContext; + + ReadParams.ulUserChipId = f_pInterruptMask->ulUserChipIndex; + + result = Oct6100UserDriverReadOs( &ReadParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + if ( (usReadData & 0xFFFF) != 0 ) + { + /* Chip's interrupt pin is active, so mask interrupt pin. */ + ReadParams.ulReadAddress = 0x214; + result = Oct6100UserDriverReadOs( &ReadParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + /* Determine if the chip's interrupt pin is active. */ + WriteParams.pProcessContext = f_pInterruptMask->pProcessContext; + + WriteParams.ulUserChipId = f_pInterruptMask->ulUserChipIndex; + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = (UINT16)( (usReadData & 0xC000) | 0x3FFF ); + + result = Oct6100UserDriverWriteOs( &WriteParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + WriteParams.ulWriteAddress = 0x212; + WriteParams.usWriteData = 0x8000; + + result = Oct6100UserDriverWriteOs( &WriteParams ); + if ( result != cOCT6100_ERR_OK ) + return cOCT6100_ERR_INTRPTS_RW_ERROR; + + return cOCT6100_ERR_OK; + } + + return cOCT6100_ERR_INTRPTS_NOT_ACTIVE; +} diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h new file mode 100644 index 0000000..cd55191 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_channel_priv.h @@ -0,0 +1,529 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_channel.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_channel_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 62 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_PRIV_H__ +#define __OCT6100_CHANNEL_PRIV_H__ + + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* ECHO channel list pointer macros. */ +#define mOCT6100_GET_CHANNEL_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelListOfst ); + +#define mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelListOfst)) + ulIndex; + +#define mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulChannelAllocOfst); + +#define mOCT6100_GET_BIDIR_CHANNEL_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BIDIR_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelListOfst ); + +#define mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BIDIR_CHANNEL )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelListOfst)) + ulIndex; + +#define mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulBiDirChannelAllocOfst ); + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_ECHO_CHAN_INDEX_ +{ + /* Index of the channel in the API echo channel list.*/ + UINT16 usEchoChanIndex; + + /* TSI chariot memory entry for the Rin/Rout stream. */ + UINT16 usRinRoutTsiMemIndex; + + /* TSI chariot memory entry for the Sin/Sout stream. */ + UINT16 usSinSoutTsiMemIndex; + + /* SSPX memory entry. */ + UINT16 usEchoMemIndex; + + /* TDM sample conversion control memory entry. */ + UINT16 usRinRoutConversionMemIndex; + UINT16 usSinSoutConversionMemIndex; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usRinTsstIndex; + UINT16 usSinTsstIndex; + UINT16 usRoutTsstIndex; + UINT16 usSoutTsstIndex; + + /* Index of the phasing TSST */ + UINT16 usPhasingTsstIndex; + + UINT8 fSinSoutCodecActive; + UINT8 fRinRoutCodecActive; + + + /* Extended Tone Detection resources.*/ + UINT16 usExtToneChanIndex; + UINT16 usExtToneMixerIndex; + UINT16 usExtToneTsiIndex; +} tOCT6100_API_ECHO_CHAN_INDEX, *tPOCT6100_API_ECHO_CHAN_INDEX; + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetChannelsEchoSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiChannelsEchoSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ChannelOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); + +UINT32 Oct6100ApiCheckChannelParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiReserveChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiWriteChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ApiUpdateChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ); + +UINT32 Oct6100ChannelCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); + +UINT32 Oct6100ApiAssertChannelParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose, + + IN OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiInvalidateChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usChanIndex ); + +UINT32 Oct6100ApiReleaseChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex ); + +UINT32 Oct6100ChannelModifySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); + +UINT32 Oct6100ApiCheckChannelModify( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pTempChanOpen, + OUT PUINT16 f_pusNewPhasingTsstIndex, + OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiModifyChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewRinTsstIndex, + OUT PUINT16 f_pusNewSinTsstIndex, + OUT PUINT16 f_pusNewRoutTsstIndex, + OUT PUINT16 f_pusNewSoutTsstIndex ); + +UINT32 Oct6100ApiModifyChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + OUT PUINT8 f_pfSinSoutCodecActive, + OUT PUINT8 f_pfRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_uslNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ); + +UINT32 Oct6100ApiModifyChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + IN UINT8 f_fSinSoutCodecActive, + IN UINT8 f_fRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ); + +UINT32 Oct6100ChannelBroadcastTsstAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); + +UINT32 Oct6100ApiCheckChanTsstAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex ); + +UINT32 Oct6100ApiReserveTsstAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewTsstIndex, + OUT PUINT16 f_pusNewTsstEntry ); + +UINT32 Oct6100ApiWriteTsstAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex ); + +UINT32 Oct6100ApiUpdateTsstAddChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex, + IN UINT16 f_usNewTsstEntry ); + +UINT32 Oct6100ChannelBroadcastTsstRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove); + +UINT32 Oct6100ApiAssertChanTsstRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusTsstIndex, + OUT PUINT16 f_pusTsstEntry, + OUT PUINT16 f_pusPrevTsstEntry ); + +UINT32 Oct6100ApiInvalidateTsstRemoveStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulPort, + IN BOOL f_fRemoveAll ); + +UINT32 Oct6100ApiReleaseTsstRemoveResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsstEntry, + IN UINT16 f_usPrevTsstEntry ); + +UINT32 Oct6100ApiChannelGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); + +UINT32 Oct6100ApiReserveEchoEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEchoIndex ); + +UINT32 Oct6100ApiReleaseEchoEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoChanIndex ); + +UINT32 Oct6100ApiCheckTdmConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig ); + +UINT32 Oct6100ApiCheckVqeConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN BOOL f_fEnableToneDisabler ); + +UINT32 Oct6100ApiCheckCodecConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_CODEC f_pCodecConfig, + IN UINT32 f_ulDecoderNumTssts, + OUT PUINT16 f_pusPhasingTsstIndex ); + +UINT32 Oct6100ApiWriteInputTsstControlMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulTsstInputLaw ); + +UINT32 Oct6100ApiWriteOutputTsstControlMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT32 f_ulNumTssts, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiWriteEncoderMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulEncoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulEnableSilenceSuppression, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT16 f_usPhasingTsstIndex, + IN UINT32 f_ulPhasingType, + IN UINT32 f_ulPhase ); + +UINT32 Oct6100ApiWriteDecoderMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usDecoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulPcmLaw, + IN UINT32 f_ulAdpcmNibblePosition ); + + +UINT32 Oct6100ApiClearConversionMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ); + +UINT32 Oct6100ApiWriteVqeMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteVqeNlpMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteVqeAfMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ApiWriteEchoMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ); + +UINT32 Oct6100ApiUpdateOpenStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChanModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChanOpen, + IN tPOCT6100_API_CHANNEL f_pChanEntry ); + + + + + +UINT32 Oct6100ApiRetrieveNlpConfDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulConfigDword ); + +UINT32 Oct6100ApiSaveNlpConfDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + IN UINT32 f_ulConfigDword ); + +UINT32 Oct6100ChannelCreateBiDirSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); + +UINT32 Oct6100ApiCheckChannelCreateBiDirParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + OUT PUINT16 f_pusFirstChanIndex, + OUT PUINT16 f_pusFirstChanExtraTsiIndex, + OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanIndex, + OUT PUINT16 f_pusSecondChanExtraTsiIndex, + OUT PUINT16 f_pusSecondChanSinCopyEventIndex + + ); + +UINT32 Oct6100ApiReserveChannelCreateBiDirResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + OUT PUINT16 f_pusBiDirChanIndex, + IN OUT PUINT16 f_pusFirstChanExtraTsiIndex, + IN OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusFirstChanSoutCopyEventIndex, + IN OUT PUINT16 f_pusSecondChanExtraTsiIndex, + IN OUT PUINT16 f_pusSecondChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ApiWriteChannelCreateBiDirStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ApiUpdateBiDirChannelEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + IN UINT16 f_usBiDirChanIndex, + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ); + +UINT32 Oct6100ChannelDestroyBiDirSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); + +UINT32 Oct6100ApiAssertDestroyBiDirChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir, + IN OUT PUINT16 f_pusBiDirChanIndex, + + IN OUT PUINT16 f_pusFirstChanIndex, + IN OUT PUINT16 f_pusSecondChanIndex ); + +UINT32 Oct6100ApiInvalidateBiDirChannelStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ); + +UINT32 Oct6100ApiReleaseBiDirChannelResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBiDirChanIndex, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ); + +UINT32 Oct6100ApiWriteDebugChanMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ); + +UINT32 Oct6100ApiDebugChannelOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMutePorts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinTsstIndex, + IN UINT16 f_usSinTsstIndex, + IN BOOL f_fCheckBridgeIndex ); + +UINT32 Oct6100ApiSetChannelLevelControl( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearAlcHlcStatusBit ); + +UINT32 Oct6100ApiSetChannelTailConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fModifyOnly ); + +UINT32 Oct6100ChannelMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute ); + +UINT32 Oct6100ApiAssertChannelMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ); + +UINT32 Oct6100ChannelUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); + +UINT32 Oct6100ApiAssertChannelUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ); + +UINT32 Oct6100ApiMuteSinWithFeatures( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN BOOL f_fEnableSinWithFeatures ); + +UINT32 Oct6100ApiMuteChannelPorts( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usPortMask, + IN BOOL f_fMute ); + +INT32 Oct6100ApiOctFloatToDbEnergyByte( + IN UINT8 x ); + +INT32 Oct6100ApiOctFloatToDbEnergyHalf( + IN UINT16 x ); + +UINT16 Oct6100ApiDbAmpHalfToOctFloat( + IN INT32 x ); + +#endif /* __OCT6100_CHANNEL_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h new file mode 100644 index 0000000..46a13e3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_open_priv.h @@ -0,0 +1,264 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_chip_open.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_chip_open_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 63 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_PRIV_H__ +#define __OCT6100_CHIP_OPEN_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_INSTANCE_SIZES_ +{ + /* Each of the following elements indicates the size of the instance memory */ + /* needed by the corresponding API module. All sizes are in bytes. */ + UINT32 ulChannelList; + UINT32 ulChannelAlloc; + + UINT32 ulTsiCnctList; + UINT32 ulTsiCnctAlloc; + + UINT32 ulMixerEventList; + UINT32 ulMixerEventAlloc; + + UINT32 ulBiDirChannelList; + UINT32 ulBiDirChannelAlloc; + + UINT32 ulAdpcmChannelList; + UINT32 ulAdpcmChannelAlloc; + + UINT32 ulSoftBufPlayoutEventsBuffer; + + UINT32 ulCopyEventList; + UINT32 ulCopyEventAlloc; + + UINT32 ulConfBridgeList; + UINT32 ulConfBridgeAlloc; + + UINT32 ulFlexConfParticipantsList; + UINT32 ulFlexConfParticipantsAlloc; + + UINT32 ulPlayoutBufList; + UINT32 ulPlayoutBufAlloc; + UINT32 ulPlayoutBufMemoryNodeList; + + + + UINT32 ulSoftToneEventsBuffer; + + UINT32 ulPhasingTsstList; + UINT32 ulPhasingTsstAlloc; + + UINT32 ulConversionMemoryAlloc; + + UINT32 ulTsiMemoryAlloc; + UINT32 ulTsstAlloc; + + UINT32 ulTsstEntryList; + UINT32 ulTsstEntryAlloc; + + UINT32 ulRemoteDebugList; + UINT32 ulRemoteDebugTree; + UINT32 ulRemoteDebugPktCache; + UINT32 ulRemoteDebugDataBuf; + + /* Memory consumed by static members of API instance. */ + UINT32 ulApiInstStatic; + + /* Total memory size for API instance. */ + UINT32 ulApiInstTotal; + +} tOCT6100_API_INSTANCE_SIZES, *tPOCT6100_API_INSTANCE_SIZES; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pOpenChip ); + +UINT32 Oct6100ApiCheckImageFileHeader( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ); + +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pOpenChip ); + +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pInstance ); + +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstanceSizes ); + +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstanceSizes ); + +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pInstance ); + +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMapExternalMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiWriteH100Registers( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ); + +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ); + +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ); + +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ); + +UINT32 Oct6100ApiCreateEgoEntry( + IN OUT UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + IN UINT32 f_aulEntry[ 2 ] ); + + + + + +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ); + +UINT32 Oct6100ProductionBistSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PRODUCTION_BIST f_pProductionBist ); + +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ); + +UINT32 Oct6100ApiReadCapacity( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiCpuRegisterBistReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiBootFc2PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiProgramFc1PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiClearInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); +#endif /* __OCT6100_CHIP_OPEN_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h new file mode 100644 index 0000000..6c36163 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_chip_stats_priv.h @@ -0,0 +1,55 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_chip_stats.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_chip_stats_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_PRIV_H__ +#define __OCT6100_CHIP_STATS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiChipStatsSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ChipGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +#endif /* __OCT6100_CHIP_STATS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h new file mode 100644 index 0000000..071e645 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h @@ -0,0 +1,318 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_conf_bridge.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_conf_bridge_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 30 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_PRIV_H__ +#define __OCT6100_CONF_BRIDGE_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_CONF_BRIDGE_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_CONF_BRIDGE )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeListOfst); + +#define mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_CONF_BRIDGE )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeListOfst)) + ulIndex; + +#define mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulConfBridgeAllocOfst); + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_FLEX_CONF_PARTICIPANT )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantListOfst); + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_FLEX_CONF_PARTICIPANT )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantListOfst)) + ulIndex; + +#define mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulFlexConfParticipantAllocOfst); + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetConfBridgeSwSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiConfBridgeSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst ); + +UINT32 Oct6100ConfBridgeOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ApiCheckBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ApiReserveBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiUpdateBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); + +UINT32 Oct6100ApiAssertBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiReleaseBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeChanAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); + +UINT32 Oct6100ApiCheckBridgeAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfMute, + OUT PUINT32 f_pulInputPort, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT32 f_pulListenerMaskIndex, + OUT PUINT32 f_pulListenerMask, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusTapChannelIndex ); + +UINT32 Oct6100ApiReserveBridgeAddResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fFlexibleConfBridge, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex, + OUT PUINT16 f_pusTapBridgeIndex ); + +UINT32 Oct6100ApiBridgeEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChannelIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulInputPort, + IN UINT8 f_fMute, + IN UINT32 f_ulListenerMaskIndex, + IN UINT32 f_ulListenerMask, + IN UINT8 f_fTap, + IN UINT16 f_usTapBridgeIndex, + IN UINT16 f_usTapChanIndex ); + +UINT32 Oct6100ApiBridgeAddParticipantToChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT16 f_usLoadOrAccumulateEventIndex, + IN UINT16 f_usStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT32 f_ulSourceInputPort, + IN UINT32 f_ulDestinationInputPort ); + +UINT32 Oct6100ConfBridgeChanRemoveSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); + +UINT32 Oct6100ApiCheckChanRemoveParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT8 f_pfFlexibleConfBridge, + OUT PUINT8 f_pfTap, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT16 f_pusCopyEventIndex ); + +UINT32 Oct6100ApiReleaseChanEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex ); + +UINT32 Oct6100ApiBridgeEventRemove ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChannelIndex, + IN UINT8 f_fFlexibleConfBridge, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT16 f_usCopyEventIndex, + IN UINT8 f_fTap ); + +UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usSourceChannelIndex, + IN UINT16 f_usDestinationChannelIndex, + IN UINT8 f_fRemovePermanently ); + +UINT32 Oct6100ConfBridgeChanMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); + +UINT32 Oct6100ApiUpdateBridgeMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ); + +UINT32 Oct6100ApiCheckBridgeMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ); + +UINT32 Oct6100ConfBridgeChanUnMuteSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); + +UINT32 Oct6100ApiCheckBridgeUnMuteParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusLoadEventIndex, + OUT PUINT16 f_pusSubStoreEventIndex, + OUT PUINT8 f_pfFlexibleConfBridge ); + +UINT32 Oct6100ApiUpdateBridgeUnMuteResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usLoadEventIndex, + IN UINT16 f_usSubStoreEventIndex, + IN UINT8 f_fFlexibleConfBridge ); + +UINT32 Oct6100ConfBridgeDominantSpeakerSetSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); + +UINT32 Oct6100ApiCheckBridgeDominantSpeakerParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex ); + +UINT32 Oct6100ApiUpdateBridgeDominantSpeakerResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChanIndex, + IN UINT16 f_usBridgeIndex ); + +UINT32 Oct6100ConfBridgeMaskChangeSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); + +UINT32 Oct6100ApiCheckBridgeMaskChangeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange, + OUT PUINT16 f_pusChannelIndex, + OUT PUINT16 f_pusBridgeIndex, + OUT PUINT32 f_pulNewParticipantMask ); + +UINT32 Oct6100ApiUpdateMaskModifyResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ); + +UINT32 Oct6100ApiBridgeUpdateMask( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usChanIndex, + IN UINT32 f_ulNewListenerMask ); + +UINT32 Oct6100ConfBridgeGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); + +UINT32 Oct6100ApiReserveBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusConfBridgeIndex ); + +UINT32 Oct6100ApiReleaseBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usConfBridgeIndex ); + +UINT32 Oct6100ApiGetPrevLastSubStoreEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usBridgeIndex, + IN UINT16 f_usBridgeFirstLoadEventPtr, + OUT PUINT16 f_pusLastSubStoreEventIndex ); + +UINT32 Oct6100ApiGetPreviousEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usStartIndex, + IN UINT16 f_usSearchedIndex, + IN UINT16 f_usLoopCnt, + OUT PUINT16 f_pusPreviousIndex ); + +UINT32 Oct6100ApiBridgeSetDominantSpeaker( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usChannelIndex, + IN UINT16 f_usDominantSpeakerIndex ); + +UINT32 Oct6100ApiReserveFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT PUINT16 f_pusParticipantIndex ); + +UINT32 Oct6100ApiReleaseFlexConfParticipantEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN UINT16 f_usParticipantIndex ); + +#endif /* __OCT6100_CONF_BRIDGE_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h new file mode 100644 index 0000000..44a9a21 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_debug_priv.h @@ -0,0 +1,58 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_debug.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_debug_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_PRIV_H__ +#define __OCT6100_DEBUG_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100DebugSelectChannelSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan, + IN BOOL f_fCheckChannelRecording ); + +UINT32 Oct6100DebugGetDataSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); + +#endif /* __OCT6100_DEBUG_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h new file mode 100644 index 0000000..fd3980a --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_events_priv.h @@ -0,0 +1,82 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_events.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_events_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_PRIV_H__ +#define __OCT6100_EVENTS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftBuf ) \ + pSoftBuf = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst ); + +#define mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftBuf ) \ + pSoftBuf = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst ); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetEventsSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100EventGetToneSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); + +UINT32 Oct6100ApiTransferToneEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ); + + + +UINT32 Oct6100BufferPlayoutGetEventSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); + +UINT32 Oct6100BufferPlayoutTransferEvents( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulResetBuf ); + +UINT32 Oct6100BufferPlayoutCheckForSpecificEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulChannelPort, + IN BOOL f_fSaveToSoftBuffer, + OUT PBOOL f_pfEventDetected ); + +#endif /* __OCT6100_EVENTS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h new file mode 100644 index 0000000..d29f1b0 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_interrupts_priv.h @@ -0,0 +1,158 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_interrupts.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_interrupts_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_PRIV_H__ +#define __OCT6100_INTERRUPTS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_INTRPT_ENABLE_TIME( \ + ulRegMclkTimeHigh, \ + ulRegMclkTimeLow, \ + ulIntrptState, \ + ulIntrptEnableMclkHigh, \ + ulIntrptEnableMclkLow, \ + ulIntrptTimeoutMclk, \ + ulTimeDiff ) \ + if ( ulIntrptState == cOCT6100_INTRPT_WILL_TIMEOUT ) \ + { \ + ulIntrptEnableMclkLow = ulRegMclkTimeLow + ulIntrptTimeoutMclk; \ + if ( ulIntrptEnableMclkLow < ulRegMclkTimeLow ) \ + ulIntrptEnableMclkHigh = (ulRegMclkTimeHigh + 1) & 0xFF; \ + else \ + ulIntrptEnableMclkHigh = ulRegMclkTimeHigh; \ + \ + ulIntrptState = cOCT6100_INTRPT_IN_TIMEOUT; \ + } \ + \ + if ( ulIntrptEnableMclkLow < ulRegMclkTimeLow ) \ + { \ + ulTimeDiff = (cOCT6100_FFFFFFFF - ulRegMclkTimeLow - 1) + ulIntrptEnableMclkLow; \ + } \ + else \ + { \ + ulTimeDiff = ulIntrptEnableMclkLow - ulRegMclkTimeLow; \ + } + +#define mOCT6100_CHECK_INTRPT_TIMEOUT( \ + ulRegMclkTimePlus5MsHigh, \ + ulRegMclkTimePlus5MsLow, \ + ulIntrptDisableMclkHigh, \ + ulIntrptDisableMclkLow, \ + ulIntrptEnableMclkHigh, \ + ulIntrptEnableMclkLow, \ + ulIntrptState, \ + fIntrptChange ) \ + /* Branch depending on whether the disable time is lesser or greater than the timeout time. */ \ + if ( ulIntrptDisableMclkLow < ulIntrptEnableMclkLow ) \ + { \ + /* Disable period is over if mclk is greater than timeout time or less than disabled time. */ \ + if ( ulRegMclkTimePlus5MsLow > ulIntrptEnableMclkLow || \ + ulRegMclkTimePlus5MsLow < ulIntrptDisableMclkLow || \ + ulRegMclkTimePlus5MsHigh != ulIntrptEnableMclkHigh ) \ + { \ + fIntrptChange = TRUE; \ + ulIntrptState = cOCT6100_INTRPT_ACTIVE; \ + } \ + } \ + else \ + { \ + /* Disable period is over if mclk is lesser than disable time and greater than timeout. */ \ + if ( (ulRegMclkTimePlus5MsLow > ulIntrptEnableMclkLow && ulRegMclkTimePlus5MsLow < ulIntrptDisableMclkLow) || \ + (ulRegMclkTimePlus5MsHigh != ulIntrptDisableMclkHigh && ulRegMclkTimePlus5MsHigh != ulIntrptEnableMclkHigh) ) \ + { \ + fIntrptChange = TRUE; \ + ulIntrptState = cOCT6100_INTRPT_ACTIVE; \ + } \ + } + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiIsrSwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiIsrHwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig ); + +UINT32 Oct6100InterruptConfigureSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_CONFIGURE f_pIntrptConfig, + IN BOOL f_fCheckParams ); + +UINT32 Oct6100ApiClearEnabledInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100InterruptServiceRoutineSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +UINT32 Oct6100ApiWriteIeRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReadIntrptRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags, + IN UINT32 f_ulRegister210h ); + +UINT32 Oct6100ApiUpdateIntrptStates( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +UINT32 Oct6100ApiWriteIntrptRegs( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReadChipMclkTime( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiUpdateIntrptTimeouts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiScheduleNextMclkIntrpt( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIntrptToSet ); + +UINT32 Oct6100ApiScheduleNextMclkIntrptSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCheckProcessorState( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +#endif /* __OCT6100_INTERRUPTS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h new file mode 100644 index 0000000..77eed5e --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_memory_priv.h @@ -0,0 +1,97 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_memory_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_memory.c. All elements defined in this + file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 17 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MEMORY_PRIV_H__ +#define __OCT6100_MEMORY_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* TSI allocation pointer macros. */ +#define mOCT6100_GET_TSI_MEMORY_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiMemoryAllocOfst ); + +/* Conversion memory allocation pointer macros. */ +#define mOCT6100_GET_CONVERSION_MEMORY_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulConversionMemoryAllocOfst ); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetMemorySwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiBufferPlayoutMemorySwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiReserveBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulNewNode ); + +UINT32 Oct6100ApiReleaseBufferPlayoutMemoryNode( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulOldNode ); + +UINT32 Oct6100ApiReserveBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulSize, + OUT PUINT32 f_pulMallocAddress ); + +UINT32 Oct6100ApiReleaseBufferPlayoutMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMallocAddress ); + +UINT32 Oct6100ApiReserveTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiMemIndex ); + +UINT32 Oct6100ApiReleaseTsiMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusConversionMemIndex ); + +UINT32 Oct6100ApiReleaseConversionMemEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ); + +#endif /* __OCT6100_MEMORY_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h new file mode 100644 index 0000000..70d2fc0 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h @@ -0,0 +1,277 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_miscellaneous_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_miscellaneous.c. All elements defined in + this file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 20 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MISCELLANEOUS_PRIV_H__ +#define __OCT6100_MISCELLANEOUS_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/*---------------------------------------------------------------------------*\ + Macros used to shell the user function calls. These macros are used to + assert that the user does not change any of the members of the function's + parameter structure, as required and indicated in the API specification. + Ofcourse, these macros make the code heavier and thus slower. That is why + there is a compile option for disabling the extra checking. These can be + very helpful tools in debugging. +\*---------------------------------------------------------------------------*/ + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulWriteAddress; \ + UINT16 _usWriteData; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = WriteParams.pProcessContext; \ + _ulUserChipId = WriteParams.ulUserChipId; \ + _ulWriteAddress = WriteParams.ulWriteAddress; \ + _usWriteData = WriteParams.usWriteData; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteApi( &WriteParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( WriteParams.pProcessContext != _pProcessContext || \ + WriteParams.ulUserChipId != _ulUserChipId || \ + WriteParams.ulWriteAddress != _ulWriteAddress || \ + WriteParams.ulWriteAddress != _ulWriteAddress || \ + WriteParams.usWriteData != _usWriteData ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteApi( &WriteParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT16 _usWriteData; \ + UINT32 _ulWriteLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = SmearParams.pProcessContext; \ + _ulUserChipId = SmearParams.ulUserChipId; \ + _usWriteData = SmearParams.usWriteData; \ + _ulWriteLength = SmearParams.ulWriteLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteSmearApi( &SmearParams ); \ + \ + /* Check if user changed members of function's paraeter structure. */ \ + if ( SmearParams.pProcessContext != _pProcessContext || \ + SmearParams.ulUserChipId != _ulUserChipId || \ + SmearParams.usWriteData != _usWriteData || \ + SmearParams.ulWriteLength != _ulWriteLength) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_SMEAR_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteSmearApi( &SmearParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulWriteAddress; \ + PUINT16 _pusWriteData; \ + UINT32 _ulWriteLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = BurstParams.pProcessContext; \ + _ulUserChipId = BurstParams.ulUserChipId; \ + _ulWriteAddress = BurstParams.ulWriteAddress; \ + _pusWriteData = BurstParams.pusWriteData; \ + _ulWriteLength = BurstParams.ulWriteLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverWriteBurstApi( &BurstParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( BurstParams.pProcessContext != _pProcessContext || \ + BurstParams.ulUserChipId != _ulUserChipId || \ + BurstParams.ulWriteAddress != _ulWriteAddress || \ + BurstParams.pusWriteData != _pusWriteData || \ + BurstParams.ulWriteLength != _ulWriteLength ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_WRITE_BURST_API; \ +} +#else +#define mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) \ + ulResult = Oct6100UserDriverWriteBurstApi( &BurstParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulReadAddress; \ + PUINT16 _pusReadData; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = ReadParams.pProcessContext; \ + _ulUserChipId = ReadParams.ulUserChipId; \ + _ulReadAddress = ReadParams.ulReadAddress; \ + _pusReadData = ReadParams.pusReadData; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverReadApi( &ReadParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( ReadParams.pProcessContext != _pProcessContext || \ + ReadParams.ulUserChipId != _ulUserChipId || \ + ReadParams.ulReadAddress != _ulReadAddress || \ + ReadParams.pusReadData != _pusReadData ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_READ_API; \ +} +#else +#define mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) \ + ulResult = Oct6100UserDriverReadApi( &ReadParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + + +#ifndef cOCT6100_REMOVE_USER_FUNCTION_CHECK +#define mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) \ +{ \ + PVOID _pProcessContext; \ + UINT32 _ulUserChipId; \ + UINT32 _ulReadAddress; \ + PUINT16 _pusReadData; \ + UINT32 _ulReadLength; \ + \ + /* Store the data that is to be passed to the user. */ \ + _pProcessContext = BurstParams.pProcessContext; \ + _ulUserChipId = BurstParams.ulUserChipId; \ + _ulReadAddress = BurstParams.ulReadAddress; \ + _pusReadData = BurstParams.pusReadData; \ + _ulReadLength = BurstParams.ulReadLength; \ + \ + /* Call user function. */ \ + ulResult = Oct6100UserDriverReadBurstApi( &BurstParams ); \ + \ + /* Check if user changed members of function's parameter structure. */ \ + if ( BurstParams.pProcessContext != _pProcessContext || \ + BurstParams.ulUserChipId != _ulUserChipId || \ + BurstParams.ulReadAddress != _ulReadAddress || \ + BurstParams.pusReadData != _pusReadData || \ + BurstParams.ulReadLength != _ulReadLength ) \ + ulResult = cOCT6100_ERR_FATAL_DRIVER_READ_BURST_API; \ +} +#else +#define mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ) \ + ulResult = Oct6100UserDriverReadBurstApi( &BurstParams ); +#endif /* cOCT6100_REMOVE_USER_FUNCTION_CHECK */ + +#define mOCT6100_ASSIGN_USER_READ_WRITE_OBJ( f_pApiInst, Params ) + +#define mOCT6100_CREATE_FEATURE_MASK( f_ulFieldSize, f_ulFieldBitOffset, f_pulFieldMask ) \ +{ \ + (*f_pulFieldMask) = ( 1 << f_ulFieldSize ); \ + (*f_pulFieldMask) --; \ + (*f_pulFieldMask) <<= f_ulFieldBitOffset; \ +} + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiWaitForTime( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_aulWaitTime[ 2 ] ); + +UINT32 Oct6100ApiWaitForPcRegisterBit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulPcRegAdd, + IN UINT32 f_ulPcBitNum, + IN UINT32 f_ulValue, + IN UINT32 f_ulTimeoutUs, + OUT PBOOL f_pfBitEqual ); + +UINT32 Oct6100ApiWriteDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + IN UINT32 f_ulWriteData ); + +UINT32 Oct6100ApiReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ); + +VOID Oct6100ApiCreateFeatureMask( + IN UINT32 f_ulFieldSize, + IN UINT32 f_ulFieldBitOffset, + OUT PUINT32 f_pulFieldMask ); + +unsigned char const *Oct6100ApiStrStr( + IN unsigned char const *f_pszSource, + IN unsigned char const *f_pszString, + IN unsigned char const *f_pszLastCharPtr ); + +UINT32 Oct6100ApiStrLen( + IN unsigned char const *f_pszString ); + +UINT32 Oct6100ApiAsciiToHex( + IN UINT8 f_chCharacter, + IN PUINT32 f_pulValue ); + +UINT8 Oct6100ApiHexToAscii( + IN UINT32 f_ulNumber ); + +UINT32 Oct6100ApiRand( + IN UINT32 f_ulRange ); + +UINT32 oct6100_retrieve_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 *f_pulConfigDword); + +UINT32 oct6100_save_nlp_conf_dword(tPOCT6100_INSTANCE_API f_pApiInst, + tPOCT6100_API_CHANNEL f_pChanEntry, + UINT32 f_ulAddress, + UINT32 f_ulConfigDword); + +#endif /* __OCT6100_MISCELLANEOUS_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h new file mode 100644 index 0000000..b6a7a34 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_mixer_priv.h @@ -0,0 +1,150 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_mixer.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_mixer_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_PRIV_H__ +#define __OCT6100_MIXER_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_MIXER_EVENT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_MIXER_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventListOfst); + +#define mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_MIXER_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventListOfst)) + ulIndex; + +#define mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulMixerEventAllocOfst); + +#define mOCT6100_GET_COPY_EVENT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_COPY_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventListOfst); + +#define mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_COPY_EVENT )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventListOfst)) + ulIndex; + +#define mOCT6100_GET_COPY_EVENT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulCopyEventAllocOfst); + +/***************************** TYPES ***************************************/ + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetMixerSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiMixerSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiMixerEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100ApiMixerEventRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType ); + +UINT32 Oct6100MixerCopyEventCreateSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); + +UINT32 Oct6100ApiCheckCopyEventCreateParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + OUT PUINT16 f_pusSourceChanIndex, + OUT PUINT16 f_pusDestinationChanIndex ); + +UINT32 Oct6100ApiReserveCopyEventCreateResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusCopyEntryIndex, + IN OUT PUINT16 f_pusCopyEventIndex ); + +UINT32 Oct6100ApiWriteCopyEventCreateStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100ApiUpdateCopyEventCreateEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ); + +UINT32 Oct6100MixerCopyEventDestroySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); + +UINT32 Oct6100ApiAssertCopyEventDestroyParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy, + IN OUT PUINT16 f_pusCopyEventIndex, + IN OUT PUINT16 f_pusMixerEventIndex ); + +UINT32 Oct6100ApiInvalidateCopyEventStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ); + +UINT32 Oct6100ApiReleaseCopyEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ); + +UINT32 Oct6100ApiReserveMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ); + +UINT32 Oct6100ApiReleaseMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ); + +UINT32 Oct6100ApiGetFreeMixerEventCnt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulFreeEventCnt ); + +UINT32 Oct6100ApiReserveCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ); + +UINT32 Oct6100ApiReleaseCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ); +#endif /* __OCT6100_MIXER_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h new file mode 100644 index 0000000..e17ab8b --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h @@ -0,0 +1,114 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_phasing_tsst.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_phasing_tsst_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_PRIV_H__ +#define __OCT6100_PHASING_TSST_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_PHASING_TSST_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_PHASING_TSST )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstListOfst); + +#define mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_PHASING_TSST )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstListOfst)) + ulIndex; + +#define mOCT6100_GET_PHASING_TSST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulPhasingTsstAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetPhasingTsstSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiPhasingTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100PhasingTsstOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100ApiCheckPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100ApiReservePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ); + +UINT32 Oct6100ApiWritePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100ApiUpdatePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen, + IN UINT16 f_usPhasingIndex, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100PhasingTsstCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); + +UINT32 Oct6100ApiAssertPhasingParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose, + OUT PUINT16 f_pusPhasingIndex, + OUT PUINT16 f_pusTsstIndex ); + +UINT32 Oct6100ApiInvalidatePhasingStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex ); + +UINT32 Oct6100ApiReleasePhasingResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT UINT16 f_usPhasingIndex ); + +UINT32 Oct6100ApiReservePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusPhasingIndex ); + +UINT32 Oct6100ApiReleasePhasingEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usPhasingIndex ); + +#endif /* #ifndef cOCT6100_REMOVE_PHASING_TSST */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h new file mode 100644 index 0000000..a69e942 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_playout_buf_priv.h @@ -0,0 +1,201 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_playout_buf.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_playout_buf_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_PRIV_H__ +#define __OCT6100_PLAYOUT_BUF_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* Playout buffer list pointer macros. */ +#define mOCT6100_GET_BUFFER_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BUFFER )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufListOfst ); + +#define mOCT6100_GET_BUFFER_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BUFFER )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufListOfst)) + ulIndex; + +#define mOCT6100_GET_BUFFER_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetPlayoutBufferSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiPlayoutBufferSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100BufferLoadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex ); + +UINT32 Oct6100BufferLoadBlockInitSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); + +UINT32 Oct6100BufferLoadBlockSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); + +UINT32 Oct6100ApiCheckBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fCheckBufferPtr ); + +UINT32 Oct6100ApiCheckBufferLoadBlockParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock, + OUT PUINT32 f_pulBufferBase ); + +UINT32 Oct6100ApiReserveBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN BOOL f_fReserveListStruct, + IN UINT32 f_ulBufIndex, + OUT PUINT32 f_pulBufIndex, + OUT PUINT32 f_pulBufBase ); + +UINT32 Oct6100ApiWriteBufferInMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufferBase, + IN UINT32 f_ulBufferLength, + IN PUINT8 f_pbyBuffer ); + +UINT32 Oct6100ApiUpdateBufferEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad, + IN UINT32 f_ulBufIndex, + IN UINT32 f_ulBufBase ); + +UINT32 Oct6100BufferUnloadSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + IN BOOL f_fReleaseListStruct ); + +UINT32 Oct6100ApiAssertBufferParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_UNLOAD f_pBufferUnload, + OUT PUINT32 f_pulBufIndex, + OUT PUINT32 f_pulBufBase ); + +UINT32 Oct6100ApiReleaseBufferResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufIndex, + IN UINT32 f_ulBufBase, + IN BOOL f_fReleaseListStruct ); + +UINT32 Oct6100BufferPlayoutAddSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); + +UINT32 Oct6100ApiCheckPlayoutAddParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex ); + +UINT32 Oct6100ApiWriteBufferAddStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ); + +UINT32 Oct6100BufferPlayoutStartSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulPlayoutStopEventType ); + +UINT32 Oct6100ApiCheckPlayoutStartParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulBufferIndex, + OUT PBOOL f_pfNotifyOnPlayoutStop, + OUT PUINT32 f_pulUserEventId, + OUT PBOOL f_pfAllowStartIfActive ); + +UINT32 Oct6100ApiWriteChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex, + IN BOOL f_fNotifyOnPlayoutStop, + IN UINT32 f_ulUserEventId, + IN BOOL f_fAllowStartIfActive, + IN UINT32 f_ulPlayoutStopEventType ); + +UINT32 Oct6100ApiUpdateChanPlayoutEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulBufferIndex ); + +UINT32 Oct6100BufferPlayoutStopSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); + +UINT32 Oct6100ApiAssertPlayoutStopParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT16 f_pusEchoMemIndex ); + +UINT32 Oct6100ApiInvalidateChanPlayoutStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex, + IN UINT16 f_usEchoMemIndex + + ); + +UINT32 Oct6100ApiReleaseChanPlayoutResources ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop, + IN UINT32 f_ulChannelIndex ); + +UINT32 Oct6100ApiReserveBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulBufIndex ); + +UINT32 Oct6100ApiReleaseBufPlayoutListEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBufIndex ); + +#endif /* __OCT6100_PLAYOUT_BUF_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h new file mode 100644 index 0000000..c599ee9 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_remote_debug_priv.h @@ -0,0 +1,144 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_remote_debug.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_remote_debug_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_PRIV_H__ +#define __OCT6100_REMOTE_DEBUG_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_REMOTE_DEBUG_LIST_ENTRY_PNT( pSharedInfo, ulIndex, pEntry ) \ + pEntry = ( tPOCT6100_API_REMOTE_DEBUG_SESSION )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulSessionListOfst) + ulIndex; + +#define mOCT6100_GET_REMOTE_DEBUG_TREE_PNT( pSharedInfo, pList ) \ + pList = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst); + +#define mOCT6100_GET_REMOTE_DEBUG_DATA_BUF_PNT( pSharedInfo, pulDataBuf ) \ + pulDataBuf = ( PUINT16 )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulDataBufOfst); + +#define mOCT6100_GET_REMOTE_DEBUG_SESSION_PKT_CACHE_PNT( pSharedInfo, pulPktCache, ulSessionIndex ) \ + pulPktCache = ( PUINT32 )(( PUINT8 )pSharedInfo + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst) + (ulSessionIndex * (cOCTRPC_MAX_PACKET_BYTE_LENGTH / 4)); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetRemoteDebugSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiRemoteDebuggingSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiCheckEndianDetectField( + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + IN UINT32 f_ulPktLengthDword ); + +VOID Oct6100ApiCalculateChecksum( + IN PUINT32 f_pulPktPayload, + IN UINT32 f_ulPktLengthDword, + OUT PUINT32 f_pulChecksum ); + +VOID Oct6100ApiFormResponsePkt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulPktLengthDword, + IN BOOL f_fRetryPktResponse, + IN BOOL f_fReplaceProtocolNum, + IN BOOL f_fReplaceInterfaceType, + IN BOOL f_fReplaceInterfaceVersion, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulParsingErrorValue, + IN UINT32 f_ulPayloadDwordIndex, + IN UINT32 f_ulChecksum ); + +UINT32 Oct6100ApiCheckPktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN OUT PUINT32 f_pulRspPktPayload, + IN UINT32 f_ulSessionIndex, + IN UINT32 f_ulPktLengthDword, + IN UINT32 f_ulChecksum ); + +VOID Oct6100ApiExecutePktCommands( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulRcvPktPayload, + IN UINT32 f_ulPktLengthDword ); + +UINT32 Oct6100ApiCheckSessionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCTRPC_OGRDTP_HEADER f_pOgrdtpHeader, + OUT PUINT32 f_pulSessionIndex ); + +VOID Oct6100ApiRpcReadWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcReadBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcReadArray( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteWord( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteSmear( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcWriteBurst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcSetHotChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcGetDebugChanIndex( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader ); + +VOID Oct6100ApiRpcDisconnect( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCTRPC_COMMAND_HEADER f_pCmndHeader, + IN OUT UINT32 f_ulSessionNumber ); + +#endif /* __OCT6100_REMOTE_DEBUG_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h new file mode 100644 index 0000000..e1982bd --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tlv_priv.h @@ -0,0 +1,515 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tlv.c. All elements defined in this + file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 58 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TLV_PRIV_H__ +#define __OCT6100_TLV_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* List of TLV types supported by this API. */ +#define cOCT6100_TLV_TYPE_VERSION_NUMBER 0 +#define cOCT6100_TLV_TYPE_CUSTOMER_PROJECT_ID 2 + +#define cOCT6100_TLV_TYPE_POUCH_BASE_ADDRESS 3 +#define cOCT6100_TLV_TYPE_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_TYPE_CH_MAIN_SIZE 5 +#define cOCT6100_TLV_TYPE_CH_MAIN_IO_OFFSET 6 +#define cOCT6100_TLV_TYPE_CH_MAIN_ZCB_OFFSET 7 +#define cOCT6100_TLV_TYPE_CH_MAIN_ZCB_SIZE 8 +#define cOCT6100_TLV_TYPE_CH_MAIN_XCB_OFFSET 9 +#define cOCT6100_TLV_TYPE_CH_MAIN_XCB_SIZE 10 +#define cOCT6100_TLV_TYPE_CH_MAIN_YCB_OFFSET 11 +#define cOCT6100_TLV_TYPE_CH_MAIN_YCB_SIZE 12 +#define cOCT6100_TLV_TYPE_FREE_MEM_BASE_ADDRESS 13 +#define cOCT6100_TLV_TYPE_CH_ROOT_CONF_OFFSET 14 + +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_OFFSET 15 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_ZPO_SIZE 16 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_OFFSET 17 +#define cOCT6100_TLV_TYPE_POA_CH_MAIN_YPO_SIZE 18 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZWP 19 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZIS 20 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_ZSP 21 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YWP 22 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YIS 23 +#define cOCT6100_TLV_TYPE_POA_BOFF_RW_YSP 24 +#define cOCT6100_TLV_TYPE_POA_BOFF_RO_ZRP 25 +#define cOCT6100_TLV_TYPE_POA_BOFF_RO_YRP 26 + +#define cOCT6100_TLV_TYPE_CNR_CONF_BOFF_RW_ENABLE 27 +#define cOCT6100_TLV_TYPE_ANR_CONF_BOFF_RW_ENABLE 28 + +#define cOCT6100_TLV_TYPE_HZ_CONF_BOFF_RW_ENABLE 29 +#define cOCT6100_TLV_TYPE_HX_CONF_BOFF_RW_ENABLE 30 + +#define cOCT6100_TLV_TYPE_LCA_Z_CONF_BOFF_RW_GAIN 31 +#define cOCT6100_TLV_TYPE_LCA_Y_CONF_BOFF_RW_GAIN 32 + +#define cOCT6100_TLV_TYPE_CNA_CONF_BOFF_RW_ENABLE 33 + +#define cOCT6100_TLV_TYPE_NOA_CONF_BOFF_RW_ENABLE 34 + +#define cOCT6100_TLV_TYPE_VFA_CONF_BOFF_RW_ENABLE 35 + +#define cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 37 + +#define cOCT6100_TLV_TYPE_STATSA_MAIN_IO_BOFF_RO_EPC 38 +#define cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_INST 39 +#define cOCT6100_TLV_TYPE_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 40 + +#define cOCT6100_TLV_TYPE_DIS_CONF_BOFF_RW_ENABLE 41 +#define cOCT6100_TLV_TYPE_TDM_CONF_BOFF_RW_ENABLE 42 +#define cOCT6100_TLV_TYPE_NT_CONF_BOFF_RW_ENABLE 43 +#define cOCT6100_TLV_TYPE_AEC_CONF_BOFF_RW_ENABLE 44 + +#define cOCT6100_TLV_TYPE_PCM_LEAK_CONF_BOFF_RW 45 +#define cOCT6100_TLV_TYPE_DEFAULT_ERL_CONF_BOFF_RW 46 +#define cOCT6100_TLV_TYPE_TONE_REM_CONF_BOFF_RW_ENABLE 47 + +#define cOCT6100_TLV_TYPE_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 48 + +#define cOCT6100_TLV_TYPE_NLP_CONV_CAP_CONF_BOFF_RW 49 +#define cOCT6100_TLV_TYPE_MATRIX_EVENT_SIZE 50 +#define cOCT6100_TLV_TYPE_CNR_RW_ENABLE 51 +#define cOCT6100_TLV_TYPE_MAX_TAIL_LENGTH_RW_ENABLE 52 + +#define cOCT6100_TLV_TYPE_PLAYOUT_ENABLE 53 +#define cOCT6100_TLV_TYPE_DOMINANT_SPEAKER_BOFF_RW_ENABLE 54 + +#define cOCT6100_TLV_TYPE_ANR_RW_ENABLE 57 +#define cOCT6100_TLV_TYPE_TONE_REMOVAL_ENABLE 58 +#define cOCT6100_TLV_TYPE_MUSIC_PROTECTION_RW_ENABLE 59 +#define cOCT6100_TLV_TYPE_TAIL_DISP_CONF_BOFF_RW_ENABLE 60 +#define cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_ENABLE 62 + +#define cOCT6100_TLV_TYPE_AEC_DEFAULT_ERL_BOFF 64 + +#define cOCT6100_TLV_TYPE_Z_ALC_TARGET_BOFF 65 +#define cOCT6100_TLV_TYPE_Y_ALC_TARGET_BOFF 66 +#define cOCT6100_TLV_TYPE_Z_HLC_TARGET_BOFF 67 +#define cOCT6100_TLV_TYPE_Y_HLC_TARGET_BOFF 68 +#define cOCT6100_TLV_TYPE_ALC_HLC_STATUS_BOFF 69 + +#define cOCT6100_TLV_TYPE_Z_PLAYOUT_HARD_SKIP_BOFF 70 +#define cOCT6100_TLV_TYPE_Y_PLAYOUT_HARD_SKIP_BOFF 71 + +#define cOCT6100_TLV_TYPE_AFT_FIELD_BOFF 72 + +#define cOCT6100_TLV_TYPE_VOICE_DETECTED_STAT_BOFF 73 + +#define cOCT6100_TLV_TYPE_GAIN_APPLIED_RIN_STAT_BOFF 74 +#define cOCT6100_TLV_TYPE_GAIN_APPLIED_SOUT_STAT_BOFF 75 + +#define cOCT6100_TLV_TYPE_MAX_ADAPT_ALE_BOFF 77 +#define cOCT6100_TLV_TYPE_RIN_ANR_BOFF 78 + +#define cOCT6100_TLV_TYPE_NUMBER_PLAYOUT_EVENTS 79 + +#define cOCT6100_TLV_TYPE_RIN_MUTE_BOFF 80 +#define cOCT6100_TLV_TYPE_SIN_MUTE_BOFF 81 + +#define cOCT6100_TLV_TYPE_CHAN_TAIL_LENGTH_BOFF 82 + +#define cOCT6100_TLV_TYPE_CHAN_VQE_TONE_DISABLING_BOFF 83 + +#define cOCT6100_TLV_TYPE_ANR_SNR_IMPROVEMENT_BOFF 84 +#define cOCT6100_TLV_TYPE_ANR_AGRESSIVITY_BOFF 85 + +#define cOCT6100_TLV_TYPE_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 86 +#define cOCT6100_TLV_TYPE_RIN_TONE_REM_COUNTER_BOFF 87 + +#define cOCT6100_TLV_TYPE_AF_TAIL_DISP_VALUE_BOFF 88 + +#define cOCT6100_TLV_TYPE_POUCH_COUNTER_BOFF 89 + +#define cOCT6100_TLV_TYPE_AEC_TAIL_LENGTH_BOFF 90 + +#define cOCT6100_TLV_TYPE_MATRIX_DWORD_BASE 91 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_STATS_BYTE_SIZE 92 +#define cOCT6100_TLV_TYPE_RECORDED_PCM_EVENT_BYTE_SIZE 93 +#define cOCT6100_TLV_TYPE_HOT_CHANNEL_SELECT_DWORD_BASE 94 +#define cOCT6100_TLV_TYPE_IS_ISR_CALLED_BOFF 95 + +#define cOCT6100_TLV_TYPE_MATRIX_TIMESTAMP_DWORD_BASE 96 + +#define cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_OFFSET 100 +#define cOCT6100_TLV_TYPE_CHAN_MAIN_IO_STATS_SIZE 101 + +#define cOCT6100_TLV_TYPE_AF_WRITE_PTR_BYTE_OFFSET 104 +#define cOCT6100_TLV_TYPE_MATRIX_WP_DWORD_BASE 105 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 106 + +#define cOCT6100_TLV_TYPE_MUSIC_PROTECTION_ENABLE_BOFF 107 + +#define cOCT6100_TLV_TYPE_IMAGE_TYPE 108 +#define cOCT6100_TLV_TYPE_MAX_WIRELINE_CHANNELS 111 + +#define cOCT6100_TLV_TYPE_AF_EVENT_CB_SIZE 112 + +#define cOCT6100_TLV_TYPE_ZZ_ENERGY_CHAN_STATS_BOFF 116 +#define cOCT6100_TLV_TYPE_YY_ENERGY_CHAN_STATS_BOFF 117 + +#define cOCT6100_TLV_TYPE_BUFFER_PLAYOUT_SKIP_IN_EVENTS 119 + +#define cOCT6100_TLV_TYPE_SOUT_NOISE_BLEACHING 121 + +#define cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE 124 +#define cOCT6100_TLV_TYPE_DOUBLE_TALK_BEH_MODE_BOFF 125 + +#define cOCT6100_TLV_TYPE_IDLE_CODE_DETECTION_BOFF 136 + +#define cOCT6100_TLV_TYPE_NLP_STATISTICS 138 + +#define cOCT6100_TLV_TYPE_RIN_ANR_VALUE 147 + +#define cOCT6100_TLV_TYPE_ADPCM_ENABLE 150 +#define cOCT6100_TLV_TYPE_NUM_TONE_DETECTOR 151 +#define cOCT6100_TLV_TYPE_CONFERENCING_ENABLE 152 +#define cOCT6100_TLV_TYPE_MAX_NUMBER_OF_CHANNELS 153 +#define cOCT6100_TLV_TYPE_DEBUG_CHAN_INDEX_VALUE 154 +#define cOCT6100_TLV_TYPE_TONE_DETECTOR_PROFILE 155 +#define cOCT6100_TLV_TYPE_TEST_MODE_ENABLE 156 +#define cOCT6100_TLV_TYPE_MAX_TAIL_DISPLACEMENT 157 + + +/* TLV length defines. */ +#define cOCT6100_TLV_MIN_LENGTH_DEFAULT 4 +#define cOCT6100_TLV_MAX_LENGTH_DEFAULT 0xFFFFFFFF + +#define cOCT6100_TLV_MIN_LENGTH_VERSION_NUMBER 4 +#define cOCT6100_TLV_MAX_LENGTH_VERSION_NUMBER 1016 +#define cOCT6100_TLV_MIN_LENGTH_CUSTOMER_PROJECT_ID 4 +#define cOCT6100_TLV_MAX_LENGTH_CUSTOMER_PROJECT_ID 4 + + +#define cOCT6100_TLV_MIN_LENGTH_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_MAX_LENGTH_CH0_MAIN_BASE_ADDRESS 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_IO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_IO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_ZCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_ZCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_XCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_XCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_MAIN_YCB_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_MAIN_YCB_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_FREE_MEM_BASE_ADDRESS 4 +#define cOCT6100_TLV_MAX_LENGTH_FREE_MEM_BASE_ADDRESS 4 +#define cOCT6100_TLV_MIN_LENGTH_CH_ROOT_CONF_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CH_ROOT_CONF_OFFSET 4 + +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_ZPO_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_ZPO_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_CH_MAIN_YPO_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_POA_CH_MAIN_YPO_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZWP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZWP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZIS 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZIS 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_ZSP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_ZSP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YWP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YWP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YIS 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YIS 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RW_YSP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RW_YSP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_ZRP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_ZRP 8 +#define cOCT6100_TLV_MIN_LENGTH_POA_BOFF_RO_YRP 8 +#define cOCT6100_TLV_MAX_LENGTH_POA_BOFF_RO_YRP 8 + +#define cOCT6100_TLV_MIN_LENGTH_CNR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CNR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_ANR_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_HZ_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_HZ_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_HX_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_HX_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MAX_LENGTH_LCA_Z_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MIN_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN 8 +#define cOCT6100_TLV_MAX_LENGTH_LCA_Y_CONF_BOFF_RW_GAIN 8 + +#define cOCT6100_TLV_MIN_LENGTH_CNA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CNA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_NOA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_NOA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_VFA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_VFA_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 8 +#define cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_TAIL_DISP 8 + +#define cOCT6100_TLV_MIN_LENGTH_STATSA_MAIN_IO_BOFF_RO_EPC 8 +#define cOCT6100_TLV_MAX_LENGTH_STATSA_MAIN_IO_BOFF_RO_EPC 8 + +#define cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST 8 +#define cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_INST 8 +#define cOCT6100_TLV_MIN_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 8 +#define cOCT6100_TLV_MAX_LENGTH_BOOTA_POUCH_BOFF_RW_BOOT_RESULT 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_CHAN_MAIN_IO_STATS_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_MAIN_IO_STATS_SIZE 4 + +#define cOCT6100_TLV_MIN_LENGTH_CDA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_CDA_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_TDM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TDM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_DIS_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_DIS_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_NT_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_NT_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_AEC_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_PCM_LEAK_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_PCM_LEAK_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_DEFAULT_ERL_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_DEFAULT_ERL_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_NLP_CONV_CAP_CONF_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 8 +#define cOCT6100_TLV_MAX_LENGTH_TLA_MAIN_IO_BOFF_RW_MAX_ECHO_POINT 8 + +#define cOCT6100_TLV_MIN_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_DOMINANT_SPEAKER_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_TAIL_DISP_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_DEFAULT_ERL_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_ALC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_HLC_TARGET_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MIN_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_ALC_HLC_STATUS_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_Z_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_Y_PLAYOUT_HARD_SKIP_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_AFT_FIELD_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_AFT_FIELD_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_VOICE_DETECTED_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_VOICE_DETECTED_STAT_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_RIN_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_GAIN_APPLIED_SOUT_STAT_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_MAX_ADAPT_ALE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_MAX_ADAPT_ALE_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_ANR_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_ANR_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_ANR_VALUE_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_ANR_VALUE_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_SIN_MUTE_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_SIN_MUTE_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_SNR_IMPROVEMENT_BOFF_RW 8 +#define cOCT6100_TLV_MIN_LENGTH_ANR_AGRESSIVITY_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_ANR_AGRESSIVITY_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_TAIL_LENGTH_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_TAIL_LENGTH_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_CHAN_VQE_TONE_DIS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_CHAN_VQE_TONE_DIS_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_TONE_REM_CONF_BOFF_RW_ENABLE 8 + +#define cOCT6100_TLV_MIN_LENGTH_RIN_TONE_REM_COUNTER_BOFF_RW 8 +#define cOCT6100_TLV_MAX_LENGTH_RIN_TONE_REM_COUNTER_BOFF_RW 8 + +#define cOCT6100_TLV_MIN_LENGTH_AF_TAIL_DISP_VALUE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_AF_TAIL_DISP_VALUE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_POUCH_COUNTER_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_POUCH_COUNTER_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_AEC_TAIL_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_AEC_TAIL_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_IS_ISR_CALLED_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_IS_ISR_CALLED_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_ENABLE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_ZZ_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MIN_LENGTH_YY_ENERGY_CHAN_STATS_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_YY_ENERGY_CHAN_STATS_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION_BOFF 8 +#define cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION_BOFF 8 + +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_INDEX_VALUE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_INDEX_VALUE 4 +#define cOCT6100_TLV_MIN_LENGTH_ADPCM_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_ADPCM_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_NUM_TONE_DETECTOR 4 +#define cOCT6100_TLV_MAX_LENGTH_NUM_TONE_DETECTOR 4 +#define cOCT6100_TLV_MIN_LENGTH_CONFERENCING_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_CONFERENCING_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_NUMBER_OF_CHANNELS 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_NUMBER_OF_CHANNELS 4 +#define cOCT6100_TLV_MIN_LENGTH_TONE_DETECTOR_PROFILE 4 +#define cOCT6100_TLV_MAX_LENGTH_TONE_DETECTOR_PROFILE 4 +#define cOCT6100_TLV_MIN_LENGTH_TEST_MODE_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_TEST_MODE_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_DISPLACEMENT 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_DISPLACEMENT 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_EVENT_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_EVENT_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_CNR_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_CNR_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_ANR_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_ANR_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_TAIL_LENGTH_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_PLAYOUT_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_PLAYOUT_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_MUSIC_PROTECTION_RW_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_MUSIC_PROTECTION_RW_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_TONE_REMOVAL_ENABLE 4 +#define cOCT6100_TLV_MAX_LENGTH_TONE_REMOVAL_ENABLE 4 +#define cOCT6100_TLV_MIN_LENGTH_NUMBER_PLAYOUT_EVENTS 4 +#define cOCT6100_TLV_MAX_LENGTH_NUMBER_PLAYOUT_EVENTS 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_HOT_CHANNEL_SELECT_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_TIMESTAMP_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_TIMESTAMP_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_AF_WRITE_PTR_BYTE_OFFSET 4 +#define cOCT6100_TLV_MAX_LENGTH_AF_WRITE_PTR_BYTE_OFFSET 4 +#define cOCT6100_TLV_MIN_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_RECORDED_PCM_EVENT_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_MATRIX_WP_DWORD_BASE 4 +#define cOCT6100_TLV_MAX_LENGTH_MATRIX_WP_DWORD_BASE 4 +#define cOCT6100_TLV_MIN_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_DEBUG_CHAN_LITE_STATS_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_IMAGE_TYPE 4 +#define cOCT6100_TLV_MAX_LENGTH_IMAGE_TYPE 4 +#define cOCT6100_TLV_MIN_LENGTH_MAX_WIRELINE_CHANNELS 4 +#define cOCT6100_TLV_MAX_LENGTH_MAX_WIRELINE_CHANNELS 4 +#define cOCT6100_TLV_MIN_LENGTH_AF_EVENT_CB_BYTE_SIZE 4 +#define cOCT6100_TLV_MAX_LENGTH_AF_EVENT_CB_BYTE_SIZE 4 +#define cOCT6100_TLV_MIN_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS 4 +#define cOCT6100_TLV_MAX_LENGTH_BUFFER_PLAYOUT_SKIP_IN_EVENTS 4 +#define cOCT6100_TLV_MIN_LENGTH_DOUBLE_TALK_BEH_MODE 4 +#define cOCT6100_TLV_MAX_LENGTH_DOUBLE_TALK_BEH_MODE 4 +#define cOCT6100_TLV_MIN_LENGTH_SOUT_NOISE_BLEACHING 4 +#define cOCT6100_TLV_MAX_LENGTH_SOUT_NOISE_BLEACHING 4 +#define cOCT6100_TLV_MIN_LENGTH_IDLE_CODE_DETECTION 4 +#define cOCT6100_TLV_MAX_LENGTH_IDLE_CODE_DETECTION 4 +#define cOCT6100_TLV_MIN_LENGTH_NLP_STATISTICS 4 +#define cOCT6100_TLV_MAX_LENGTH_NLP_STATISTICS 4 + + +/***************************** TYPES ***************************************/ + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiProcessTlvRegion( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiInterpretTlvEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTlvFieldType, + IN UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulTlvValueAddress ); + +UINT32 Oct6100ApiTlvCheckLengthField( + IN OUT UINT32 f_ulTlvFieldLength, + IN UINT32 f_ulMinLengthValue, + IN UINT32 f_ulMaxLengthValue ); + +UINT32 Oct6100ApiTlvReadDword( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulReadData ); + +UINT32 Oct6100ApiTlvReadBitOffsetStruct( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulAddress, + OUT tPOCT6100_TLV_OFFSET f_pBitOffsetStruct ); + +#endif /* __OCT6100_TLV_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h new file mode 100644 index 0000000..c3192c2 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tone_detection_priv.h @@ -0,0 +1,111 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tone_detection.c. All elements defined in + this file are for private usage of the API. All public elements are + defined in the oct6100_tone_detection_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_PRIV_H__ +#define __OCT6100_TONE_DETECTION_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ToneDetectionEnableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable ); + +UINT32 Oct6100ApiCheckToneEnableParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_ENABLE f_pToneDetectEnable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + + OUT PUINT32 f_pulExtToneChanIndex ); + +UINT32 Oct6100ApiWriteToneDetectEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + + IN UINT32 f_ulExtToneChanIndex ); + +UINT32 Oct6100ApiUpdateChanToneDetectEntry ( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex ); + +UINT32 Oct6100ToneDetectionDisableSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable ); + +UINT32 Oct6100ApiAssertToneDetectionParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TONE_DETECTION_DISABLE f_pToneDetectDisable, + OUT PUINT32 f_pulChannelIndex, + OUT PUINT32 f_pulToneEventNumber, + OUT PUINT32 f_pulExtToneChanIndex, + + OUT PBOOL f_pfDisableAll ); + +UINT32 Oct6100ApiClearToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + + IN BOOL f_fDisableAll ); + +UINT32 Oct6100ApiReleaseToneDetectionEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulChannelIndex, + IN UINT32 f_ulToneEventNumber, + IN UINT32 f_ulExtToneChanIndex, + IN BOOL f_fDisableAll ); + +UINT32 Oct6100ApiIsSSTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fSSTone ); + +UINT32 Oct6100ApiIs2100Tone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulToneEventNumber, + OUT PBOOL f_fIs2100Tone ); + +#endif /* __OCT6100_TONE_DETECTION_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h new file mode 100644 index 0000000..b7c57f3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h @@ -0,0 +1,126 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tsi_cnct.c. All elements defined in + this file are for private usage of the API. All public elements are + defined in the oct6100_tsi_cnct_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_PRIV_H__ +#define __OCT6100_TSI_CNCT_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* TSI connection list pointer macros. */ +#define mOCT6100_GET_TSI_CNCT_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_TSI_CNCT )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctListOfst ); + +#define mOCT6100_GET_TSI_CNCT_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_TSI_CNCT )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctListOfst)) + ulIndex; + +#define mOCT6100_GET_TSI_CNCT_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsiCnctAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetTsiCnctSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiTsiCnctSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + + +UINT32 Oct6100TsiCnctOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100ApiCheckTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100ApiReserveTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiWriteTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiUpdateTsiEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + + +UINT32 Oct6100TsiCnctCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); + +UINT32 Oct6100ApiAssertTsiParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiInvalidateTsiStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiReleaseTsiResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusTsiChanIndex ); + +UINT32 Oct6100ApiReleaseTsiCnctEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex ); + +#endif /* __OCT6100_TSI_CNCT_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h new file mode 100644 index 0000000..ca080b3 --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_tsst_priv.h @@ -0,0 +1,89 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_tsst.c. All elements defined in + this file are for private usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSST_PRIV_H__ +#define __OCT6100_TSST_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +/* TSST allocation and serialization pointer macros. */ +#define mOCT6100_GET_TSST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PUINT32 )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstAllocOfst); + +#define mOCT6100_GET_TSST_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_TSST_ENTRY )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListOfst ); + +#define mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_TSST_ENTRY )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListOfst)) + ulIndex; + +#define mOCT6100_GET_TSST_LIST_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulTsstListAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetTsstSwSizes( + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiTsstSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + +UINT32 Oct6100ApiValidateTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulNumTssts, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulDirection ); + +UINT32 Oct6100ApiReserveTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + OUT PUINT16 f_pusTsstMemIndex, + OUT PUINT16 f_pusTsstListIndex ); + +UINT32 Oct6100ApiReleaseTsst( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulTimeslot, + IN UINT32 f_ulStream, + IN UINT32 f_ulNumTsst, + IN UINT32 f_ulDirection, + IN UINT16 f_usTsstListIndex ); + +#endif /* __OCT6100_TSST_PRIV_H__ */ diff --git a/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h new file mode 100644 index 0000000..7b3eb5d --- /dev/null +++ b/xpp/oct612x/octdeviceapi/oct6100api/oct6100_version.h @@ -0,0 +1,39 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_version.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the version of API. To obtain that version + number, the user must call the API function Oct6100ApiGetVersion(). + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API 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. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 52 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_VERSION_H__ +#define __OCT6100_VERSION_H__ + +/* String version of the OCT6100 API.*/ + +#define cOCT6100_API_VERSION "OCT6100API-01.00-PR49" + +#endif /* __OCT6100_VERSION_H__ */ diff --git a/xpp/oct612x/test.c b/xpp/oct612x/test.c new file mode 100644 index 0000000..0105e58 --- /dev/null +++ b/xpp/oct612x/test.c @@ -0,0 +1,46 @@ +/* + NOTE: This is not intended to be a functional program. Its only purpose + is to act as a tool to find out what portions of the Octasic API kit we + actually need to link into our drivers. As such, it references every API + call that the actual drivers use, and we let the compiler and linker tell + us what parts of each API module are actually needed to successfully + build this program. + */ +#include "oct6100api/oct6100_api.h" + +int main(int argc, char **argv) +{ + tPOCT6100_INSTANCE_API pApiInstance; + UINT32 ulResult; + tOCT6100_CHANNEL_MODIFY modify; + tOCT6100_INTERRUPT_FLAGS InterruptFlags; + tOCT6100_TONE_EVENT tonefound; + tOCT6100_EVENT_GET_TONE tonesearch; + tOCT6100_CHIP_OPEN ChipOpen; + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + tOCT6100_CHANNEL_OPEN ChannelOpen; + tOCT6100_TONE_DETECTION_ENABLE enable; + tOCT6100_CHIP_CLOSE ChipClose; + tOCT6100_API_GET_CAPACITY_PINS CapacityPins; + + Oct6100ChannelModifyDef(&modify); + ulResult = Oct6100ChannelModify(pApiInstance, &modify); + Oct6100InterruptServiceRoutineDef(&InterruptFlags); + Oct6100InterruptServiceRoutine(pApiInstance, &InterruptFlags); + Oct6100EventGetToneDef(&tonesearch); + ulResult = Oct6100EventGetTone(pApiInstance, &tonesearch); + Oct6100ChipOpenDef(&ChipOpen); + Oct6100GetInstanceSizeDef(&InstanceSize); + ulResult = Oct6100GetInstanceSize(&ChipOpen, &InstanceSize); + ulResult = Oct6100ChipOpen(pApiInstance, &ChipOpen); + Oct6100ChannelOpenDef(&ChannelOpen); + ulResult = Oct6100ChannelOpen(pApiInstance, &ChannelOpen); + Oct6100ToneDetectionEnableDef(&enable); + Oct6100ToneDetectionEnable(pApiInstance, &enable); + Oct6100ChipCloseDef(&ChipClose); + ulResult = Oct6100ChipClose(pApiInstance, &ChipClose); + Oct6100ApiGetCapacityPinsDef(&CapacityPins); + ulResult = Oct6100ApiGetCapacityPins(&CapacityPins); + + return 0; +} diff --git a/xpp/parse_span_specs.c b/xpp/parse_span_specs.c new file mode 100644 index 0000000..4cbc27f --- /dev/null +++ b/xpp/parse_span_specs.c @@ -0,0 +1,152 @@ +/* + * Written by Oron Peled + * Copyright (C) 2014, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "parse_span_specs.h" + +void free_span_specifications(struct span_specs *span_specs) +{ + if (span_specs) { + if (span_specs->buf) + free(span_specs->buf); + free(span_specs); + } +} + +static enum tdm_codec is_alaw_span_type(const char *span_type) +{ + assert(span_type); + if (strcmp(span_type, "E1") == 0) + return TDM_CODEC_ALAW; + else if (strcmp(span_type, "T1") == 0) + return TDM_CODEC_ULAW; + return TDM_CODEC_UNKNOWN; +} + +struct span_specs *parse_span_specifications(const char *spec_string, int default_is_alaw) +{ + struct span_specs *span_specs; + char *p; + int spanno; + int i; + + if (!spec_string) + return NULL; + /* Allocate and Initialize */ + span_specs = calloc(sizeof(char *), MAX_SPANNO); + if (!span_specs) + goto err; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) + span_specs->span_is_alaw[spanno] = TDM_CODEC_UNKNOWN; + span_specs->buf = strdup(spec_string); + if (!span_specs->buf) + goto err; + for (i = 0;; i++) { + char *curr_item; + char *tokenize_key; + char *key; + char *value; + enum tdm_codec is_alaw; + int matched; + + /* Split to items */ + p = (i == 0) ? span_specs->buf : NULL; + p = strtok_r(p, " \t,", &curr_item); + if (!p) + break; + + /* Split to : */ + key = strtok_r(p, ":", &tokenize_key); + if (!key) { + fprintf(stderr, + "Missing ':' (item #%d inside '%s')\n", + i+1, spec_string); + goto err; + } + value = strtok_r(NULL, ":", &tokenize_key); + if (!value) { + fprintf(stderr, + "Missing value after ':' (item #%d inside '%s')\n", + i+1, spec_string); + goto err; + } + + /* Match span specification and set alaw/ulaw */ + is_alaw = is_alaw_span_type(value); + if (is_alaw == TDM_CODEC_UNKNOWN) { + fprintf(stderr, + "Illegal span type '%s' (item #%d inside '%s')\n", + value, i+1, spec_string); + goto err; + } + matched = 0; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + char tmpbuf[BUFSIZ]; + + snprintf(tmpbuf, sizeof(tmpbuf), "%d", spanno + 1); + if (fnmatch(p, tmpbuf, 0) == 0) { + matched++; + span_specs->span_is_alaw[spanno] = is_alaw; + } + } + if (!matched) { + fprintf(stderr, + "Span specification '%s' does not match any span (item #%d inside '%s')\n", + key, i+1, spec_string); + goto err; + } + } + + /* Set defaults */ + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + if (span_specs->span_is_alaw[spanno] == TDM_CODEC_UNKNOWN) { + span_specs->span_is_alaw[spanno] = default_is_alaw; + } + } + return span_specs; +err: + free_span_specifications(span_specs); + return NULL; +} + +void print_span_specifications(struct span_specs *span_specs, FILE *output) +{ + int spanno; + + if (!span_specs) + return; + for (spanno = 0; spanno < MAX_SPANNO; spanno++) { + enum tdm_codec is_alaw; + + is_alaw = span_specs->span_is_alaw[spanno]; + fprintf(output, "%d %s\n", + spanno+1, (is_alaw == TDM_CODEC_ALAW) ? "alaw" : "ulaw"); + } +} diff --git a/xpp/parse_span_specs.h b/xpp/parse_span_specs.h new file mode 100644 index 0000000..b7dddf9 --- /dev/null +++ b/xpp/parse_span_specs.h @@ -0,0 +1,43 @@ +#ifndef PARSE_SPAN_SPECS_H +#define PARSE_SPAN_SPECS_H + +/* + * Written by Oron Peled + * Copyright (C) 2014, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define MAX_SPANNO 4 /* E1/T1 spans -- always in first unit. 1-based */ + +enum tdm_codec { + TDM_CODEC_UNKNOWN, + TDM_CODEC_ULAW, + TDM_CODEC_ALAW, +}; + +struct span_specs { + char *buf; + enum tdm_codec span_is_alaw[MAX_SPANNO]; +}; + +struct span_specs *parse_span_specifications(const char *spec_string, int default_is_alaw); +void free_span_specifications(struct span_specs *span_specs); +void print_span_specifications(struct span_specs *span_specs, FILE *output); + +#endif /* PARSE_SPAN_SPECS_H */ diff --git a/xpp/perl_modules/Dahdi.pm b/xpp/perl_modules/Dahdi.pm new file mode 100644 index 0000000..c3bb2bc --- /dev/null +++ b/xpp/perl_modules/Dahdi.pm @@ -0,0 +1,78 @@ +package Dahdi; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Span; + +=head1 NAME + +Dahdi - Perl interface to Dahdi information + +This package allows access from Perl to information about Dahdi +hardware and loaded Dahdi devices. + +=head1 SYNOPSIS + + # Listing channels in analog spans: + use Dahdi; + # scans system: + my @spans = Dahdi::spans(); + for my $span (@spans) { + next if ($span->is_digital); + $span->num. " - [". $span->type ."] ". $span->name. "\n"; + for my $chan ($span->chans) { + print " - ".$chan->num . " - [". $chan->type. "] ". $chan->fqn". \n"; + } + } +=cut + +our $virt_base; +our $proc_dahdi_base; +our $proc_usb_base; +our $sys_base; + +=head1 spans() + +Returns a list of span objects, ordered by span number. + +=cut + +sub spans() { + my @spans; + + -d $proc_dahdi_base or return (); + foreach my $zfile (glob "$proc_dahdi_base/*") { + next unless ($zfile =~ m{^$proc_dahdi_base/\d+$}); + my $span = Dahdi::Span->new($zfile); + push(@spans, $span); + } + @spans = sort { $a->num <=> $b->num } @spans; + return @spans; +} + +=head1 ENVIRONMENT + +If C is set in the environment, it will be considered +as a path to a directory that holds a dump (copy) of all the required +files from /proc and /sys . You can generate that directory using the +script C . + +=head1 SEE ALSO + +Span objects: L. + +Dahdi channels objects: L. + +Dahdi hardware devices information: L. + +Xorcom Astribank -specific information: L. + +=cut + +1; diff --git a/xpp/perl_modules/Dahdi/Chans.pm b/xpp/perl_modules/Dahdi/Chans.pm new file mode 100644 index 0000000..8a43f58 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Chans.pm @@ -0,0 +1,264 @@ +package Dahdi::Chans; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; + +=head1 NAME + +Dahdi::Chans - Perl interface to a Dahdi channel information + +This package allows access from perl to information about a Dahdi +channel. It is part of the Dahdi Perl package. + +=head1 alarms() + +In an array context returns a list of alarm strings (RED, BLUE, etc.) +for this channel (an empty list == false if there are no alarms). +In scalar context returns the number of alarms for a specific channel. + +=head1 battery() + +Returns 1 if channel reports to have battery (A remote PBX connected to +an FXO port), 0 if channel reports to not have battery and C +otherwise. + +Currently only wcfxo and Astribank FXO modules report battery. For the +rest of the channels + +=head1 fqn() + +(Fully Qualified Name) Returns the full "name" of the channel. + +=head1 index() + +Returns the number of this channel (in the span). + +=head1 num() + +Returns the number of this channel as a Dahdi channel. + +=head signalling() + +Returns the signalling set for this channel through /etc/dahdi/system.conf . +This is always empty before dahdi_cfg was run. And shows the "other" type +for FXS and for FXO. + +=head1 span() + +Returns a reference to the span to which this channel belongs. + +=head1 type() + +Returns the type of the channel: 'FXS', 'FXO', 'EMPTY', etc. + +=cut + +my @alarm_types = qw(BLUE YELLOW RED LOOP RECOVERING NOTOPEN); + +# Taken from dahdi-base.c +my @sigtypes = ( + "FXSLS", + "FXSKS", + "FXSGS", + "FXOLS", + "FXOKS", + "FXOGS", + "E&M-E1", + "E&M", + "Clear", + "HDLCRAW", + "HDLCFCS", + "HDLCNET", + "Hardware-assisted HDLC", + "MTP2", + "Slave", + "CAS", + "DACS", + "DACS+RBS", + "SF (ToneOnly)", + "Unconfigured", + "Reserved" + ); + +sub new($$$$$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $span = shift or die "Missing a span parameter\n"; + my $index = shift; + my $line = shift or die "Missing an input line\n"; + defined $index or die "Missing an index parameter\n"; + my $self = { + 'SPAN' => $span, + 'INDEX' => $index, + }; + bless $self, $pack; + my ($num, $fqn, $rest) = split(/\s+/, $line, 3); + $num or die "Missing a channel number parameter\n"; + $fqn or die "Missing a channel fqn parameter\n"; + my $signalling = ''; + my @alarms = (); + my $info = ''; + if(defined $rest) { + # remarks in parenthesis (In use), (no pcm) + while($rest =~ s/\s*(\([^)]+\))\s*/ /) { + $info .= " $1"; + } + # Alarms + foreach my $alarm (@alarm_types) { + if($rest =~ s/\s*(\b${alarm}\b)\s*/ /) { + push(@alarms, $1); + } + } + foreach my $sig (@sigtypes) { + if($rest =~ s/^\Q$sig\E/ /) { + $signalling = $sig; + last; + } + } + warn "Unrecognized garbage '$rest' in $fqn\n" + if $rest =~ /\S/; + } + $self->{NUM} = $num; + $self->{FQN} = $fqn; + $self->{SIGNALLING} = $signalling; + $self->{ALARMS} = \@alarms; + $self->{INFO} = $info; + my $type; + if($fqn =~ m|\bXPP_(\w+)/.*$|) { + $type = $1; # An Astribank + } elsif ($fqn =~ m{\bWCFXO/.*}) { + $type = "FXO"; # wcfxo - x100p and relatives. + # A single port card. The driver issue RED alarm when + # There's no better + $self->{BATTERY} = !($span->description =~ /\bRED\b/); + } elsif ($fqn =~ m{\bFXS/.*}) { + $type = "FXS"; # likely Rhino + } elsif ($fqn =~ m{\bFXO/.*}) { + $type = "FXO"; # likely Rhino + } elsif ($fqn =~ m{---/.*}) { + $type = "EMPTY"; # likely Rhino, empty slot. + } elsif ($fqn =~ m{\b(WCTE|TE[24]|WCT1|WCT13x|Tor2|TorISA|WP[TE]1|cwain[12]|R[124]T1|AP40[124]|APE40[124])/.*}) { + # TE[24]: Digium wct4xxp + # WCT1: Digium single span card drivers? + # Tor2: Tor PCI cards + # TorISA: ISA ones (still used?) + # WP[TE]1: Sangoma. TODO: this one tells us if it is TE or NT. + # cwain: Junghanns E1 card. + # R[124]: Rhino r1t1/rxt1 cards + # AP40[124]: Aligera AP40X cards + # APE40[124]: Aligera APE40X cards + $type = "PRI"; + } elsif ($fqn =~ m{\b(WCBRI|B4|ZTHFC\d*|ztqoz\d*)/.*}) { + # WCBRI: The Digium Hx8 series cards with BRI module. + # B4: The Digium wcb4xxp DAHDI driver + # ZTHFC: HFC-s single-port card (zaphfc/vzaphfc) + # ztqoz: qozap (Junghanns) multi-port HFC card + $type = "BRI"; + } elsif ($fqn =~ m{\bDYN/.*}) { + # DYN : Dynamic span (TDMOE) + $type = "DYN" + } elsif ($fqn =~ m{\bztgsm/.*}) { + # Junghanns GSM card + $type = "GSM"; + } elsif($signalling ne '') { + $type = 'FXO' if $signalling =~ /^FXS/; + $type = 'FXS' if $signalling =~ /^FXO/; + } else { + $type = $self->probe_type(); + } + $self->type($type); + $self->span()->type($type) + if ! defined($self->span()->type()) || + $self->span()->type() eq 'UNKNOWN'; + return $self; +} + +=head1 probe_type() + +In the case of some cards, the information in /proc/dahdi is not good +enough to tell the type of each channel. In this case an extra explicit +probe is needed. + +Currently this is implemented by using some invocations of dahdi_cfg(8). + +It may later be replaced by dahdi_scan(8). + +=cut + +my $dahdi_cfg = $ENV{DAHDI_CFG} || '/usr/sbin/dahdi_cfg'; +sub probe_type($) { + my $self = shift; + my $fqn = $self->fqn; + my $num = $self->num; + my $type; + + if($fqn =~ m:WCTDM/|WRTDM/|OPVXA1200/:) { + my %maybe; + + undef %maybe; + foreach my $sig (qw(fxo fxs)) { + my $cmd = "echo ${sig}ks=$num | $dahdi_cfg -c /dev/fd/0"; + + $maybe{$sig} = system("$cmd >/dev/null 2>&1") == 0; + } + if($maybe{fxo} and $maybe{fxs}) { + $type = 'EMPTY'; + } elsif($maybe{fxo}) { + $type = 'FXS'; + } elsif($maybe{fxs}) { + $type = 'FXO'; + } else { + $type = 'EMPTY'; + } + } else { + $type = $self->type; + } + return $type; +} + +sub battery($) { + my $self = shift or die; + my $span = $self->span or die; + + return undef unless defined $self->type && $self->type eq 'FXO'; + return $self->{BATTERY} if defined $self->{BATTERY}; + + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my $index = $self->index; + return undef if !$xpd; + + # It's an XPD (FXO) + my @lines = @{$xpd->lines}; + my $line = $lines[$index]; + return $line->battery; +} + +sub alarms($) { + my $self = shift or die; + my @alarms = @{$self->{ALARMS}}; + + return @alarms; +} + +sub blink($$) { + my $self = shift or die; + my $on = shift; + my $span = $self->span or die; + + my $xpd = Dahdi::Xpp::xpd_of_span($span); + my $index = $self->index; + return undef if !$xpd; + + my @lines = @{$xpd->lines}; + my $line = $lines[$index]; + return $line->blink($on); +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Config/Gen.pm b/xpp/perl_modules/Dahdi/Config/Gen.pm new file mode 100644 index 0000000..cc439de --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen.pm @@ -0,0 +1,275 @@ +package Dahdi::Config::Gen; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# + +=head1 NAME + +Dahdi::Config::Gen -- Wrapper class for configuration generators. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen qw(is_true); + my $params = Dahdi::Config::Params->new('the-config-file'); + my $gconfig = Dahdi::Config::Gen->new($params); + my $num = $gconfig->{'base_exten'}; + my $overlap = is_true($gconfig->{'brint_overlap'}); + $gconfig->dump; # For debugging + $gconfig->run_generator('system', {}, @spans); + +=head1 DESCRIPTION + +The constructor must be given an C object. +The returned object contains all data required for generation in the +form of a hash. + +The constructor maps the Cs from the parameter object into semantic +configuration keys. E.g: the C item is mapped to C and +C keys. + +The actual generation is done by delegation to one of the generators. +This is done via the C method which receive the +generator name, a generator specific options hash and a list of +span objects (from C) for which to generate configuration. + +This module contains few helper functions. E.g: C, C. + +=cut + +require Exporter; +@ISA = qw(Exporter); + +@EXPORT_OK = qw(is_true); + +use strict; + +# Parse values as true/false +sub is_true($) { + my $val = shift; + return undef unless defined $val; + return $val =~ /^(1|y|yes)$/i; +} + +sub range_string($$) { + my ($start, $end) = @_; + + if($start == $end) { + sprintf "%d", $start; + } else { + sprintf "%d-%d", $start, $end; + } +} + +# Generate channel range strings from arrays of chan numbers +# E.g: "63-77,79-93" +sub channo_range(@) { + my @channos = sort { $a <=> $b } @_; + my $first_num = $channos[0]; + my $range_start = $first_num; + my @range; + my $prev = undef; + + foreach my $c (@channos) { + my $curr = $c; + if(!defined($prev)) { + # First iteration + $prev = $curr; + } elsif($curr != $prev + 1) { + # New range + push(@range, range_string($range_start, $prev)); + $range_start = $curr; + } + $prev = $curr; + } + if($prev >= $first_num) { + # Last range + push(@range, range_string($range_start, $prev)); + } + return join(',', @range); +} + +# Generate channel range strings from chan objects +# E.g: "63-77,79-93" +sub chan_range(@) { + my @chans = sort { $a->num <=> $b->num } @_; + my @channos = map { $_->num } @chans; + channo_range(@channos); +} + +# Generate channel range strings from digital span objects +# E.g: "63-77,79-93" +sub bchan_range($) { + my $span = shift || die; + die unless $span->is_digital(); + my $first_chan = ($span->chans())[0]; + my $first_num = $first_chan->num(); + my $bchan_ref = $span->bchan_list(); + my @channos = map { $_ + $first_num } @{$bchan_ref}; + channo_range(@channos); +} + +# Returns a channel numbers array from a channel range string +sub parse_chan_range($) { + my $rangestr = shift; + $rangestr =~ s/\s*//g; # Squeeze + die "Bad characters in '$rangestr'" if $rangestr =~ /[^\d\s,-]/; + my @ranges = split(/,/, $rangestr); + my @channos; + my $last_end; + + foreach my $range (@ranges) { + my ($start, $end) = split(/-/, $range, 2); + $end = $start unless defined $end; + die "Bad characters in '$start'" if $start =~ /\D/; + die "Bad characters in '$end'" if $end =~ /\D/; + die "Reversed range $end < $start" if $end < $start; + die "Channel number < 1" if $start < 1; + die "New range begins below previous $start <= $last_end" if defined($last_end) && $last_end >= $start; + for(my $i = $start + 0; $i <= $end; $i++) { + push(@channos, $i); + } + $last_end = $end; + } + return sort { $a <=> $b } @channos; +} + +sub new($) { + my $pack = shift || die "$0: Missing package argument"; + my $p = shift || die "$0: Missing parameters argument"; + + # Set defaults + my $fxs_default_start = $p->item('fxs_default_start'); + my $fxo_default_start = $p->item('fxo_default_start'); + + my %default_context = ( + FXO => $p->item('context_lines'), + FXS => $p->item('context_phones'), + IN => $p->item('context_input'), + OUT => $p->item('context_output'), + DYN => $p->item('context_lines'), + BRI_TE => $p->item('context_lines'), + BRI_NT => $p->item('context_lines'), + E1_TE => $p->item('context_lines'), + T1_TE => $p->item('context_lines'), + J1_TE => $p->item('context_lines'), + E1_NT => $p->item('context_lines'), + T1_NT => $p->item('context_lines'), + J1_NT => $p->item('context_lines'), + ); + my %default_group = ( + FXO => $p->item('group_lines'), + FXS => $p->item('group_phones'), + IN => '', + OUT => '', + DYN => '', + BRI_TE => $p->item('group_lines'), + BRI_NT => $p->item('group_lines'), + E1_TE => $p->item('group_lines'), + T1_TE => $p->item('group_lines'), + J1_TE => $p->item('group_lines'), + E1_NT => $p->item('group_lines'), + T1_NT => $p->item('group_lines'), + J1_NT => $p->item('group_lines'), + ); + my %default_dahdi_signalling = ( + FXO => "fxs$fxo_default_start", + FXS => "fxo$fxs_default_start", + IN => "fxo$fxs_default_start", + OUT => "fxo$fxs_default_start", + DYN => "clear", + ); + my %default_chan_dahdi_signalling = ( + FXO => "fxs_$fxo_default_start", + FXS => "fxo_$fxs_default_start", + IN => "fxo_$fxs_default_start", + OUT => "fxo_$fxs_default_start", + DYN => "auto", # Cheating. Won't really work + ); + + # First complex mapping + my $gconfig = { + PARAMETERS => $p, + 'loadzone' => $p->item('lc_country'), + 'defaultzone' => $p->item('lc_country'), + 'context' => \%default_context, + 'group' => \%default_group, + 'dahdi_signalling' => \%default_dahdi_signalling, + 'chan_dahdi_signalling' => \%default_chan_dahdi_signalling, + }; + # Now add trivial mappings + my @trivial = qw( + base_exten + freepbx + fxs_immediate + bri_hardhdlc + bri_sig_style + r2_idle_bits + tdm_framing + echo_can + brint_overlap + pri_termtype + pri_connection_type + em_signalling + ); + foreach my $k (@trivial) { + $gconfig->{$k} = $p->item($k); + } + bless $gconfig,$pack; + + return $gconfig; +} + +sub run_generator($$@) { + my $gconfig = shift || die; + my $name = shift || die "$0: Missing generator name argument"; + my $genopts = shift || die "$0: Missing genopts argument"; + ref($genopts) eq 'HASH' or die "$0: Bad genopts argument"; + my @spans = @_; + + my $module = "Dahdi::Config::Gen::$name"; + #print STDERR "DEBUG: $module\n"; + eval "use $module"; + if($@) { + die "Failed to load configuration generator for '$name': $@\n"; + } + my $cfg = $module->new($gconfig, $genopts); + $cfg->generate(@spans); +} + +sub dump($) { + my $self = shift || die; + printf STDERR "%s dump:\n", ref $self; + my $width = 30; + foreach my $k (sort keys %$self) { + my $val = $self->{$k}; + my $ref = ref $val; + #print STDERR "DEBUG: '$k', '$ref', '$val'\n"; + if($ref eq '') { + printf STDERR "%-${width}s %s\n", $k, $val; + } elsif($ref eq 'SCALAR') { + printf STDERR "%-${width}s %s\n", $k, ${$val}; + } elsif($ref eq 'ARRAY') { + #printf STDERR "%s:\n", $k; + my $i = 0; + foreach my $v (@{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->[$i]", $v; + $i++; + } + } elsif($ref eq 'HASH') { + #printf STDERR "%s:\n", $k; + foreach my $k1 (keys %{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->\{$k1\}", ${$val}{$k1}; + } + } else { + printf STDERR "%-${width}s (-> %s)\n", $k, $ref; + } + } +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm b/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm new file mode 100644 index 0000000..a92eead --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Assignedspans.pm @@ -0,0 +1,63 @@ +package Dahdi::Config::Gen::Assignedspans; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{ASSIGNED_SPANS_CONF_FILE} || "/etc/dahdi/assigned-spans.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + + # If the span_types utilities were not installed we do not want to run + # this generator or report any errors. + system "which dahdi_span_assignments > /dev/null 2>&1"; + return if $?; + + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + my $cmd = "dahdi_span_assignments dumpconfig > $file"; + system $cmd; + die "Command failed (status=$?): '$cmd'" if $?; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_span_assignments. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm new file mode 100644 index 0000000..252b91e --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm @@ -0,0 +1,299 @@ +package Dahdi::Config::Gen::Chandahdi; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{CHAN_DAHDI_CHANNELS_FILE} || "/etc/asterisk/dahdi-channels.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# Since chan_dahdi definitions "leak" to the next ones, we try +# To reset some important definitions to their chan_dahdi defaults. +my %chan_dahdi_defaults = ( + context => 'default', + group => '63', # FIXME: should not be needed. + overlapdial => 'no', + busydetect => 'no', + rxgain => 0, + txgain => 0, +); + +sub reset_chandahdi_values { + foreach my $arg (@_) { + if (exists $chan_dahdi_defaults{$arg}) { + print "$arg = $chan_dahdi_defaults{$arg}\n"; + } else { + print "$arg =\n"; + } + } +} + +sub gen_openr2($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $type = $span->type; + # Fake type for signalling + my $faketype = ($termtype eq 'TE') ? 'E1_TE' : 'E1_TE'; + my $group = $gconfig->{'group'}{"$type"}; + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + my $context = $gconfig->{'context'}{"$faketype"}; + die "$0: missing default context\n" unless $context; + my @to_reset = qw/context group/; + my $chans = Dahdi::Config::Gen::bchan_range($span); + $group .= "," . (10 + $num); # Invent unique group per span + my $country = $gconfig->{'loadzone'}; + my @valid_countries = qw( ar br cn cz co ec itu mx ph ve ); + die "Country '$country' is invalid for R2. Use one of: @valid_countries\n" + unless grep { $_ eq $country } @valid_countries; + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", 'mfcr2'; + printf "caller = %s\n", ($termtype eq 'TE') ? 'no' : 'yes'; + printf "mfcr2_logdir = span%d\n", $span->num; + print <<"EOF"; +mfcr2_variant=$country +mfcr2_get_ani_first=no +mfcr2_max_ani=10 +mfcr2_max_dnis=4 +mfcr2_category=national_subscriber +mfcr2_call_files=yes +mfcr2_logging=all +mfcr2_mfback_timeout=-1 +mfcr2_metering_pulse_timeout=-1 +EOF + printf "channel => %s\n", $chans; + + reset_chandahdi_values(@to_reset); +} + +sub gen_cas($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $type = $span->type; + my $group = $gconfig->{'group'}{"$type"}; + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + my $context = $gconfig->{'context'}{"$type"}; + die "$0: missing default context\n" unless $context; + # Fake type for signalling + my $faketype = ($termtype eq 'TE') ? 'FXO' : 'FXS'; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$faketype}; + my $em_signalling = $gconfig->{'em_signalling'}; + if ($em_signalling ne 'none') { + $sig = $em_signalling; + # FIXME: but we don't handle E1 yet + $sig = 'em_e1' if $span->proto eq 'E1'; + } + my @to_reset = qw/context group/; + my $chans = Dahdi::Config::Gen::chan_range($span->chans()); + $group .= "," . (10 + $num); # Invent unique group per span + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", $sig; + printf "channel => %s\n", $chans; + reset_chandahdi_values(@to_reset); +} + +sub gen_digital($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); + if($span->is_pri && $gconfig->{'pri_connection_type'} eq 'R2') { + printf "; Skipped: $gconfig->{'pri_connection_type'}\n\n"; + return; + } + my $type = $span->type() || die "$0: Span #$num -- unkown type\n"; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $group = $gconfig->{'group'}{"$type"}; + my $context = $gconfig->{'context'}{"$type"}; + my @to_reset = qw/context group/; + + die "$0: missing default group (termtype=$termtype)\n" unless defined($group); + die "$0: missing default context\n" unless $context; + + my $sig = $span->signalling || die "missing signalling info for span #$num type $type"; + grep($gconfig->{'bri_sig_style'} eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI"; + if($span->is_bri() and $gconfig->{'bri_sig_style'} eq 'bri_ptmp') { + $sig .= '_ptmp'; + } + if ($span->is_bri() && $termtype eq 'NT' && is_true($gconfig->{'brint_overlap'})) { + print "overlapdial = yes\n"; + push(@to_reset, qw/overlapdial/); + } + + $group .= "," . (10 + $num); # Invent unique group per span + printf "group=$group\n"; + printf "context=$context\n"; + printf "switchtype = %s\n", $span->switchtype; + printf "signalling = %s\n", $sig; + printf "channel => %s\n", Dahdi::Config::Gen::bchan_range($span); + reset_chandahdi_values(@to_reset); +} + +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $gconfig->{'base_exten'} + $num; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$type}; + my $context = $gconfig->{'context'}{$type}; + my $group = $gconfig->{'group'}{$type}; + my $callerid; + my $immediate; + + return if $type eq 'EMPTY'; + die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig; + die "missing context for chan #$num type $type" unless $context; + $callerid = ($type eq 'FXO') + ? 'asreceived' + : sprintf "\"Channel %d\" <%d>", $num, $exten; + if($type eq 'IN') { + $immediate = 'yes'; + } + # FIXME: $immediage should not be set for 'OUT' channels, but meanwhile + # it's better to be compatible with genzaptelconf + $immediate = 'yes' if $gconfig->{'fxs_immediate'} eq 'yes' and $sig =~ /^fxo_/; + my $signalling = $chan->signalling; + $signalling = " " . $signalling if $signalling; + my $info = $chan->info; + $info = " " . $info if $info; + printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info; + printf "signalling=$sig\n"; + printf "callerid=$callerid\n"; + printf "mailbox=%d\n", $exten unless $type eq 'FXO'; + if(defined $group) { + printf "group=$group\n"; + } + printf "context=$context\n"; + printf "immediate=$immediate\n" if defined $immediate; + printf "channel => %d\n", $num; + # Reset following values to default + printf "callerid=\n"; + printf "mailbox=\n" unless $type eq 'FXO'; + if(defined $group) { + printf "group=\n"; + } + printf "context=default\n"; + printf "immediate=no\n" if defined $immediate; + print "\n"; +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "; Autogenerated by $0 on %s\n", scalar(localtime); + print "; If you edit this file and execute $0 again,\n"; + print "; your manual changes will be LOST.\n"; + print <<"HEAD"; +; Dahdi Channels Configurations (chan_dahdi.conf) +; +; This is not intended to be a complete chan_dahdi.conf. Rather, it is intended +; to be #include-d by /etc/chan_dahdi.conf that will include the global settings +; + +HEAD + foreach my $span (@spans) { + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + if($span->is_digital) { + if($span->is_pri) { + if($gconfig->{'pri_connection_type'} eq 'R2') { + $self->gen_openr2($gconfig, $span); + } elsif($gconfig->{'pri_connection_type'} eq 'CAS') { + $self->gen_cas($gconfig, $span); + } else { + $self->gen_digital($gconfig, $span); + } + } elsif($span->is_bri) { + $self->gen_digital($gconfig, $span); + } + } else { + foreach my $chan ($span->chans()) { + if(is_true($genopts->{'freepbx'}) || is_true($gconfig->{'freepbx'})) { + # Freepbx has its own idea about channels + my $type = $chan->type; + if($type eq 'FXS' || $type eq 'OUT' || $type eq 'IN') { + printf "; Skip channel=%s($type) -- freepbx option.\n", + $chan->num; + next; + } + } + $self->gen_channel($chan); + } + } + print "\n"; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +chandahdi - Generate configuration for chan_dahdi channels. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Chandahdi; + + my $cfg = new Dahdi::Config::Gen::Chandahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F +This is used as a configuration for asterisk(1). +It should be included in the main F. + +Its location may be overriden via the environment variable +C. + +=head1 OPTIONS + +=over 4 + +=item freepbx + +With this option we do not generate channel definitions for FXS, Input and +Output ports. This is done because these channel definitions need to be +generated and inserted into I database anyway. + +=back + +The I option may be activated also by adding a C line +to the C file. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm b/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm new file mode 100644 index 0000000..52e7bc9 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Freepbxdb.pm @@ -0,0 +1,116 @@ +package Dahdi::Config::Gen::Freepbxdb; + +# Written by Tzafrir Cohen +# Copyright (C) 2011, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. + +use strict; +use Socket; +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $self = { + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $gconfig->{'base_exten'} + $num; + my $callerid = sprintf "\"Channel %d\" <%04d>", $num, $exten; + my @cmds = (); + #push @cmds, "database put DEVICE/$exten default_user $exten"; + #push @cmds, "database put DEVICE/$exten dial ZAP/$num"; + push @cmds, "database put DEVICE/$exten dial DAHDI/$num"; + #push @cmds, "database put DEVICE/$exten type fixed"; + push @cmds, "database put DEVICE/$exten user $exten"; + push @cmds, "database put AMPUSER/$exten device $exten"; + push @cmds, "database put AMPUSER/$exten cidname $callerid"; + return @cmds; +} + +sub generate($) { + my $self = shift || die; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my $ast_sock = '/var/run/asterisk/asterisk.ctl'; + my @spans = @_; + my @cmds = (); + warn "Empty configuration -- no spans\n" unless @spans; + print "Configuring FXSs for FreePBX\n" if $genopts->{verbose}; + foreach my $span (@spans) { + next if $span->is_digital; + foreach my $chan ($span->chans()) { + next unless ($chan->type eq 'FXS'); + push @cmds, $self->gen_channel($chan); + } + } + #open(CMDS,"|$command >/dev/null") or + socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; + connect(SOCK, sockaddr_un($ast_sock)) || + die "$0: Freepbxdb: Failed connecting to $ast_sock\n: $!"; + foreach (@cmds) { + # Note: commands are NULL-terminated: + print SOCK "$_\0"; + sleep 0.001; + } + close(SOCK) or + die "$0: Freepbxdb: Failed sending commands ($ast_sock): $!\n"; +} + +1; + +__END__ + +=head1 NAME + +freepbxdb - Generate astdb configuration required by FreePBX + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Freepbxdb; + + my $cfg = new Dahdi::Config::Gen::Freepbxdb(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Updates the Asterisk DB entries for FXS channels detected. Requires +Asterisk running. + +The configuration generated here bypasses FreePBX's standard configuration +and allows using a simple dialplan snippet such as: + + [from-internal-custom](+) + exten => _4XXX,1,Dial(DAHDI/${EXTEN:1}) + +This may come in handy in testing. At least until FreePBX will provide a +simple automated interface to do the same. + +=head1 OPTIONS + +None, so far. + +=head1 FILES + +=over + +=item C + +The socket to which commands are sent. FIXME: make this a parameter. + +=back + diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm b/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm new file mode 100644 index 0000000..c00e3eb --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Modules.pm @@ -0,0 +1,62 @@ +package Dahdi::Config::Gen::Modules; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{DAHDI_MODULES_FILE} || "/etc/dahdi/modules"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 (%s) on %s\n", __PACKAGE__, scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + my @drivers = Dahdi::Hardware->drivers; + print join("\n", @drivers),"\n"; + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +modules - Generate list of dahdi drivers to load at startup + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Modules(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. This is a list of modules, one per +line. This list is normally used by F. + +Its location may be overriden via the environment variable +F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm b/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm new file mode 100644 index 0000000..b1914bb --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Spantypes.pm @@ -0,0 +1,86 @@ +package Dahdi::Config::Gen::Spantypes; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{SPAN_TYPES_CONF_FILE} || "/etc/dahdi/span-types.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + + # If the dahdi_span_types utilities were not installed we do not want to run + # this generator or report any errors. + system "which dahdi_span_types > /dev/null 2>&1"; + return if $?; + + my $line_mode = $genopts->{'line-mode'}; + my $cmd; + if (defined $line_mode) { + $line_mode =~ /^[ETJ]1$/ or die "Bad line-mode='$line_mode'\n"; + $cmd = "dahdi_span_types --line-mode=$line_mode dumpconfig > $file"; + printf("Generating $file (with default line-mode %s)\n", $line_mode) + if $genopts->{verbose}; + } else { + $cmd = "dahdi_span_types dumpconfig > $file"; + printf("Generating $file (no --line-mode override)\n") + if $genopts->{verbose}; + } + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + system $cmd; + die "Command failed (status=$?): '$cmd'" if $?; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_span_types. + +Its location may be overriden via the environment variable F. + +You would normally run: + + dahdi_genconf --line-mode= + +which is a short for: + + dahdi_genconf spantypes=line-mode= + +This is done by running: + dahdi_span_types dumpconfig --line-mode=line_mode> + +where I is the module parameter, and defaults to B if not +given (running C). diff --git a/xpp/perl_modules/Dahdi/Config/Gen/System.pm b/xpp/perl_modules/Dahdi/Config/Gen/System.pm new file mode 100644 index 0000000..cb7b14b --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/System.pm @@ -0,0 +1,277 @@ +package Dahdi::Config::Gen::System; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{DAHDI_CONF_FILE} || "/etc/dahdi/system.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +my $bri_te_last_timing = 1; + +sub print_echo_can($$) { + my $gconfig = shift || die; + my $chans = shift || die; # channel or range of channels. + my $echo_can = $gconfig->{'echo_can'}; + return if !defined($echo_can) || $echo_can eq 'none'; + + print "echocanceller=$echo_can,$chans\n"; +} + +sub gen_t1_cas($$) { + my $self = shift || die; + my $gconfig = shift || die; + my $parameters = $gconfig->{PARAMETERS} || die; + my $genconf_file = $parameters->{GENCONF_FILE} || die; + my $span = shift || die; + my $num = $span->num() || die; + my $proto = $span->proto || die; + die "Generate configuration for '$proto' is not possible. Maybe you meant R2?" + unless $proto eq 'T1'; + my $pri_connection_type = $gconfig->{pri_connection_type} || die; + die "Span #$num is analog" unless $span->is_digital(); + die "Span #$num is not CAS" unless $span->is_pri && $pri_connection_type eq 'CAS'; + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $timing; + my $lbo = 0; + my $framing = $gconfig->{tdm_framing}; + if(!defined $framing) { + $framing = 'esf'; + } elsif($framing ne 'esf' && $framing ne 'd4') { + die "T1-CAS valid framing is only 'esf' or 'd4'. Not '$framing'. Check '$genconf_file'\n"; + } + my $coding = $span->coding() || die "$0: No coding information for span #$num\n"; + my $span_crc4 = $span->crc4(); + $span_crc4 = (defined $span_crc4) ? ",$span_crc4" : ''; + my $span_yellow = $span->yellow(); + $span_yellow = (defined $span_yellow) ? ",$span_yellow" : ''; + $timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++; + printf "span=%d,%d,%d,%s,%s%s%s\n", + $num, + $timing, + $lbo, + $framing, + $coding, + $span_crc4, + $span_yellow; + printf "# termtype: %s\n", lc($termtype); + my $dchan_type; + my $chan_range; + if($span->is_pri()) { + if ($pri_connection_type eq 'PRI') { + $chan_range = Dahdi::Config::Gen::bchan_range($span); + printf "bchan=%s\n", $chan_range; + my $dchan = $span->dchan(); + printf "dchan=%d\n", $dchan->num(); + } elsif ($pri_connection_type eq 'R2' ) { + my $idle_bits = $gconfig->{'r2_idle_bits'}; + $chan_range = Dahdi::Config::Gen::bchan_range($span); + printf "cas=%s:$idle_bits\n", $chan_range; + } elsif ($pri_connection_type eq 'CAS' ) { + my $type = ($termtype eq 'TE') ? 'FXO' : 'FXS'; + my $sig = $gconfig->{'dahdi_signalling'}{$type}; + my $em_signalling = $gconfig->{'em_signalling'}; + if ($em_signalling ne 'none') { + $sig = 'e&m'; + # FIXME: but we don't handle E1 yet + $sig = 'e&me1' if $proto eq 'E1'; + } + die "unknown default dahdi signalling for chan $num type $type" unless defined $sig; + $chan_range = Dahdi::Config::Gen::chan_range($span->chans()); + printf "%s=%s\n", $sig, $chan_range; + } + } else { + die "Digital span $num is not PRI"; + } + print_echo_can($gconfig, $chan_range); +} + +sub gen_digital($$$) { + my $self = shift || die; + my $gconfig = shift || die; + my $span = shift || die; + my $num = $span->num() || die; + die "Span #$num is analog" unless $span->is_digital(); + my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n"; + my $timing; + my $lbo = 0; + my $framing = $span->framing() || die "$0: No framing information for span #$num\n"; + my $coding = $span->coding() || die "$0: No coding information for span #$num\n"; + my $span_crc4 = $span->crc4(); + $span_crc4 = (defined $span_crc4) ? ",$span_crc4" : ''; + my $span_yellow = $span->yellow(); + $span_yellow = (defined $span_yellow) ? ",$span_yellow" : ''; + my $span_termination = $span->termination(); + $span_termination = (defined $span_termination) ? ",$span_termination" : ''; + my $span_softntte = $span->softntte(); + $span_softntte = (defined $span_softntte) ? ",$span_softntte" : ''; + # "MFC/R2 does not normally use CRC4" + # FIXME: a finer way to override: + if ($gconfig->{'pri_connection_type'} eq 'R2') { + $span_crc4 = ''; + $framing = 'cas'; + } + $timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++; + printf "span=%d,%d,%d,%s,%s%s%s%s%s\n", + $num, + $timing, + $lbo, + $framing, + $coding, + $span_crc4, + $span_yellow, + $span_termination, + $span_softntte; + printf "# termtype: %s\n", lc($termtype); + my $dchan_type; + if ($span->is_bri()) { + my $use_bristuff = 0; + my $cfg_hardhdlc = $gconfig->{'bri_hardhdlc'}; + my $xpd = Dahdi::Xpp::xpd_of_span($span); + if(!defined($cfg_hardhdlc) || $cfg_hardhdlc =~ /AUTO/i) { + # Autodetect + if(defined($xpd)) { + # Bristuff? + if(defined($xpd->dchan_hardhdlc) && !is_true($xpd->dchan_hardhdlc)) { + $use_bristuff = 1; + } + } + } elsif(!is_true($cfg_hardhdlc)) { + $use_bristuff = 1; + } + if($use_bristuff) { + $dchan_type = 'dchan'; + } else { + $dchan_type = 'hardhdlc'; + } + printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span); + my $dchan = $span->dchan(); + printf "$dchan_type=%d\n", $dchan->num(); + } elsif($span->is_pri()) { + if ($gconfig->{'pri_connection_type'} eq 'PRI') { + printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span); + my $dchan = $span->dchan(); + printf "dchan=%d\n", $dchan->num(); + } elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) { + my $idle_bits = $gconfig->{'r2_idle_bits'}; + printf "cas=%s:$idle_bits\n", Dahdi::Config::Gen::bchan_range($span); + printf "dchan=%d\n", $span->dchan()->num(); + } + } else { + die "Digital span $num is not BRI, nor PRI?"; + } + print_echo_can($gconfig, Dahdi::Config::Gen::bchan_range($span)); +} + +sub gen_signalling($$) { + my $gconfig = shift || die; + my $chan = shift || die; + my $type = $chan->type; + my $num = $chan->num; + + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + if($type eq 'EMPTY') { + printf "# channel %d, %s, no module.\n", $num, $chan->fqn; + return; + } + my $signalling = $gconfig->{'dahdi_signalling'}; + my $sig = $signalling->{$type} || die "unknown default dahdi signalling for chan $num type $type"; + if ($type eq 'IN') { + printf "# astbanktype: input\n"; + } elsif ($type eq 'OUT') { + printf "# astbanktype: output\n"; + } + printf "$sig=$num\n"; + print_echo_can($gconfig, $num); +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 on %s\n", scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + print <<"HEAD"; +# Dahdi Configuration File +# +# This file is parsed by the Dahdi Configurator, dahdi_cfg +# +HEAD + foreach my $span (@spans) { + printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description; + if($span->is_digital) { + if($span->is_pri) { + if($gconfig->{'pri_connection_type'} eq 'CAS') { + $self->gen_t1_cas($gconfig, $span); + } else { + $self->gen_digital($gconfig, $span); + } + } elsif($span->is_bri) { + $self->gen_digital($gconfig, $span); + } + } else { + foreach my $chan ($span->chans()) { + if(1 || !defined $chan->type) { + my $type = $chan->probe_type; + my $num = $chan->num; + die "Failed probing type for channel $num" + unless defined $type; + $chan->type($type); + } + gen_signalling($gconfig, $chan); + } + } + print "\n"; + } + print <<"TAIL"; +# Global data + +loadzone = $gconfig->{'loadzone'} +defaultzone = $gconfig->{'defaultzone'} +TAIL + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +dahdi - Generate configuration for dahdi drivers. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Dahdi; + + my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_cfg(1). + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm b/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm new file mode 100644 index 0000000..cb6bff0 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm @@ -0,0 +1,72 @@ +package Dahdi::Config::Gen::Unicall; +use strict; + +use Dahdi::Config::Gen qw(is_true); + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{UNICALL_CHANNELS_FILE} || "/etc/asterisk/unicall-channels.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + die "Only for R2" unless $gconfig->{'pri_connection_type'} eq 'R2'; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "; Autogenerated by $0 on %s\n", scalar(localtime); + print "; If you edit this file and execute $0 again,\n"; + print "; your manual changes will be LOST.\n"; + print "; This file should be #included in unicall.conf\n\n"; + foreach my $span (@spans) { + next unless $span->is_digital(); + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + my $idle_bits = $gconfig->{'r2_idle_bits'}; + printf "protocolend=%s\n", ($span->termtype() eq 'TE') ? 'cpe' : 'co'; + printf "channel=%s\n", Dahdi::Config::Gen::bchan_range($span); + print "\n"; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +unicall - Generate configuration for unicall channels. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Unicall; + + my $cfg = new Dahdi::Config::Gen::Unicall(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F to be included in +F + +Its location may be overriden via the environment variable +C. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Users.pm b/xpp/perl_modules/Dahdi/Config/Gen/Users.pm new file mode 100644 index 0000000..05a345f --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Users.pm @@ -0,0 +1,227 @@ +package Dahdi::Config::Gen::Users; +use strict; + +use File::Basename; +use Dahdi::Config::Gen qw(is_true); + +# Generate a complete users.conf for the asterisk-gui +# As the asterisk-gui provides no command-line interface of its own and +# no decent support of #include, we have no choice but to nuke users.conf +# if we're to provide a working system + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{USERS_FILE} || "/etc/asterisk/users.conf"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# A single analog trunk for all the FXO channels +sub gen_analog_trunk { + my @fxo_ports = @_; + return unless (@fxo_ports); # no ports + + my $ports = join(',', @fxo_ports); + + print << "EOF" +[trunk_1] +trunkname = analog +hasexten = no +hasiax = no +hassip = no +hasregisteriax = no +hasregistersip = no +trunkstyle = analog +dahdichan = $ports + +EOF +} + +# A digital trunk for a single span. +# FIXME: how do I create the DID context? +sub gen_digital_trunk($) { + my $span = shift; + my $num = $span->num; + my $sig = $span->signalling; + my $type = $span->type; + my $bchan_range = Dahdi::Config::Gen::bchan_range($span); + + print << "EOF"; +[span_$num] +group = $num +hasexten = no +signalling = $sig +trunkname = Span $num $type +trunkstyle = digital ; GUI metadata +hassip = no +hasiax = no +context = DID_span_$num +dahdichan = $bchan_range + +EOF +} + +my $ExtenNum; + +# A single user for a FXS channel +sub gen_channel($$) { + my $self = shift || die; + my $chan = shift || die; + my $gconfig = $self->{GCONFIG}; + my $type = $chan->type; + my $num = $chan->num; + die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital(); + my $exten = $ExtenNum++; + my $sig = $gconfig->{'chan_dahdi_signalling'}{$type}; + my $full_name = "$type $num"; + + die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig; + print << "EOF"; +[$exten] +context = DLPN_DialPlan1 +callwaiting = yes +fullname = $full_name +cid_number = $exten +hasagent = no +hasdirectory = no +hasiax = no +hasmanager = no +hassip = no +hasvoicemail = yes +mailbox = $exten +threewaycalling = yes +vmsecret = $exten +signalling = $sig +dahdichan = $num +registeriax = no +registersip = no +canreinvite = no + +EOF +} + +sub generate($) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + #$gconfig->dump; + my @spans = @_; + warn "Empty configuration -- no spans\n" unless @spans; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + print <<"HEAD"; +;! +;! Automatically generated configuration file +;! Filename: @{[basename($file)]} ($file) +;! Generator: $0 +;! Creation Date: @{[scalar(localtime)]} +;! If you edit this file and execute $0 again, +;! your manual changes will be LOST. +;! +[general] +; +; Starting point of allocation of extensions +; +userbase = @{[$gconfig->{'base_exten'}+1]} +; +; Create voicemail mailbox and use use macro-stdexten +; +hasvoicemail = yes +; +; Set voicemail mailbox @{[$gconfig->{'base_exten'}+1]} password to 1234 +; +vmsecret = 1234 +; +; Create SIP Peer +; +hassip = no +; +; Create IAX friend +; +hasiax = no +; +; Create Agent friend +; +hasagent = no +; +; Create H.323 friend +; +;hash323 = yes +; +; Create manager entry +; +hasmanager = no +; +; Remaining options are not specific to users.conf entries but are general. +; +callwaiting = yes +threewaycalling = yes +callwaitingcallerid = yes +transfer = yes +canpark = yes +cancallforward = yes +callreturn = yes +callgroup = 1 +pickupgroup = 1 +localextenlength = @{[length($gconfig->{'base_exten'})]} + + +HEAD + my @fxo_ports = (); + $ExtenNum = $self->{GCONFIG}->{'base_exten'}; + foreach my $span (@spans) { + printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description; + if ($span->type =~ /^(BRI_(NT|TE)|E1|T1)$/) { + gen_digital_trunk($span); + next; + } + foreach my $chan ($span->chans()) { + if (grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' )) { + $self->gen_channel($chan); + } elsif ($chan->type eq 'FXO') { + # TODO: "$first_chan-$last_chan" + push @fxo_ports,($chan->num); + } + } + print "\n"; + } + gen_analog_trunk(@fxo_ports); + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +users - Generate configuration for users.conf. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Users; + + my $cfg = new Dahdi::Config::Gen::Users(\%global_config, \%genopts); + $cfg->generate(@span_list); + +=head1 DESCRIPTION + +Generate the F which is used by asterisk(1) +and AsteriskGUI. This will replace your entire configuration including +any SIP/IAX users and trunks you may have set. Thus it's probably only +appropriate for an initial setup. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm b/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm new file mode 100644 index 0000000..146b097 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Gen/Xpporder.pm @@ -0,0 +1,142 @@ +package Dahdi::Config::Gen::Xpporder; +use strict; + +use Dahdi::Config::Gen qw(is_true); +use Dahdi::Xpp; + +sub new($$$) { + my $pack = shift || die; + my $gconfig = shift || die; + my $genopts = shift || die; + my $file = $ENV{XPPORDER_CONF} || "/etc/dahdi/xpp_order"; + my $self = { + FILE => $file, + GCONFIG => $gconfig, + GENOPTS => $genopts, + }; + bless $self, $pack; + return $self; +} + +# +# Returns list of xbuses sorted by the span numbers assigned +# to their XPD's. Also checks that each XBUS span numbers are sequential. +sub get_sorted_xbuses(@) { + my @spans = @_; # Verify our spans + my @xbuses = Dahdi::Xpp::xbuses; + my %xbus_of_span; + my %xbus_beginning; + my %seen_spans; + my @sorted_xbuses; + foreach my $xbus (@xbuses) { + my $last_spanno; + foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) { + my $spanno = $xpd->spanno; + if(!$spanno) { + printf STDERR "%s: Is not registered. Skipping.\n", $xpd->fqn; + next; + } + $seen_spans{$spanno}++; + if($xbus_of_span{$spanno}) { + printf STDERR "%s: Span %d already seen on %s\n", + $xpd->fqn, $spanno, $xbus_of_span{$spanno}->name; + die; + } + $xbus_of_span{$spanno} = $xbus; + # Check XPD's sequential numbering + if(defined $last_spanno) { + if($last_spanno + 1 != $spanno) { + printf STDERR "%s: Bad span numbers (%d, %d)\n", + $xpd->fqn, $last_spanno, $spanno; + die; + } + } else { + $xbus_beginning{$xbus} = $spanno; + } + $last_spanno = $spanno; + } + } + foreach my $span (@spans) { + my $spanno = $span->num; + if(!defined($seen_spans{$spanno})) { + warn "Span $spanno: Ignored: Does not belong to any XPD\n"; + } + } + @sorted_xbuses = sort { $xbus_beginning{$a} <=> $xbus_beginning{$b} } @xbuses; + return @sorted_xbuses; +} + +sub generate($$$) { + my $self = shift || die; + my $file = $self->{FILE}; + my $gconfig = $self->{GCONFIG}; + my $genopts = $self->{GENOPTS}; + my @spans = @_; # Verify it's all our spans + my @xbuses = get_sorted_xbuses(@spans); + warn "Empty configuration -- no xbuses\n" unless @xbuses; + rename "$file", "$file.bak" + or $! == 2 # ENOENT (No dependency on Errno.pm) + or die "Failed to backup old config: $!\n"; + #$gconfig->dump; + print "Generating $file\n" if $genopts->{verbose}; + open(F, ">$file") || die "$0: Failed to open $file: $!\n"; + my $old = select F; + printf "# Autogenerated by $0 on %s\n", scalar(localtime); + print "# If you edit this file and execute $0 again,\n"; + print "# your manual changes will be LOST.\n"; + print <<'HEAD'; +# +# This is an optional configuration file for ordering +# Dahdi registration. +# +# It is read from /etc/dahdi/xpp_order. This location +# may be overridden via the environment variable XPPORDER_CONF +# +# Lines may contain: +# - The Astribank label (verbatim) +# - The Astribank connector string (prefixed with @) +# Ordering number of each listed Astribank is determined +# by its position in this file. +# Astribanks not listed in this file, get an ordering +# number of 99 (last). +# +# Astribanks with same ordering number are sorted by their +# connectors (to preserve legacy behavior). +# +# Examples: +#usb:1234 +#@usb-0000:06:02.2-2 +HEAD + foreach my $xbus (@xbuses) { + my $label = $xbus->label; + my $connector = $xbus->connector; + my $name = $xbus->name; + printf "%s\t# %s #(%s)\n", $label, $connector, $name; + } + close F; + select $old; +} + +1; + +__END__ + +=head1 NAME + +Xpporder - Generate Astribank ordering information for dahdi_registration. + +=head1 SYNOPSIS + + use Dahdi::Config::Gen::Xpporder; + + my $cfg = new Dahdi::Config::Gen::Xpporder(\%global_config, \%genopts); + $cfg->generate; + +=head1 DESCRIPTION + +Generate the F. +This is the configuration for dahdi_registration(1). +The order is determined according to current Dahdi registration +order. + +Its location may be overriden via the environment variable F. diff --git a/xpp/perl_modules/Dahdi/Config/Params.pm b/xpp/perl_modules/Dahdi/Config/Params.pm new file mode 100644 index 0000000..0cc0d88 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Config/Params.pm @@ -0,0 +1,156 @@ +package Dahdi::Config::Params; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; + +=head1 NAME + +Dahdi::Config::Params -- Object oriented representation of F file. + +=head1 SYNOPSIS + + use Dahdi::Config::Params; + my $params = Dahdi::Config::Params->new('the-config-file'); + print $params->item{'some-key'}; + print $params->item{'some-key', NODEFAULTS => 1}; + $params->dump; # For debugging + +=head1 DESCRIPTION + +The constructor must be given a configuration file name: + +=over 4 + +=item * Missing file is B an error. + +=item * Other opening errors cause a C to be thrown. + +=item * The file name is saved as the value of C key. + +=back + +The access to config keys should only be done via the C method: + +=over 4 + +=item * It contains all hard-coded defaults. + +=item * All these values are overriden by directives in the config file. + +=item * Calling it with C 1> option, returns C for keys that +do not appear in the configuration file. + +=back + +=cut + +sub new($$) { + my $pack = shift || die; + my $cfg_file = shift || die; + my $self = { + GENCONF_FILE => $cfg_file, + }; + bless $self, $pack; + if(!open(F, $cfg_file)) { + if(defined($!{ENOENT})) { + #print STDERR "No $cfg_file. Assume empty config\n"; + return $self; # Empty configuration + } + die "$pack: Failed to open '$cfg_file': $!\n"; + } + #print STDERR "$pack: $cfg_file\n"; + my $array_key; + while() { + my ($key, $val); + chomp; + s/#.*$//; + s/\s+$//; # trim tail whitespace + next unless /\S/; + if(defined $array_key && /^\s+/) { + s/^\s+//; # trim beginning whitespace + push(@{$self->{$array_key}}, $_); + next; + } + undef $array_key; + ($key, $val) = split(/\s+/, $_, 2); + $key = lc($key); + if(! defined $val) { + $array_key = $key; + next; + } + die "$cfg_file:$.: Duplicate key '$key'\n", if exists $self->{$key}; + $self->{$key} = $val; + } + close F; + return $self; +} + +sub item($$@) { + my $self = shift || die; + my $key = shift || die; + my %options = @_; + my %defaults = ( + base_exten => '4000', + freepbx => 'no', # Better via -F command line + fxs_immediate => 'no', + fxs_default_start => 'ks', + fxo_default_start => 'ks', + em_signalling => 'none', + lc_country => 'us', + context_lines => 'from-pstn', + context_phones => 'from-internal', + context_input => 'astbank-input', + context_output => 'astbank-output', + group_phones => '5', + group_lines => '0', + brint_overlap => 'no', + bri_sig_style => 'bri_ptmp', + echo_can => 'mg2', + bri_hardhdlc => 'auto', + pri_connection_type => 'PRI', + r2_idle_bits => '1101', + tdm_framing => 'esf', + 'pri_termtype' => [ 'SPAN/* TE' ], + ); + return $self->{$key} if exists($self->{$key}) or $options{NODEFAULTS}; + return $defaults{$key}; +} + +sub dump($) { + my $self = shift || die; + printf STDERR "%s dump:\n", ref $self; + my $width = 30; + foreach my $k (sort keys %$self) { + my $val = $self->{$k}; + my $ref = ref $val; + #print STDERR "DEBUG: '$k', '$ref', '$val'\n"; + if($ref eq '') { + printf STDERR "%-${width}s %s\n", $k, $val; + } elsif($ref eq 'SCALAR') { + printf STDERR "%-${width}s %s\n", $k, ${$val}; + } elsif($ref eq 'ARRAY') { + #printf STDERR "%s:\n", $k; + my $i = 0; + foreach my $v (@{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->[$i]", $v; + $i++; + } + } elsif($ref eq 'HASH') { + #printf STDERR "%s:\n", $k; + foreach my $k1 (keys %{$val}) { + printf STDERR "%-${width}s %s\n", "$k\->\{$k1\}", ${$val}{$k1}; + } + } else { + printf STDERR "%-${width}s (-> %s)\n", $k, $ref; + } + } +} + +1; + diff --git a/xpp/perl_modules/Dahdi/Hardware.pm b/xpp/perl_modules/Dahdi/Hardware.pm new file mode 100644 index 0000000..ba89447 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware.pm @@ -0,0 +1,235 @@ +package Dahdi::Hardware; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; + +=head1 NAME + +Dahdi::Hardware - Perl interface to a Dahdi devices listing + + + use Dahdi::Hardware; + + my $hardware = Dahdi::Hardware->scan; + + # mini dahdi_hardware: + foreach my $device ($hardware->device_list) { + print "Vendor: device->{VENDOR}, Product: $device->{PRODUCT}\n" + } + + # let's see if there are devices without loaded drivers, and sugggest + # drivers to load: + my @to_load = (); + foreach my $device ($hardware->device_list) { + if (! $device->{LOADED} ) { + push @to_load, ($device->${DRIVER}); + } + } + if (@to_load) { + print "To support the extra devices you probably need to run:\n" + print " modprobe ". (join ' ', @to_load). "\n"; + } + + +This module provides information about available Dahdi devices on the +system. It identifies devices by (USB/PCI) bus IDs. + + +=head1 Device Attributes + +As usual, object attributes can be used in either upp-case or +lower-case, or lower-case functions. + +=head2 bus_type + +'PCI' or 'USB'. + + +=head2 description + +A one-line description of the device. + + +=head2 driver + +Name of a Dahdi device driver that should handle this device. This is +based on a pre-made list. + + +=head2 vendor, product, subvendor, subproduct + +The PCI and USB vendor ID, product ID, sub-vendor ID and sub-product ID. +(The standard short lspci and lsusb listings show only vendor and +product IDs). + + +=head2 loaded + +If the device is handled by a module - the name of the module. Else - +undef. + + +=head2 priv_device_name + +A string that shows the "location" of that device on the bus. + + +=head2 is_astribank + +True if the device is a Xorcom Astribank (which may provide some extra +attributes). + +=head2 serial + +(Astribank-specific attrribute) - the serial number string of the +Astribank. + +=cut +# +# A global hardware handle +# + +my %hardware_list = ( + 'PCI' => [], + 'USB' => [], + ); + + +sub new($$) { + my $pack = shift || die "Wasn't called as a class method\n"; + my $name = shift || die "$0: Missing device name"; + my $type = shift || die "$0: Missing device type"; + my $dev = {}; + $dev->{'BUS_TYPE'} = $type; + $dev->{IS_ASTRIBANK} = 0 unless defined $dev->{'IS_ASTRIBANK'}; + $dev->{'HARDWARE_NAME'} = $name; + return $dev; +} + +=head1 device_list() + +Returns a list of the hardware devices on the system. + +You must run scan() first for this function to run meaningful output. + +=cut + +sub device_list($) { + my $pack = shift || die; + my @types = @_; + my @list; + + @types = qw(USB PCI) unless @types; + foreach my $t (@types) { + my $lst = $hardware_list{$t}; + @list = ( @list, @{$lst} ); + } + return @list; +} + +sub device_by_hwname($$) { + my $pack = shift || die; + my $name = shift || die; + my @list = device_list('localcall'); + + my @good = grep { $_->hardware_name eq $name } @list; + return undef unless @good; + @good > 1 && die "$pack: Multiple matches for '$name': @good"; + return $good[0]; +} + +=head1 drivers() + +Returns a list of drivers (currently sorted by name) that are used by +the devices in the current system (regardless to whether or not they are +loaded. + +=cut + +sub drivers($) { + my $self = shift || die; + my @devs = device_list('localcall'); + my @drvs = map { $_->{DRIVER} } @devs; + # Make unique + my %drivers; + @drivers{@drvs} = 1; + return sort keys %drivers; +} + + +=head1 scan() + +Scan the system for Dahdi devices (PCI and USB). Returns nothing but +must be run to initialize the module. + +=cut + +my $hardware_scanned; + +sub scan($) { + my $pack = shift || die; + + return if $hardware_scanned++; + foreach my $type (qw(PCI USB)) { + eval "use Dahdi::Hardware::$type"; + die $@ if $@; + $hardware_list{$type} = [ "Dahdi::Hardware::$type"->scan_devices ]; + } +} + +=head1 rescan + +Rescan for devices. In case new devices became available since the script +has started. + +=cut + +sub rescan($) { + my $pack = shift || die; + + $hardware_scanned = 0; + $pack->scan(); +} + +sub import { + Dahdi::Hardware->scan unless grep(/\bnoscan\b/i, @_); +} + +sub showall { + my $pack = shift || die; + my @devs; + + my $printer = sub { + my $title = shift; + my @devs = @_; + + return unless @devs; + printf "%s:\n", $title; + foreach my $dev (@devs) { + printf "\t%s\n", $dev->hardware_name; + foreach my $k (sort keys %{$dev}) { + my $v = $dev->{$k}; + if($k eq 'MPPINFO') { + printf "\t\tMPPINFO:\n"; + eval "use Dahdi::Xpp::Mpp"; + die $@ if $@; + $v->showinfo("\t\t "); + } else { + printf "\t\t%-20s %s\n", $k, $v; + } + } + } + }; + foreach my $type (qw(USB PCI)) { + my $lst = $hardware_list{$type}; + &$printer("$type devices", @{$lst}); + } +} + +1; diff --git a/xpp/perl_modules/Dahdi/Hardware/PCI.pm b/xpp/perl_modules/Dahdi/Hardware/PCI.pm new file mode 100644 index 0000000..aa4de51 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware/PCI.pm @@ -0,0 +1,261 @@ +package Dahdi::Hardware::PCI; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; + +our @ISA = qw(Dahdi::Hardware); + +# Lookup algorithm: +# First match 'vendor:product/subvendor:subproduct' key +# Else match 'vendor:product/subvendor' key +# Else match 'vendor:product' key +# Else not a dahdi hardware. +my %pci_ids = ( + # from wct4xxp + '10ee:0314' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P/TE405P (1st Gen)' }, + 'd161:1420' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE420 (5th Gen)' }, + 'd161:1410' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (5th Gen)' }, + 'd161:1405' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (5th Gen)' }, + 'd161:0420/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE420 (4th Gen)' }, + 'd161:0410/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (4th Gen)' }, + 'd161:0405/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (4th Gen)' }, + 'd161:0410/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (3rd Gen)' }, + 'd161:0405/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (3rd Gen)' }, + 'd161:0410' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE410P (2nd Gen)' }, + 'd161:0405' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE405P (2nd Gen)' }, + 'd161:1220' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE220 (5th Gen)' }, + 'd161:1205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (5th Gen)' }, + 'd161:1210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (5th Gen)' }, + 'd161:0220/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE220 (4th Gen)' }, + 'd161:0205/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (4th Gen)' }, + 'd161:0210/0004' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (4th Gen)' }, + 'd161:0205/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P (3rd Gen)' }, + 'd161:0210/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (3rd Gen)' }, + 'd161:0205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P ' }, + 'd161:0210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P ' }, + 'd161:1820' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE820 (5th Gen)' }, + + # from wctdm24xxp + 'd161:2400' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM2400P' }, + 'd161:0800' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM800P' }, + 'd161:8002' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX800' }, + 'd161:8003' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX2400' }, + 'd161:8005' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM410P' }, + 'd161:8006' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard AEX410P' }, + 'd161:8007' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'HA8-0000' }, + 'd161:8008' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'HB8-0000' }, + + # from pciradio + 'e159:0001/e16b' => { DRIVER => 'pciradio', DESCRIPTION => 'PCIRADIO' }, + + # from wcfxo + 'e159:0001/8084' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + 'e159:0001/8085' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P' }, + 'e159:0001/8086' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + 'e159:0001/8087' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X101P clone' }, + '1057:5608' => { DRIVER => 'wcfxo', DESCRIPTION => 'Wildcard X100P' }, + + # from wct1xxp + 'e159:0001/6159' => { DRIVER => 'wct1xxp', DESCRIPTION => 'Digium Wildcard T100P T1/PRI or E100P E1/PRA Board' }, + + # from wctdm + 'e159:0001/a159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/e159' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard S400P Prototype' }, + 'e159:0001/b100' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV E/F' }, + 'e159:0001/b1d9' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b118' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/b119' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV I' }, + 'e159:0001/a9fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a8fd' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a800' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a801' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a908' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + 'e159:0001/a901' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + #'e159:0001' => { DRIVER => 'wctdm', DESCRIPTION => 'Wildcard TDM400P REV H' }, + + # from wcte11xp + 'e159:0001/71fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79fe' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/795e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/79de' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + 'e159:0001/797e' => { DRIVER => 'wcte11xp', DESCRIPTION => 'Digium Wildcard TE110P T1/E1 Board' }, + + # from wcte12xp + 'd161:0120' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE12xP' }, + 'd161:8000' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE121' }, + 'd161:8001' => { DRIVER => 'wcte12xp', DESCRIPTION => 'Wildcard TE122' }, + + # from wcte13xp + 'd161:800a' => { DRIVER => 'wcte13xp', DESCRIPTION => 'Wildcard TE131/TE133' }, + 'd161:800b' => { DRIVER => 'wcte13xp', DESCRIPTION => 'Wildcard TE132/TE134' }, + + # from wcaxx + 'd161:800c' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A8A' }, + 'd161:800d' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A8B' }, + 'd161:800f' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A4A' }, + 'd161:8010' => { DRIVER => 'wcaxx', DESCRIPTION => 'Digium A4B' }, + + # from wcte435/235 + 'd161:800e' => { DRIVER => 'wcte43x', DESCRIPTION => 'Wildcard TE435/235' }, + 'd161:8013' => { DRIVER => 'wcte43x', DESCRIPTION => 'Wildcard TE436/236' }, + + # from wcb4xxp + 'd161:b410' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B410P' }, + + # from tor2 + '10b5:9030' => { DRIVER => 'tor2', DESCRIPTION => 'PLX 9030' }, + '10b5:3001' => { DRIVER => 'tor2', DESCRIPTION => 'PLX Development Board' }, + '10b5:d00d' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/PRI or E1/PRA' }, + '10b5:4000' => { DRIVER => 'tor2', DESCRIPTION => 'Tormenta 2 Quad T1/E1 (non-Digium clone)' }, + + # # from wctc4xxp + 'd161:3400' => { DRIVER => 'wctc4xxp', DESCRIPTION => 'Wildcard TC400P' }, + 'd161:8004' => { DRIVER => 'wctc4xxp', DESCRIPTION => 'Wildcard TCE400P' }, + + # Cologne Chips: + # (Still a partial list) + '1397:08b4/1397:b540' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Swyx 4xS0 SX2 QuadBri' }, + '1397:08b4/1397:b556' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns DuoBRI ISDN card' }, + '1397:08b4/1397:b520' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN card' }, + '1397:08b4/1397:b550' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN card' }, + '1397:08b4/1397:b752' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns QuadBRI ISDN PCI-E card' }, + '1397:16b8/1397:b552' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns OctoBRI ISDN card' }, + '1397:16b8/1397:b55b' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Junghanns OctoBRI ISDN card' }, + '1397:08b4/1397:e884' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B200P' }, + '1397:08b4/1397:e888' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B400P' }, + '1397:16b8/1397:e998' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'OpenVox B800P' }, + '1397:08b4/1397:b566' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN2S0' }, + '1397:08b4/1397:b560' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN4S0' }, + '1397:08b4/1397:b762' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN4S0 PCI-E card' }, + '1397:16b8/1397:b562' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'BeroNet BN8S0' }, + '1397:08b4' => { DRIVER => 'qozap', DESCRIPTION => 'Generic Cologne ISDN card' }, + '1397:16b8' => { DRIVER => 'qozap', DESCRIPTION => 'Generic OctoBRI ISDN card' }, + '1397:30b1' => { DRIVER => 'cwain', DESCRIPTION => 'HFC-E1 ISDN E1 card' }, + '1397:2bd0' => { DRIVER => 'zaphfc', DESCRIPTION => 'HFC-S ISDN BRI card' }, + # Has three submodels. Tested with 0675:1704: + '1043:0675' => { DRIVER => 'zaphfc', DESCRIPTION => 'ASUSTeK Computer Inc. ISDNLink P-IN100-ST-D' }, + '1397:f001' => { DRIVER => 'ztgsm', DESCRIPTION => 'HFC-GSM Cologne Chips GSM' }, + + # Rhino cards (based on pci.ids) + '0b0b:0105' => { DRIVER => 'r1t1', DESCRIPTION => 'Rhino R1T1' }, + '0b0b:0205' => { DRIVER => 'r4fxo', DESCRIPTION => 'Rhino R14FXO' }, + '0b0b:0206' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB4FXO 4-channel FXO analog telphony card' }, + '0b0b:0305' => { DRIVER => 'rxt1', DESCRIPTION => 'Rhino R4T1' }, + '0b0b:0405' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R8FXX' }, + '0b0b:0406' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB8FXX 8-channel modular analog telphony card' }, + '0b0b:0505' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R24FXX' }, + '0b0b:0506' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXS 24-Channel FXS analog telphony card' }, + '0b0b:0605' => { DRIVER => 'rxt1', DESCRIPTION => 'Rhino R2T1' }, + '0b0b:0705' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R24FXS' }, + '0b0b:0706' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXO 24-Channel FXO analog telphony card' }, + '0b0b:0906' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB24FXX 24-channel modular analog telphony card' }, + + # Sangoma cards (based on pci.ids) + '1923:0040' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A200/Remora FXO/FXS Analog AFT card' }, + '1923:0100' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A104d QUAD T1/E1 AFT card' }, + '1923:0300' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A101 single-port T1/E1' }, + '1923:0400' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma Technologies Corp. A104u Quad T1/E1 AFT' }, + + # Yeastar (from output of modinfo): + 'e159:0001/2151' => { DRIVER => 'ystdm8xx', DESCRIPTION => 'Yeastar YSTDM8xx'}, + + 'e159:0001/9500:0003' => { DRIVER => 'opvxa1200', DESCRIPTION => 'OpenVox A800P' }, + + # Aligera + '10ee:1004' => { DRIVER => 'ap400', DESCRIPTION => 'Aligera AP40X/APE40X 1E1/2E1/4E1 card' }, + ); + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; + +sub pci_sorter { + return $a->priv_device_name() cmp $b->priv_device_name(); +} + +sub new($@) { + my $pack = shift || die "Wasn't called as a class method\n"; + my %attr = @_; + my $name = sprintf("pci:%s", $attr{PRIV_DEVICE_NAME}); + my $self = Dahdi::Hardware->new($name, 'PCI'); + %{$self} = (%{$self}, %attr); + bless $self, $pack; + return $self; +} + +my %pci_devs; + +sub readfile($) { + my $name = shift || die; + open(F, $name) || die "Failed to open '$name': $!"; + my $str = ; + close F; + chomp($str); + return $str; +} + +sub scan_devices($) { + my @devices; + + while(<$Dahdi::sys_base/bus/pci/devices/*>) { + m,([^/]+)$,,; + my $name = $1; + my $l = readlink $_ || die; + $pci_devs{$name}{PRIV_DEVICE_NAME} = $name; + $pci_devs{$name}{DEVICE} = $l; + $pci_devs{$name}{VENDOR} = readfile "$_/vendor"; + $pci_devs{$name}{PRODUCT} = readfile "$_/device"; + $pci_devs{$name}{SUBVENDOR} = readfile "$_/subsystem_vendor"; + $pci_devs{$name}{SUBPRODUCT} = readfile "$_/subsystem_device"; + my $dev = $pci_devs{$name}; + grep(s/0x//, $dev->{VENDOR}, $dev->{PRODUCT}, $dev->{SUBVENDOR}, $dev->{SUBPRODUCT}); + $pci_devs{$name}{DRIVER} = ''; + } + + while(<$Dahdi::sys_base/bus/pci/drivers/*/[0-9]*>) { + m,^(.*?)/([^/]+)/([^/]+)$,; + my $prefix = $1; + my $drvname = $2; + my $id = $3; + my $l = readlink "$prefix/$drvname/module"; + # Find the real module name (if we can). + if(defined $l) { + my $moduledir = "$prefix/$drvname/$l"; + my $modname = $moduledir; + $modname =~ s:^.*/::; + $drvname = $modname; + } + $pci_devs{$id}{LOADED} = $drvname; + } + foreach (sort keys %pci_devs) { + my $dev = $pci_devs{$_}; + my $key; + # Try to match + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}:$dev->{SUBPRODUCT}"; + $key = "$dev->{VENDOR}:$dev->{PRODUCT}/$dev->{SUBVENDOR}" if !defined($pci_ids{$key}); + $key = "$dev->{VENDOR}:$dev->{PRODUCT}" if !defined($pci_ids{$key}); + next unless defined $pci_ids{$key}; + + my $d = Dahdi::Hardware::PCI->new( + PRIV_DEVICE_NAME => $dev->{PRIV_DEVICE_NAME}, + VENDOR => $dev->{VENDOR}, + PRODUCT => $dev->{PRODUCT}, + SUBVENDOR => $dev->{SUBVENDOR}, + SUBPRODUCT => $dev->{SUBPRODUCT}, + LOADED => $dev->{LOADED}, + DRIVER => $pci_ids{$key}{DRIVER}, + DESCRIPTION => $pci_ids{$key}{DESCRIPTION}, + ); + push(@devices, $d); + } + @devices = sort pci_sorter @devices; + return @devices; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Hardware/USB.pm b/xpp/perl_modules/Dahdi/Hardware/USB.pm new file mode 100644 index 0000000..c9f2ada --- /dev/null +++ b/xpp/perl_modules/Dahdi/Hardware/USB.pm @@ -0,0 +1,221 @@ +package Dahdi::Hardware::USB; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; + +our @ISA = qw(Dahdi::Hardware); + +my %usb_ids = ( + # from wcusb + '06e6:831c' => { DRIVER => 'wcusb', DESCRIPTION => 'Wildcard S100U USB FXS Interface' }, + '06e6:831e' => { DRIVER => 'wcusb2', DESCRIPTION => 'Wildcard S110U USB FXS Interface' }, + '06e6:b210' => { DRIVER => 'wc_usb_phone', DESCRIPTION => 'Wildcard Phone Test driver' }, + + # from xpp_usb + 'e4e4:1130' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 no-firmware' }, + 'e4e4:1131' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 USB-firmware' }, + 'e4e4:1132' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-8/16 FPGA-firmware' }, + 'e4e4:1140' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI no-firmware' }, + 'e4e4:1141' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI USB-firmware' }, + 'e4e4:1142' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-BRI FPGA-firmware' }, + 'e4e4:1150' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi no-firmware' }, + 'e4e4:1151' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi USB-firmware' }, + 'e4e4:1152' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-multi FPGA-firmware' }, + 'e4e4:1160' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular no-firmware' }, + 'e4e4:1161' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular USB-firmware' }, + 'e4e4:1162' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular FPGA-firmware' }, + 'e4e4:1163' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-TwinStar monitor' }, + 'e4e4:1164' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-EEPROM burner' }, + + # Sangoma USB FXO: + '10c4:8461' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma WANPIPE USB-FXO Device' }, + ); + + +$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin"; + +sub usb_sorter() { + return $a->hardware_name cmp $b->hardware_name; +} + +sub mpp_addinfo($) { + my $self = shift || die; + + my $mppinfo = Dahdi::Xpp::Mpp->new($self); + $self->{MPPINFO} = $mppinfo if defined $mppinfo; +} + +sub new($@) { + my $pack = shift or die "Wasn't called as a class method\n"; + my %attr = @_; + my $name = sprintf("usb:%s", $attr{PRIV_DEVICE_NAME}); + my $self = Dahdi::Hardware->new($name, 'USB'); + %{$self} = (%{$self}, %attr); + bless $self, $pack; + return $self; +} + +sub readval($) { + my $fname = shift || warn; + open(F, $fname) || warn "Failed opening '$fname': $!"; + my $val = ; + close F; + chomp $val; + warn "$fname is empty" unless defined $val and $val; + return $val; +} + +sub set_transport($$) { + my $pack = shift || die; + my $xbus = shift || die; + my $xbus_dir = shift; + my $transportdir = "$xbus_dir/transport"; + if(! -e "$transportdir/ep_00") { + warn "A trasnport in '$transportdir' is not USB"; + return undef; + } + my ($usbdev) = glob("$transportdir/usb_device:*"); + my $busnum; + my $devnum; + # Different kernels... + if(defined $usbdev) { # It's USB + if($usbdev =~ /.*usb_device:usbdev(\d+)\.(\d+)/) { + $busnum = $1; + $devnum = $2; + } else { + warn "Bad USB transportdir='$transportdir' usbdev='$usbdev'\n"; + } + } elsif(-f "$transportdir/idVendor" ) { + my $transport_link = readlink($transportdir); + $transport_link =~ m|/(\d+)-[\d.]+$|; + $busnum = $1; + $devnum = readval("$transportdir/devnum"); + } + my $usbname = sprintf("%03d/%03d", $busnum, $devnum); + #printf STDERR "DEBUG: %03d/%03d\n", $busnum, $devnum; + $xbus->{USB_DEVNAME} = $usbname; + my $hwdev = Dahdi::Hardware->device_by_hwname("usb:$usbname"); + if(defined $hwdev) { + #print "set_transport: ", $hwdev, "\n"; + $xbus->{TRANSPORT} = $hwdev; + $hwdev->{XBUS} = $xbus; + $hwdev->{LOADED} = 'xpp_usb'; + $xbus->{IS_TWINSTAR} = $hwdev->is_twinstar; + } + return $hwdev; +} + +sub _get_attr($) { + my $attr_file = shift; + + open(ATTR, $attr_file) or die "Failed to read SysFS attribute $attr_file\n"; + my $value = ; + chomp $value; + return $value; +} + +sub _get_attr_optional($$) { + my ($attr_file, $def_val) = @_; + + eval {return _get_attr($attr_file)}; + + # If we got here, _get_attr exploded. Return the default value: + return $def_val; +} + +sub scan_devices_sysfs($) { + my $pack = shift || die; + my @devices = (); + + while (<$Dahdi::sys_base/bus/usb/devices/*-*>) { + next unless -r "$_/idVendor"; # endpoints + + # Older kernels, e.g. 2.6.9, don't have the attribute + # busnum: + m|/((\d+)-[\d.]+)$|; + my $busnum = $2 || next; + my $dev_sys_name = $1; + my $vendor = _get_attr("$_/idVendor"); + my $product = _get_attr("$_/idProduct"); + my $model = $usb_ids{"$vendor:$product"}; + next unless defined $model; + my $devnum = _get_attr("$_/devnum"); + my $serial = _get_attr_optional("$_/serial", ''); + my $devname = sprintf("%03d/%03d", $busnum, $devnum); + # Get driver for first interface of the device: + my $iface = "$_/$dev_sys_name:1.0"; + my $loaded = readlink("$iface/driver"); + if (defined $loaded) { + $loaded =~ s|.*/||; + } + my $d = Dahdi::Hardware::USB->new( + IS_ASTRIBANK => ($model->{DRIVER} eq 'xpp_usb')?1:0, + PRIV_DEVICE_NAME => $devname, + VENDOR => $vendor, + PRODUCT => $product, + SERIAL => $serial, + DESCRIPTION => $model->{DESCRIPTION}, + DRIVER => $model->{DRIVER}, + LOADED => $loaded, + ); + push(@devices, $d); + } + return @devices; +} + +sub scan_devices($) { + my $pack = shift || die; + my $usb_device_list = "$Dahdi::proc_usb_base/devices"; + return $pack->scan_devices_sysfs() unless (-r $usb_device_list); + + my @devices; + open(F, $usb_device_list) || die "Failed to open $usb_device_list: $!"; + local $/ = ''; + while() { + my @lines = split(/\n/); + my ($tline) = grep(/^T/, @lines); + my ($pline) = grep(/^P/, @lines); + my ($dline) = grep(/^I/, @lines); + my ($sline) = grep(/^S:.*SerialNumber=/, @lines); + my ($busnum,$devnum) = ($tline =~ /Bus=(\w+)\W.*Dev#=\s*(\w+)\W/); + my $devname = sprintf("%03d/%03d", $busnum, $devnum); + my ($vendor,$product) = ($pline =~ /Vendor=(\w+)\W.*ProdID=(\w+)\W/); + my $serial; + if(defined $sline) { + $sline =~ /SerialNumber=(.*)/; + $serial = $1; + #$serial =~ s/[[:^print:]]/_/g; + } + my $loaded; + if ($dline =~ /Driver=(\w+)/) { + $loaded = $1; + } + my $model = $usb_ids{"$vendor:$product"}; + next unless defined $model; + my $d = Dahdi::Hardware::USB->new( + IS_ASTRIBANK => ($model->{DRIVER} eq 'xpp_usb')?1:0, + PRIV_DEVICE_NAME => $devname, + VENDOR => $vendor, + PRODUCT => $product, + SERIAL => $serial, + DESCRIPTION => $model->{DESCRIPTION}, + DRIVER => $model->{DRIVER}, + LOADED => $loaded, + ); + push(@devices, $d); + } + close F; + @devices = sort usb_sorter @devices; + return @devices; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Span.pm b/xpp/perl_modules/Dahdi/Span.pm new file mode 100644 index 0000000..69c5d03 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Span.pm @@ -0,0 +1,420 @@ +package Dahdi::Span; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Chans; + +=head1 NAME + +Dahdi::Spans - Perl interface to a Dahdi span information + +This package allows access from perl to information about a Dahdi +channel. It is part of the Dahdi Perl package. + +A span is a logical unit of Dahdi channels. Normally a port in a +digital card or a whole analog card. + +See documentation of module L for usage example. Specifically +C must be run initially. + +=head1 by_number() + +Get a span by its Dahdi span number. + +=head1 Span Properties + +=head2 num() + +The span number. + +=head2 name() + +The name field of a Dahdi span. E.g.: + + TE2/0/1 + +=head2 description() + +The description field of the span. e.g: + + "T2XXP (PCI) Card 0 Span 1" HDB3/CCS/CRC4 RED + +=head2 chans() + +The list of the channels (L objects) of this span. +In a scalar context returns the number of channels this span has. + +=head2 bchans() + +Likewise a list of bchannels (or a count in a scalar context). + +=head2 is_sync_master() + +Is this span the source of timing for Dahdi? + +=head2 type() + +Type of span, or "UNKNOWN" if could not be detected. Current known +types: + +BRI_TE, BRI_NT, E1_TE, E1_NT, J1_TE, J1_NT, T1_TE, T1_NT, FXS, FXO + +=head2 is_pri() + +Is this an E1/J1/T1 span? + +=head2 is_bri() + +Is this a BRI span? + +=head2 is_digital() + +Is this a digital (as opposed to analog) span? + +=head2 termtype() + +Set for digital spans. "TE" or "NT". Will probably be assumed to be "TE" +if there's no information pointing either way. + +=head2 coding() + +Suggested sane coding type (e.g.: "hdb3", "b8zs") for this type of span. + +=head2 framing() + +Suggested sane framing type (e.g.: "ccs", "esf") for this type of span. + +=head2 yellow(), crc4() + +Likewise, suggestions ofr the respective fields in the span= line in +/etc/dahdi/system.conf for this span. + +=head2 signalling() + +Suggested chan_dahdi.conf signalling for channels of this span. + +=head2 switchtype() + +Suggested chan_dahdi.conf switchtype for channels of this span. + +=head1 Note + +Most of those properties are normally used as lower-case functions, but +actually set in the module as capital-letter propeties. To look at e.g. +"signalling" is set, look for "SIGNALLING". + +=cut + +sub chans($) { + my $span = shift; + return @{$span->{CHANS}}; +} + +sub by_number($) { + my $span_number = shift; + die "Missing span number" unless defined $span_number; + my @spans = Dahdi::spans(); + + my ($span) = grep { $_->num == $span_number } @spans; + return $span; +} + +my @bri_strings = ( + 'BRI_(NT|TE)', + '(?:quad|octo)BRI PCI ISDN Card.* \[(NT|TE)\]', + 'octoBRI \[(NT|TE)\] ', + 'HFC-S PCI A ISDN.* \[(NT|TE)\] ', + '(B4XXP) \(PCI\) Card', # Use dahdi_scan to determine TE/NT mode + '(WCBRI)', # has selectable NT/TE modes via dahdi_cfg + ); + +my @pri_strings = ( + 'Tormenta 2 .*Quad (E1|T1)', # tor2. + 'Xorcom XPD.*: (E1|T1)', # Astribank PRI + 'Digium Wildcard .100P (T1|E1)/', # wct1xxp + 'ISA Tormenta Span 1', # torisa + 'TE110P T1/E1', # wcte11xp + 'Wildcard TE120P', # wcte12xp + 'Wildcard TE121', # wcte12xp + 'Wildcard TE122', # wcte12xp + 'Wildcard TE131/TE133', # wcte13xp + 'Wildcard TE132/TE134', # wcte13xp + 'T[248]XXP \(PCI\) Card ', # wct4xxp + 'WCTE43X \(PCI\) Card ', # wcte43xp + 'WCTE23X \(PCI\) Card ', # wcte43xp + 'R[24]T1 \(PCI\) Card', # rxt1 + 'Rhino R1T1 (E1)/PRA Card', # r1t1 + 'Rhino R1T1 (T1)/PRI Card', # r1t1 + 'WP(E1|T1)/.* "wanpipe', # Sangoma E1/T1 + ); + +my @soft_term_type_strings = ( + 'Xorcom XPD.*: (E1|T1)', # Astribank PRI + '(WCBRI)', # has selectable NT/TE modes via dahdi_cfg +); + +our $DAHDI_BRI_NET = 'bri_net'; +our $DAHDI_BRI_CPE = 'bri_cpe'; + +our $DAHDI_PRI_NET = 'pri_net'; +our $DAHDI_PRI_CPE = 'pri_cpe'; + +sub init_proto($$) { + my $self = shift; + my $proto = shift; + + $self->{PROTO} = $proto; + if($proto eq 'E1') { + $self->{DCHAN_IDX} = 15; + $self->{BCHAN_LIST} = [ 0 .. 14, 16 .. 30 ]; + } elsif($proto eq 'T1') { + $self->{DCHAN_IDX} = 23; + $self->{BCHAN_LIST} = [ 0 .. 22 ]; + } + $self->{TYPE} = "${proto}_$self->{TERMTYPE}"; +} + +sub get_digital_spantype { + my $span_no = shift; + my @lines = split /\n/, `dahdi_scan`; + my $found_span = 0; + foreach my $line (@lines) { + if (! $found_span) { + if ($line =~ m/\[$span_no\]/) { + $found_span = 1; + } + } else { + if ($line !~ m/^\[/) { + if ($line =~ m/digital-(TE|NT)/ ){ + return $1; + } + } else { + $found_span = 0; + } + } + } + die "Cannot determine digital spantype"; +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $proc_file = shift or die "Missing a proc file parameter\n"; + $proc_file =~ m{[^/]*/(\d+)$}; + my $num = $1 or die " Invalid span file name: $proc_file\n"; + my $self = { NUM => $num }; + bless $self, $pack; + $self->{TYPE} = "UNKNOWN"; + open(F, "$proc_file") or die "Failed to open '$proc_file\n"; + my $head = ; + chomp $head; + $self->{IS_DIGITAL} = 0; + $self->{IS_BRI} = 0; + $self->{IS_PRI} = 0; + $self->{TERMTYPE} = "UNKNOWN"; + foreach my $cardtype (@bri_strings) { + if($head =~ m/$cardtype/) { + my $termtype = $1; + if ($1 eq 'B4XXP') { + $termtype = get_digital_spantype($num); + } + if ($1 eq 'WCBRI') { + $termtype = 'TE'; + } + $self->{IS_DIGITAL} = 1; + $self->{IS_BRI} = 1; + $self->{TERMTYPE} = $termtype; + $self->{TYPE} = "BRI_$termtype"; + $self->{DCHAN_IDX} = 2; + $self->{BCHAN_LIST} = [ 0, 1 ]; + $self->init_proto('BRI'); + last; + } + } + foreach my $cardtype (@pri_strings) { + if($head =~ m/$cardtype/) { + my @info; + + push(@info, $1) if defined $1; + push(@info, $2) if defined $2; + my ($proto) = grep(/(E1|T1|J1)/, @info); + $proto = 'UNKNOWN' unless defined $proto; + my ($termtype) = grep(/(NT|TE)/, @info); + $termtype = 'UNKNOWN' unless defined $termtype; + + $self->{IS_DIGITAL} = 1; + $self->{IS_PRI} = 1; + $self->{TERMTYPE} = $termtype; + $self->init_proto($proto); + last; + } + } + $self->{IS_SOFT_TERM_TYPE} = 0; + foreach my $cardtype (@soft_term_type_strings) { + if($head =~ m/$cardtype/) { + $self->{IS_SOFT_TERM_TYPE} = 1; + last; + } + } + + if (($self->is_soft_term_type == 0) and ($self->termtype eq "UNKNOWN")) { + $self->{IS_SOFT_TERM_TYPE} = 1; + } + + ($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3]; + $self->{IS_DAHDI_SYNC_MASTER} = + ($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0; + $self->{CHANS} = []; + my @channels; + my $index = 0; + my @channel_lines = ; + foreach (@channel_lines) { + chomp; + s/^\s*//; + s/\s*$//; + next unless /\S/; + next unless /^\s*\d+/; # must be a real channel string. + my $c = Dahdi::Chans->new($self, $index, $_); + push(@channels, $c); + $index++; + } + close F; + if($self->is_pri()) { + # Check for PRI with unknown type strings + if($index == 31) { + if($self->{PROTO} eq 'UNKNOWN') { + $self->init_proto('E1'); + } elsif($self->{PROTO} ne 'E1') { + die "$index channels in a $self->{PROTO} span"; + } + } elsif($index == 24) { + if($self->{PROTO} eq 'UNKNOWN') { + $self->init_proto('T1'); # FIXME: J1? + } elsif($self->{PROTO} ne 'T1') { + die "$index channels in a $self->{PROTO} span"; + } + } + } + @channels = sort { $a->num <=> $b->num } @channels; + $self->{CHANS} = \@channels; + $self->{YELLOW} = undef; + $self->{CRC4} = undef; + $self->{SOFTNTTE} = undef; + $self->{TERMINATION} = undef; + if($self->is_bri()) { + $self->{CODING} = 'ami'; + $self->{DCHAN} = ($self->chans())[$self->{DCHAN_IDX}]; + $self->{BCHANS} = [ ($self->chans())[@{$self->{BCHAN_LIST}}] ]; + # Infer some info from channel name: + my $first_chan = ($self->chans())[0] || die "$0: No channels in span #$num\n"; + my $chan_fqn = $first_chan->fqn(); + if($chan_fqn =~ m(ZTHFC.*/|ztqoz.*/|XPP_BRI_.*|B4/.*|WCBRI/.*)) { # BRI + if($chan_fqn =~ m(WCBRI/.*)) { # make sure to set termination resistors on hybrid cards + $self->{TERMINATION} = 'term'; + $self->{SOFTNTTE} = 'te'; + } + $self->{FRAMING} = 'ccs'; + $self->{SWITCHTYPE} = 'euroisdn'; + $self->{SIGNALLING} = ($self->{TERMTYPE} eq 'NT') ? $DAHDI_BRI_NET : $DAHDI_BRI_CPE ; + } elsif($chan_fqn =~ m(ztgsm.*/)) { # Junghanns's GSM cards. + $self->{FRAMING} = 'ccs'; + $self->{SIGNALLING} = 'gsm'; + } + } + if($self->is_pri()) { + $self->{DCHAN} = ($self->chans())[$self->{DCHAN_IDX}]; + $self->{BCHANS} = [ ($self->chans())[@{$self->{BCHAN_LIST}}] ]; + if($self->{PROTO} eq 'E1') { + $self->{CODING} = 'hdb3'; + $self->{FRAMING} = 'ccs'; + $self->{SWITCHTYPE} = 'euroisdn'; + $self->{CRC4} = 'crc4'; + } elsif($self->{PROTO} eq 'T1') { + $self->{CODING} = 'b8zs'; + $self->{FRAMING} = 'esf'; + $self->{SWITCHTYPE} = 'national'; + } else { + die "'$self->{PROTO}' unsupported yet"; + } + } + return $self; +} + +sub bchans($) { + my $self = shift || die; + + return @{$self->{BCHANS}}; +} + +sub set_termtype($$) { + my $span = shift || die; + my $termtype = shift || die; + $span->{TERMTYPE} = $termtype; + if ($span->is_pri) { + $span->{SIGNALLING} = ($termtype eq 'NT') ? $DAHDI_PRI_NET : $DAHDI_PRI_CPE ; + } elsif ($span->is_bri) { + $span->{SIGNALLING} = ($termtype eq 'NT') ? $DAHDI_BRI_NET : $DAHDI_BRI_CPE ; + } + $span->{TYPE} = $span->proto . "_$termtype"; +} + +sub pri_set_fromconfig($$) { + my $span = shift || die; + my $genconf = shift || die; + my $name = $span->name; + return unless $span->is_soft_term_type; +# if(defined $termtype) { +# die "Termtype for $name already defined as $termtype\n"; +# } + my $pri_termtype = $genconf->{pri_termtype}; + my @pri_specs; + if(defined $pri_termtype) { + @pri_specs = @{$pri_termtype}; + } + push(@pri_specs , 'SPAN/* TE'); # Default + my @patlist = ( "SPAN/" . $span->num ); + my $xpd = Dahdi::Xpp::xpd_of_span($span); + if(defined $xpd) { + my $xbus = $xpd->xbus; + my $xbus_name = $xbus->name; + my $xpd_name = "XPD-" . $xpd->id; + my $label = $xbus->label; + my $connector = $xbus->connector; + #print "DEBUG: '$xbus_name/$xpd_name' LABEL='$label' CONNECTOR='$connector'\n"; + push(@patlist, "NUM/$xbus_name/$xpd_name"); + push(@patlist, "LABEL/$label/$xpd_name"); + push(@patlist, "CONNECTOR/$connector/$xpd_name"); + } + #print STDERR "PATLIST=@patlist\n"; + my $match_termtype; +SPEC: + for(my $i = 0; $i < @pri_specs; $i++) { + my $spec = $pri_specs[$i]; + #print STDERR "spec: $spec\n"; + my ($match, $termtype) = split(/\s+/, $spec); + next unless defined $match and defined $termtype; + # Convert "globs" to regex + $match =~ s/\*/.*/g; + $match =~ s/\?/./g; + #print STDERR "match: $match\n"; + foreach my $pattern (@patlist) { + #print STDERR "testmatch: $pattern =~ $match\n"; + if($pattern =~ /^$match$/) { + #print STDERR "MATCH '$pattern' ~ '$match' termtype=$termtype\n"; + $match_termtype = $termtype; + last SPEC; + } + } + } + die "Unknown pri_termtype" unless defined $match_termtype; + $span->set_termtype($match_termtype); +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Utils.pm b/xpp/perl_modules/Dahdi/Utils.pm new file mode 100644 index 0000000..31b1be7 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Utils.pm @@ -0,0 +1,65 @@ +package Dahdi::Utils; + +# Accessors (miniperl does not have Class:Accessor) +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + my $name = $AUTOLOAD; + $name =~ s/.*://; # strip fully-qualified portion + return if $name =~ /^[A-Z_]+$/; # ignore special methods (DESTROY) + my $key = uc($name); + my $val = shift; + if (defined $val) { + #print STDERR "set: $key = $val\n"; + return $self->{$key} = $val; + } else { + if(!exists $self->{$key}) { + #$self->xpp_dump; + #die "Trying to get uninitialized '$key'"; + } + my $val = $self->{$key}; + #print STDERR "get: $key ($val)\n"; + return $val; + } +} + +# Initialize ProcFS and SysFS pathes, in case the user set +# DAHDI_VIRT_TOP +BEGIN { + if (exists $ENV{DAHDI_VIRT_TOP}) { + $Dahdi::virt_base = $ENV{DAHDI_VIRT_TOP}; + } else { + $Dahdi::virt_base = ''; + } + $Dahdi::proc_dahdi_base = "$Dahdi::virt_base/proc/dahdi"; + $Dahdi::proc_usb_base = "$Dahdi::virt_base/proc/bus/usb"; + $Dahdi::sys_base = "$Dahdi::virt_base/sys"; +} + +sub xpp_dump($) { + my $self = shift || die; + printf STDERR "Dump a %s\n", ref($self); + foreach my $k (sort keys %{$self}) { + my $val = $self->{$k}; + $val = '**UNDEF**' if !defined $val; + printf STDERR " %-20s %s\n", $k, $val; + } +} + +# Based on Autoloader + +sub import { + my $pkg = shift; + my $callpkg = caller; + + #print STDERR "import: $pkg, $callpkg\n"; + # + # Export symbols, but not by accident of inheritance. + # + die "Sombody inherited Dahdi::Utils" if $pkg ne 'Dahdi::Utils'; + no strict 'refs'; + *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD; + *{ $callpkg . '::xpp_dump' } = \&xpp_dump; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp.pm b/xpp/perl_modules/Dahdi/Xpp.pm new file mode 100644 index 0000000..3acd2ef --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp.pm @@ -0,0 +1,307 @@ +package Dahdi::Xpp; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Hardware; +use Dahdi::Xpp::Xbus; + +=head1 NAME + +Dahdi::Xpp - Perl interface to the Xorcom Astribank drivers. + +=head1 SYNOPSIS + + # Listing all Astribanks: + use Dahdi::Xpp; + # scans hardware: + my @xbuses = Dahdi::Xpp::xbuses("SORT_CONNECTOR"); + for my $xbus (@xbuses) { + print $xbus->name." (".$xbus->label .", ". $xbus->connector .")\n"; + for my $xpd ($xbus->xpds) { + print " - ".$xpd->fqn,"\n"; + } + } +=cut + +# +# A global handle for all xbuses +# +my @xbuses; + +our $sysfs_astribanks; +our $sysfs_xpds; +our $sysfs_ab_driver; + +BEGIN { + my $virt_base = $Dahdi::virt_base; + $sysfs_astribanks = "$virt_base/sys/bus/astribanks/devices"; + $sysfs_xpds = "$virt_base/sys/bus/xpds/devices"; + $sysfs_ab_driver = "$virt_base/sys/bus/astribanks/drivers/xppdrv"; +} + +sub scan($) { + my $pack = shift || die; + + opendir(D, $sysfs_astribanks) || return(); + while(my $entry = readdir D) { + next if $entry eq '.' or $entry eq '..'; + my $xbus = Dahdi::Xpp::Xbus->new($sysfs_astribanks, $entry); + push(@xbuses, $xbus); + } + closedir D; + return @xbuses; +} + +# Nominal sorters for xbuses +sub by_name { + return $a->name cmp $b->name; +} + +sub by_connector { + return $a->connector cmp $b->connector; +} + +sub by_label { + my $cmp = $a->label cmp $b->label; + return $cmp if $cmp != 0; + return $a->connector cmp $b->connector; +} + +sub score_type { + my $score; + + return 1 if grep(/\b[ETJ]1/, @_); + return 2 if grep(/\bBRI/, @_); + return 3 if grep(/\bFXO/, @_); + return 4; # FXS +} + +sub by_type { + my @a_types = map { $_->type } $a->xpds(); + my @b_types = map { $_->type } $b->xpds(); + my $res; + + my $a_score = score_type(@a_types); + my $b_score = score_type(@b_types); + #printf STDERR "DEBUG-a: %s %s %s\n", $a->name, $a_score, join(',',@a_types); + #printf STDERR "DEBUG-b: %s %s %s\n", $b->name, $b_score, join(',',@b_types); + $res = $a_score <=> $b_score; + $res = $a->connector cmp $b->connector if $res == 0; + return $res; +} + +sub by_xpporder { + my $cmp = $a->xpporder <=> $b->xpporder; + return $cmp if $cmp != 0; + return $a->connector cmp $b->connector; +} + +=head1 xbuses([sort_order]) + +Scans system (via /sys) and returns a list of Astribank (Xbus) +objects. The optional parameter sort_order is the order in which +the Astribanks will be returns: + + +=head1 sorters([sort_order]) + +With no parameters, returns the names of built in sorters. +With a single parameter, returns a reference to the requested built in sorter. +Also, for convenience, a reference to a custom sorter function may be passed +and returned as is. + +The built in sorters are: + +=over + +=item SORT_XPPORDER + +Sort by ordering defined in F file. +Astribanks can be listed in this file by their label or by +their connector string (prefixed with <@>). + +Astribanks not listed in the F file are sorted +via ordering number 999 -- So they come after the Astribanks +that are listed. + +Astribanks with same ordering number (e.g: 999) are sorted +by their connector string (to preserve legacy behaviour). + +=item SORT_CONNECTOR + +Sort by the connector string. For USB this defines the "path" to get to +the device through controllers, hubs etc. + +=item SORT_LABEL + +Sorts by the label of the Astribank. The label field is unique to the +Astribank. It can also be viewed through 'lsusb -v' without the drivers +loaded (the iSerial field in the Device Descriptor). This is normally +relieble, but some older Astribanks have an empty label. + +=item SORT_NAME + +Sort by the "name". e.g: "XBUS-00". The order of Astribank names depends +on the load order, and hence may change between different runs. + +=item SORT_TYPE + +Sort by XPD types. First Astribanks with E1/T1/J1 XPDs, then with BRI, +then with FXO, then ones with only FXS ports. Within each type they +are sorted by the connector field (as in SORT_CONNECTOR above). + +=item custom function + +Instead of using a predefined sorter, you can pass your own sorting +function. See the example sorters in the code of this module. + +=back + +=cut + +sub sorters { + my %sorter_table = ( + SORT_CONNECTOR => \&by_connector, + SORT_NAME => \&by_name, + SORT_LABEL => \&by_label, + SORT_TYPE => \&by_type, + SORT_XPPORDER => \&by_xpporder, + # Aliases + connector => \&by_connector, + name => \&by_name, + label => \&by_label, + type => \&by_type, + xpporder => \&by_xpporder, + ); + my $which_sorter = shift || return sort keys %sorter_table; + return $which_sorter if ref($which_sorter) eq 'CODE'; + return $sorter_table{$which_sorter}; +} + +sub add_xpporder(@) { + my @xbuses = @_; + my $cfg = $ENV{XPPORDER_CONF} || '/etc/dahdi/xpp_order'; + my %order; + + # Set defaults + foreach my $xbus (@xbuses) { + $xbus->{XPPORDER} = 99; + } + # Read from optional config file + if(!open(F, $cfg)) { + warn "$0: Failed opening '$cfg': $!" + unless $! == 2; # ENOENT + return; + } + my $count = 1; + while() { + chomp; + s/#.*//; + s/^\s*//; + s/\s*$//; + next unless /\S/; + $order{$_} = $count++; + } + close F; + # Overrides from config file + foreach my $xbus (@xbuses) { + my $label = $xbus->label; + my $val; + $val = $order{$label}; + $val = $order{$xbus->connector} unless defined $val; + $xbus->{XPPORDER} = $val if defined $val; + } +} + +sub xbuses { + my $optsort = shift || 'SORT_XPPORDER'; + my @sorted_xbuses; + + if(! @xbuses) { + @xbuses = Dahdi::Xpp->scan(); + } + add_xpporder(@xbuses); + my $sorter = sorters($optsort); + die "Unknown optional sorter '$optsort'" unless defined $sorter; + @sorted_xbuses = sort $sorter @xbuses; + return @sorted_xbuses; +} + +sub xpd_of_span($) { + my $span = shift or die "Missing span parameter"; + return undef unless defined $span; + foreach my $xbus (Dahdi::Xpp::xbuses) { + foreach my $xpd ($xbus->xpds()) { + return $xpd if $xpd->fqn eq $span->name; + } + } + return undef; +} + +=head1 sync([new_sync_source]) + +Gets (and optionally sets) the internal Astribanks synchronization +source. When used to set sync source, returns the original sync source. + +A synchronization source is a value valid writing into + /sys/bus/astribanks/drivers/xppdrv/sync +For more information read that file and see README.Astribank . + +=cut + +sub sync { + my ($newsync) = @_; + my $result; + my $file = "$sysfs_ab_driver/sync"; + die "Missing '$file'\n" unless -f $file; + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + close F; + chomp $result; + $result =~ s/^SYNC=\D*//; + if(defined $newsync) { # Now change + $newsync =~ s/.*/\U$&/; + if($newsync =~ /^(\d+)$/) { + $newsync = "SYNC=$1"; + } elsif($newsync ne 'DAHDI') { + die "Bad sync parameter '$newsync'"; + } + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F $newsync; + close(F) or die "Failed in closing $file: $!"; + } + return $result; +} + +=head1 SEE ALSO + +=over + +=item L + +Xbus (Astribank) object. + +=item L + +XPD (the rough equivalent of a Dahdi span) object. + +=item L + +Object for a line: an analog port or a time-slot in a adapter. +Equivalent of a channel in Dahdi. + +=item L + +General documentation in the master package. + +=back + +=cut + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Line.pm b/xpp/perl_modules/Dahdi/Xpp/Line.pm new file mode 100644 index 0000000..bb0ec27 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Line.pm @@ -0,0 +1,65 @@ +package Dahdi::Xpp::Line; +# +# Written by Oron Peled +# Copyright (C) 2008, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; + +sub new($$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xpd = shift or die; + my $index = shift; + defined $index or die; + my $self = {}; + bless $self, $pack; + $self->{XPD} = $xpd; + $self->{INDEX} = $index; + return $self; +} + +sub blink($$) { + my $self = shift; + my $on = shift; + my $xpd = $self->xpd; + my $result = $xpd->xpd_getattr("blink"); + $result = hex($result); + if(defined($on)) { # Now change + my $onbitmask = 1 << $self->index; + my $offbitmask = $result & ~$onbitmask; + + $result = $offbitmask; + $result |= $onbitmask if $on; + $result = $xpd->xpd_setattr("blink", $result); + } + return $result; +} + +sub create_all($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xpd = shift || die; + local $/ = "\n"; + my @lines; + for(my $i = 0; $i < $xpd->{CHANNELS}; $i++) { + my $line = Dahdi::Xpp::Line->new($xpd, $i); + push(@lines, $line); + } + $xpd->{LINES} = \@lines; + if($xpd->type eq 'FXO') { + my $battery = $xpd->xpd_getattr("fxo_battery"); + die "Missing '$battery' attribute\n" unless defined $battery; + my @batt = split(/\s+/, $battery); + foreach my $l (@lines) { + die unless @batt; + my $state = shift @batt; + $l->{BATTERY} = ($state eq '+') ? 1 : 0; + } + } +} + + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Mpp.pm b/xpp/perl_modules/Dahdi/Xpp/Mpp.pm new file mode 100644 index 0000000..2c11a94 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Mpp.pm @@ -0,0 +1,222 @@ +package Dahdi::Xpp::Mpp; +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi::Utils; + +=head1 NAME + +Dahdi::Xpp::Mpp - Perl interface to C + +=head1 DESCRIPTION + +This package uses C to collect information +about Astribanks via MPP (Management Processor Protocol). + +The binary default location is F. It may be +overridden via module parameter C and the +C environment variable (higher priority). + +It may also be set/unset from code via the set_astribank_tool() method. + +=head1 METHODS + +=head2 mpp_addinfo() + +Called with a list of C objects and augment their +data with C objects. + +This method is the normal external interface of this class. + +=head2 new() + +Constructor. Receive as parameter an instance of C class +and return a C object. + +Normally, used indirectly via the mpp_addinfo() method. + +=head2 set_astribank_tool() + +Override default location of astribank_tool(8). It is legal +to set it to C. + +=head2 showinfo() + +Dump an C object for debugging. + +=cut + +my $astribank_tool = '/usr/sbin/astribank_tool'; + +sub set_astribank_tool($$) { + my $pack = shift || die; + $pack eq 'Dahdi::Xpp::Mpp' or die "$0: Called from wrong package? ($pack)"; + my $arg = shift; + $astribank_tool = $arg; + #print STDERR "Setting astribank_tool='$astribank_tool'\n"; +} + +sub import { + my ($param) = grep(/^astribank_tool=/, @_); + if(defined $param) { + $param =~ s/^astribank_tool=//; + $astribank_tool = $param; + } + if(defined $ENV{ASTRIBANK_TOOL}) { + $astribank_tool = $ENV{ASTRIBANK_TOOL}; + } +} + +sub showinfo($$) { + my $self = shift || die; + my $prefix = shift || die; + + return unless defined $self; + foreach my $k (sort keys %{$self}) { + my $v = $self->{$k}; + if(ref($v) eq 'ARRAY') { + my @a = @{$v}; + my $i; + my $ki; + for($i = 0; $i < @a; $i++) { + $ki = sprintf "%s[%d]", $k, $i; + printf "$prefix%-20s %s\n", $ki, $a[$i]; + } + } else { + if($k eq 'DEV') { + printf "$prefix%-20s -> %s\n", $k, $v->hardware_name; + } else { + printf "$prefix%-20s %s\n", $k, $v; + } + } + } +} + +sub astribank_tool_cmd($@) { + my $dev = shift || die; + my @args = @_; + my $usb_top; + + # Find USB bus toplevel + $usb_top = '/dev/bus/usb'; + $usb_top = '/proc/bus/usb' unless -d $usb_top; + die "No USB toplevel found\n" unless -d $usb_top; + my $name = $dev->priv_device_name(); + die "$0: Unkown private device name" unless defined $name; + my $path = "$usb_top/$name"; + return ($astribank_tool, '-D', "$path", @args); +} + +sub new($$$) { + my $pack = shift || die; + my $dev = shift || die; + my $product = $dev->product; + + return undef unless $dev->is_astribank; + return undef unless $dev->bus_type eq 'USB'; + return undef unless $product =~ /116./; + my $mppinfo = { + DEV => $dev, + HAS_MPP => 1, + }; + bless $mppinfo, $pack; + #print STDERR "$astribank_tool($path) -- '$product'\n"; + if(! -x $astribank_tool) { + warn "Could not run '$astribank_tool'\n"; + return $mppinfo; + } + return $mppinfo unless $product =~ /116[12]/; + $mppinfo->{'MPP_TALK'} = 1; + my @cmd = astribank_tool_cmd($dev, '-Q'); + my $name = $dev->priv_device_name(); + my $dbg_file = "$name"; + $dbg_file =~ s/\W/_/g; + #$dbg_file = "/tmp/twinstar-debug-$dbg_file"; + $dbg_file = "/dev/null"; + unless(open(F, "@cmd 2> '$dbg_file' |")) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + local $/ = "\n"; + local $_; + while() { + chomp; + #printf STDERR "'%s'\n", $_; + if(s/^INFO:\s*//) { + $mppinfo->{'PROTOCOL'} = $1 if /^protocol\s+version:\s*(\d+)/i; + } elsif(s/^EEPROM:\s*//) { + $mppinfo->{'EEPROM_RELEASE'} = $1 if /^release\s*:\s*([\d\.]+)/i; + $mppinfo->{'EEPROM_LABEL'} = $1 if /^label\s*:\s*([\w._'-]+)/i; + } elsif(s/^Extrainfo:\s+:\s*(.+?)$//) { + $mppinfo->{'EEPROM_EXTRAINFO'} = $1; + } elsif(s/^Capabilities:\s*TwinStar\s*:\s*(.+?)$//) { + my $cap = $1; + $mppinfo->{'TWINSTAR_CAPABLE'} = ($cap =~ /yes/i) ? 1 : 0; + } elsif(s/^TwinStar:\s*//) { + $mppinfo->{'TWINSTAR_PORT'} = $1 if /^connected\s+to\s*:\s*usb-(\d+)/i; + if(s/^USB-(\d+)\s*POWER\s*:\s*//) { + my $v = ($_ eq 'ON') ? 1 : 0; + $mppinfo->{'TWINSTAR_POWER'}->[$1] = $v; + } + if(s/^Watchdog[^:]+:\s*//) { + my $v = ($_ eq 'on-guard') ? 1 : 0; + $mppinfo->{'TWINSTAR_WATCHDOG'} = $v; + } + #printf STDERR "\t%s\n", $_; + } else { + #printf STDERR "\t%s\n", $_; + } + } + unless(close F) { + warn "Failed running '$astribank_tool': $!"; + return undef; + } + #$mppinfo->showinfo; + return $mppinfo; +} + +sub mpp_setwatchdog($$) { + my $mppinfo = shift || die; + my $on = shift; + die "$0: Bad value '$on'" unless defined($on) && $on =~ /^[0-1]$/; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $old = $mppinfo->tws_watchdog; + my @cmd = astribank_tool_cmd($dev, '-w', $on); + print STDERR "DEBUG($on): '@cmd'\n"; + system(@cmd); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_jump($) { + my $mppinfo = shift || die; + my $dev = $mppinfo->dev || die; + return undef unless defined $mppinfo->mpp_talk; + my $port = $mppinfo->twinstar_port; + $port = ($port == 1) ? 0 : 1; + die "Unknown TwinStar port" unless defined $port; + my @cmd = astribank_tool_cmd($dev, '-p', $port); + system(@cmd); + die "Running $astribank_tool failed: $?" if $?; +} + +sub mpp_addinfo($@) { + my $pack = shift || die; + my @devlist = @_; + + foreach my $dev (@devlist) { + $dev->{MPPINFO} = $pack->new($dev); + } +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Xbus.pm b/xpp/perl_modules/Dahdi/Xpp/Xbus.pm new file mode 100644 index 0000000..e1973b1 --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Xbus.pm @@ -0,0 +1,212 @@ +package Dahdi::Xpp::Xbus; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Hardware; +use Dahdi::Xpp::Xpd; + +sub xpds($) { + my $xbus = shift; + return @{$xbus->{XPDS}}; +} + +sub by_number($) { + my $busnumber = shift; + die "Missing xbus number parameter" unless defined $busnumber; + my @xbuses = Dahdi::Xpp::xbuses(); + + my ($xbus) = grep { $_->num == $busnumber } @xbuses; + return $xbus; +} + +sub by_label($) { + my $label = shift; + die "Missing xbus label parameter" unless defined $label; + my @xbuses = Dahdi::Xpp::xbuses(); + + my ($xbus) = grep { $_->label eq $label } @xbuses; + return $xbus; +} + +sub get_xpd_by_number($$) { + my $xbus = shift; + my $xpdid = shift; + die "Missing XPD id parameter" unless defined $xpdid; + $xpdid = sprintf("%02d", $xpdid); + my @xpds = $xbus->xpds; + my ($wanted) = grep { $_->id eq $xpdid } @xpds; + return $wanted; +} + +sub xbus_getattr($$) { + my $xbus = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my $file = sprintf "%s/%s", $xbus->sysfs_dir, $attr; + + open(F, $file) || die "Failed opening '$file': $!"; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub read_attrs() { + my $xbus = shift || die; + my @attrnames = qw(CONNECTOR LABEL STATUS); + my @attrs; + + foreach my $attr (@attrnames) { + my $val = xbus_getattr($xbus, $attr); + if($attr eq 'STATUS') { + # Some values are in all caps as well + $val = uc($val); + } elsif($attr eq 'CONNECTOR') { + $val =~ s/^/@/; # Add prefix + } elsif($attr eq 'LABEL') { + # Fix badly burned labels. + $val =~ s/[[:^print:]]/_/g; + } + $xbus->{$attr} = $val; + } +} + +sub transport_type($$) { + my $xbus = shift || die; + my $xbus_dir = shift; + my $transport = "$xbus_dir/transport"; + if(-e "$transport/ep_00") { # It's USB + $xbus->{TRANSPORT_TYPE} = 'USB'; + } else { + warn "Unkown transport in $xbus_dir\n"; + undef $xbus->{TRANSPORT_TYPE}; + } + return $xbus->{TRANSPORT_TYPE}; +} + +sub read_xpdnames($) { + my $xbus_dir = shift or die; + my $pat = sprintf "%s/[0-9][0-9]:[0-9]:[0-9]", $xbus_dir; + my @xpdnames; + + #printf STDERR "read_xpdnames(%s): $pat\n", $xbus_dir; + foreach (glob $pat) { + die "Bad /sys entry: '$_'" unless m/^.*\/([0-9][0-9]):([0-9]):([0-9])$/; + my ($busnum, $unit, $subunit) = ($1, $2, $3); + my $name = sprintf("%02d:%1d:%1d", $1, $2, $3); + #print STDERR "\t> $_ ($name)\n"; + push(@xpdnames, $name); + } + return @xpdnames; +} + +sub read_num($) { + my $self = shift or die; + my $xbus_dir = $self->sysfs_dir; + $xbus_dir =~ /.*-(\d\d)$/; + return $1; +} + +sub new($$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $parent_dir = shift or die; + my $entry_dir = shift or die; + my $xbus_dir = "$parent_dir/$entry_dir"; + my $self = {}; + bless $self, $pack; + $self->{SYSFS_DIR} = $xbus_dir; + my $num = $self->read_num; + $self->{NUM} = $num; + $self->{NAME} = "XBUS-$num"; + $self->read_attrs; + # Get transport related info + my $transport = "$xbus_dir/transport"; + die "OLD DRIVER: missing '$transport'\n" unless -e $transport; + my $transport_type = $self->transport_type($xbus_dir); + if(defined $transport_type) { + my $tt = "Dahdi::Hardware::$transport_type"; + my $hw = $tt->set_transport($self, $xbus_dir); + #printf STDERR "Xbus::new transport($transport_type): %s\n", $hw->{HARDWARE_NAME}; + } + my @xpdnames; + my @xpds; + @xpdnames = read_xpdnames($self->sysfs_dir); + foreach my $xpdstr (@xpdnames) { + my $xpd = Dahdi::Xpp::Xpd->new($self, $xpdstr); + push(@xpds, $xpd); + } + @{$self->{XPDS}} = sort { $a->id <=> $b->id } @xpds; + return $self; +} + +sub dahdi_registration($$) { + my $xbus = shift; + my $on = shift; + my $result; + my $file = sprintf("%s/dahdi_registration", $xbus->sysfs_dir); + # Handle old drivers without dahdi_registration xbus attribute + if (! -f $file) { + warn "Old xpp driver without dahdi_registration support. Emulating it using xpd/span support\n"; + my @xpds = sort { $a->id <=> $b->id } $xbus->xpds(); + my $prev; + foreach my $xpd (@xpds) { + $prev = $xpd->dahdi_registration($on); + } + return $prev; + } + # First query + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + chomp $result; + close F; + if(defined($on) and $on ne $result) { # Now change + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F ($on)?"1":"0"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + undef $result; + } + } + } + return $result; +} + +sub pretty_xpds($) { + my $xbus = shift; + my @xpds = sort { $a->id <=> $b->id } $xbus->xpds(); + my @xpd_types = map { $_->type } @xpds; + my $last_type = ''; + my $mult = 0; + my $xpdstr = ''; + foreach my $curr (@xpd_types) { + if(!$last_type || ($curr eq $last_type)) { + $mult++; + } else { + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + $mult = 1; + } + $last_type = $curr; + } + if($mult == 1) { + $xpdstr .= "$last_type "; + } elsif($mult) { + $xpdstr .= "$last_type*$mult "; + } + $xpdstr =~ s/\s*$//; # trim trailing space + return $xpdstr; +} + +1; diff --git a/xpp/perl_modules/Dahdi/Xpp/Xpd.pm b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm new file mode 100644 index 0000000..810ad9e --- /dev/null +++ b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm @@ -0,0 +1,332 @@ +package Dahdi::Xpp::Xpd; +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use Dahdi::Utils; +use Dahdi::Xpp; +use Dahdi::Xpp::Line; + +=head1 NAME + +Dahdi::Xpp::Xpd - Perl interface to the Xorcom Astribank XPDs (spans) + +=head1 SYNOPSIS + + # Listing all Astribanks: + use Dahdi::Xpp; + # scans hardware: + my @xbuses = Dahdi::Xpp::xbuses("SORT_CONNECTOR"); + for my $xbus (@xbuses) { + print $xbus->name." (".$xbus->label .", ". $xbus->connector .")\n"; + for my $xpd ($xbus->xpds) { + print " - ".$xpd->fqn,"\n"; + } + } + +=head1 xbus + +The parent L + +=head1 id + +The two-digit ID in the Xbus. Normally 0I for digital spans and +I0 for analog ones (for some digit, I). + +=head1 unit + +First digit of the ID. Zero-based number of the module inside the +Astribank, + +=head1 subunit + +Second digit of the ID. Zero-based sub-part inside the module. +Applicable only to digital (BRI/PRI) modules and always 0 for others. + +=head1 FQN + +Textual name: E.g. C. + +=head1 sysfs_dir + +The SysFS directory with information about the module. E.g. +C. + +=head1 channels + +A list of L channels of this span. In a scalar context +this will be the number of channels in the span. + +=head1 spanno + +0 if not registered with Dahdi. Otherwise, the number of the span it is +registered as. + +=head1 type + +The type of the XPD. One of: C, C, C, C, +C, C. + +=head1 is_bri + +True if this XPD is BRI. + +=head1 is_pri + +True if this XPD is PRI (E1/T1). + +=head1 is_digital + +True if this XPD is a digital port (BRI / PRI). + +=head1 termtype + +For a digital span: C or C. + +=head1 dchan_hardhdlc + +For a BRI port: true if the driver with hardhdlc support (rather than +bri_dchan). + +=cut + +my %file_warned; # Prevent duplicate warnings about same file. + +sub xpd_attr_path($@) { + my $self = shift || die; + my $xbus = $self->xbus; + my ($busnum, $unitnum, $subunitnum, @attr) = ( + $xbus->num, + $self->unit, + $self->subunit, + @_); + foreach my $attr (@attr) { + my $file = sprintf "%s/%02d:%1d:%1d/$attr", + $xbus->sysfs_dir, $busnum, $unitnum, $subunitnum; + next unless -f $file; + return $file; + } + return undef; +} + +my %attr_missing_warned; # Prevent duplicate warnings + +sub xpd_driver_getattr($$) { + my $xpd = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my ($busnum, $unitnum, $subunitnum) = ($xpd->xbus->num, $xpd->unit, $xpd->subunit); + my $file = sprintf "$Dahdi::Xpp::sysfs_xpds/%02d:%1d:%1d/driver/$attr", + $busnum, $unitnum, $subunitnum; + if(!defined($file)) { + warn "$0: xpd_driver_getattr($attr) -- Missing attribute.\n" if + $attr_missing_warned{$attr}; + return undef; + } + open(F, $file) || return undef; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub xpd_getattr($$) { + my $xpd = shift || die; + my $attr = shift || die; + $attr = lc($attr); + my $file = $xpd->xpd_attr_path(lc($attr)); + + if(!defined($file)) { + warn "$0: xpd_getattr($attr) -- Missing attribute.\n" if + $attr_missing_warned{$attr}; + return undef; + } + open(F, $file) || return undef; + my $val = ; + close F; + chomp $val; + return $val; +} + +sub xpd_setattr($$$) { + my $xpd = shift || die; + my $attr = shift || die; + my $val = shift; + $attr = lc($attr); + my $file = xpd_attr_path($xpd, $attr); + my $oldval = $xpd->xpd_getattr($attr); + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F "$val"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + return undef; + } + } + return $oldval; +} + +sub blink($$) { + my $self = shift; + my $on = shift; + my $result = $self->xpd_getattr("blink"); + if(defined($on)) { # Now change + $self->xpd_setattr("blink", ($on)?"0xFFFF":"0"); + } + return $result; +} + +sub dahdi_registration($$) { + my $self = shift; + my $on = shift; + my $result; + my $file = $self->xpd_attr_path("span", "dahdi_registration"); + die "$file is missing" unless -f $file; + # First query + open(F, "$file") or die "Failed to open $file for reading: $!"; + $result = ; + chomp $result; + close F; + if(defined($on) and $on ne $result) { # Now change + open(F, ">$file") or die "Failed to open $file for writing: $!"; + print F ($on)?"1":"0"; + if(!close(F)) { + if($! == 17) { # EEXISTS + # good + } else { + undef $result; + } + } + } + return $result; +} + +sub xpds_by_spanno() { + my @xbuses = Dahdi::Xpp::xbuses(); + my @xpds = map { $_->xpds } @xbuses; + @xpds = grep { $_->spanno } @xpds; + @xpds = sort { $a->spanno <=> $b->spanno } @xpds; + my @spanno = map { $_->spanno } @xpds; + my @idx; + @idx[@spanno] = @xpds; # The spanno is the index now + return @idx; +} + +sub new($$$) { + my $pack = shift or die "Wasn't called as a class method\n"; + my $xbus = shift or die; + my $xpdstr = shift or die; + my $sysfsdir = sprintf "%s/%s", $xbus->sysfs_dir, $xpdstr; + my ($busnum, $unit, $subunit) = split(/:/, $xpdstr); + my $self = { + XBUS => $xbus, + ID => sprintf("%1d%1d", $unit, $subunit), + FQN => $xbus->name . "/" . "XPD-$unit$subunit", + UNIT => $unit, + SUBUNIT => $subunit, + SYSFS_DIR => $sysfsdir, + }; + bless $self, $pack; + my @offhook = split / /, ($self->xpd_getattr('offhook')); + $self->{CHANNELS} = @offhook; + my $type = $self->xpd_getattr('type'); + my $span = $self->xpd_getattr('span'); + my $timing_priority = $self->xpd_getattr('timing_priority'); + $self->{SPANNO} = $span; + $self->{TYPE} = $type; + $self->{TIMING_PRIORITY} = $timing_priority; + if($type =~ /BRI_(NT|TE)/) { + $self->{IS_BRI} = 1; + $self->{TERMTYPE} = $1; + $self->{DCHAN_HARDHDLC} = $self->xpd_driver_getattr('dchan_hardhdlc'); + } elsif($type =~ /[ETJ]1/) { + $self->{IS_PRI} = 1; + # older drivers may not have 'timing_priority' + # attribute. Preserve original behaviour: + if(defined($timing_priority) && ($timing_priority == 0)) { + $self->{TERMTYPE} = 'NT'; + } else { + $self->{TERMTYPE} = 'TE'; + } + } + $self->{IS_DIGITAL} = ( $self->{IS_BRI} || $self->{IS_PRI} ); + Dahdi::Xpp::Line->create_all($self); + return $self; +} + +#------------------------------------ +# static xpd related helper functions +#------------------------------------ + +# Returns only the telephony XPD's from a list +# of one or more XPD's. +# I.e: Filters-out ECHO cancelers +sub telephony_devs { + my @devs = grep { $_->channels } @_; + return @devs; +} + +sub format_rank($$) { + my ($rank, $prio) = @_; + my $width = 2; + # 0 is replaced with a character that is sorted *AFTER* numbers. + $prio = '_' x $width unless defined $prio && $prio; + return sprintf "%${width}s-%s", $prio, $rank; +} + +sub sync_priority_rank($) { + my $xpd = shift || die; + my $prio = $xpd->timing_priority; + # The @rank array is ordered by priority of sync (good to bad) + # It is used when timing_priority is not defined (analog) or + # is 0 (NT). + my @rank = ( + ($xpd->is_pri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->is_bri and defined($xpd->termtype) and $xpd->termtype eq 'TE'), + ($xpd->type eq 'FXO'), + ($xpd->is_pri), + ($xpd->is_bri), + ($xpd->type eq 'FXS'), + ); + my $i; + for($i = 0; $i < @rank; $i++) { + last if $rank[$i]; + } + return format_rank($i, $prio); +} + +# An XPD sync priority comparator for sort() +sub sync_priority_compare() { + my $rank_a = sync_priority_rank($a); + my $rank_b = sync_priority_rank($b); + #print STDERR "DEBUG(rank): $rank_a (", $a->fqn, ") $rank_b (", $b->fqn, ")\n"; + return $rank_a cmp $rank_b; # The easy case +} + +# For debugging: show a list of XPD's with relevant sync info. +sub show_xpd_rank(@) { + print STDERR "XPD's by rank\n"; + foreach my $xpd (@_) { + my $type = $xpd->type; + my $extra = ""; + my $rank = sync_priority_rank($xpd); + if($xpd->is_digital) { + $extra .= " termtype " . ($xpd->termtype || "UNKNOWN"); + } + printf STDERR "%3s %-15s %s\n", $rank, $xpd->fqn, $extra; + } +} + +sub xpds_by_rank(@) { + my @xpd_prio = sort sync_priority_compare @_; + #show_xpd_rank(@xpd_prio); + return @xpd_prio; +} + +1; diff --git a/xpp/pic_loader.c b/xpp/pic_loader.c new file mode 100644 index 0000000..c6ed3f1 --- /dev/null +++ b/xpp/pic_loader.c @@ -0,0 +1,285 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include "hexfile.h" +#include "pic_loader.h" +#include +#include + +#define DBG_MASK 0x03 +#define MAX_HEX_LINES 10000 +#define TIMEOUT 500 + +enum xpp_packet_types { + PIC_REQ_XOP = 0x09, + PIC_REP_XOP = 0x0A +}; + +struct xpp_packet_header { + struct { + uint16_t len; + uint8_t op; + uint8_t unit; + } PACKED header; + union { + struct { + struct { + uint8_t flags; + uint8_t card_type; + uint16_t offs; + } pic_header; + uint8_t data[3]; + } PACKED pic_packet; + } d; +} PACKED; + +int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len) +{ + int recv_answer = 0; + char buf[PACKET_SIZE]; + struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; + int pack_len; + int ret; + + assert(astribank != NULL); + pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header); + phead->header.len = pack_len; + phead->header.op = PIC_REQ_XOP; + phead->header.unit = 0x00; + phead->d.pic_packet.pic_header.flags = pcmd; + phead->d.pic_packet.pic_header.card_type = card_type; + phead->d.pic_packet.pic_header.offs = offs; + if(data) + memcpy(phead->d.pic_packet.data, data, data_len); + switch (pcmd) { + case PIC_START_FLAG: + break; + case PIC_DATA_FLAG: + break; + case PIC_END_FLAG: + recv_answer = 1; + break; + case PIC_ENDS_FLAG: + break; + } + + DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd); + dump_packet(LOG_DEBUG, DBG_MASK, "dump:picline[W]", (char *)phead, pack_len); + + ret = xusb_send(astribank->xusb, buf, pack_len, TIMEOUT); + if(ret < 0) { + ERR("xusb_send failed: %d\n", ret); + return ret; + } + DBG("xusb_send: Written %d bytes\n", ret); + if (recv_answer) { + ret = xusb_recv(astribank->xusb, buf, sizeof(buf), TIMEOUT); + if(ret <= 0) { + ERR("No USB packs to read\n"); + return ret; + } else { + phead = (struct xpp_packet_header *)buf; + if(phead->header.op != PIC_REP_XOP) { + ERR("Got unexpected reply OP=0x%02X\n", phead->header.op); + dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", buf, ret); + return -EINVAL; + } + DBG("received OP=0x%02X, checksum=%02X\n", phead->header.op, phead->d.pic_packet.data[0]); + if(phead->d.pic_packet.data[0] != 0) { + ERR("PIC burning, bad checksum\n"); + return -EINVAL; + } + } + } + return 0; +} + +static const char *pic_basename(const char *fname, uint8_t *card_type) +{ + const char *basename; + regex_t regex; + char ebuf[BUFSIZ]; + const char re[] = "PIC_TYPE_([0-9]+)\\.hex"; + regmatch_t pmatch[2]; /* One for the whole match, one for the number */ + int nmatch = (sizeof(pmatch)/sizeof(pmatch[0])); + int len; + int ret; + + basename = strrchr(fname, '/'); + if(!basename) + basename = fname; + if((ret = regcomp(®ex, re, REG_ICASE | REG_EXTENDED)) != 0) { + regerror(ret, ®ex, ebuf, sizeof(ebuf)); + ERR("regcomp: %s\n", ebuf); + return NULL; + } + if((ret = regexec(®ex, basename, nmatch, pmatch, 0)) != 0) { + regerror(ret, ®ex, ebuf, sizeof(ebuf)); + ERR("regexec: %s\n", ebuf); + regfree(®ex); + return NULL; + } + /* + * Should have both complete match and a parentheses match + */ + if(pmatch[0].rm_so == -1 || pmatch[1].rm_so == -1) { + ERR("pic_basename: Bad match: pmatch[0].rm_so=%d pmatch[1].rm_so=%d\n", + pmatch[0].rm_so, pmatch[1].rm_so == -1); + regfree(®ex); + return NULL; + } + len = pmatch[1].rm_eo - pmatch[1].rm_so; + if(len >= sizeof(ebuf) - 1) + len = sizeof(ebuf) - 1; + memcpy(ebuf, basename + pmatch[1].rm_so, len); + ebuf[len] = '\0'; + DBG("match: %s\n", ebuf); + ret = atoi(ebuf); + if(ret <= 0 || ret > 9) { + ERR("pic_basename: Bad type number %d\n", ret); + regfree(®ex); + return NULL; + } + *card_type = ret; + regfree(®ex); + return basename; +} + +/* + * Returns: true on success, false on failure + */ +static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata) +{ + const char *v = hexdata->version_info; + const char *basename; + uint8_t *data; + unsigned char check_sum = 0; + uint8_t card_type; + int ret; + unsigned int i; + const char *devstr; + + v = (v[0]) ? v : "Unknown"; + assert(astribank != NULL); + assert(hexdata != NULL); + devstr = xusb_devpath(astribank->xusb); + if(!astribank->is_usb2) { + ERR("%s: Skip PIC burning (not USB2)\n", devstr); + return 0; + } + INFO("%s [%s]: Loading PIC Firmware: %s (version %s)\n", + devstr, + xusb_serial(astribank->xusb), + hexdata->fname, + hexdata->version_info); + basename = pic_basename(hexdata->fname, &card_type); + if(!basename) { + ERR("%s: Bad PIC filename '%s'. Abort.\n", devstr, hexdata->fname); + return 0; + } + DBG("basename=%s card_type=%d maxlines=%d\n", + basename, card_type, hexdata->maxlines); + /* + * Try to read extra left-overs from USB controller + */ + for(i = 2; i; i--) { + char buf[PACKET_SIZE]; + + if(xusb_recv(astribank->xusb, buf, sizeof(buf), 1) <= 0) + break; + } + if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) { + perror("Failed sending start hexline"); + return 0; + } + for(i = 0; i < hexdata->maxlines; i++) { + struct hexline *hexline; + unsigned int len; + + hexline = hexdata->lines[i]; + if(!hexline) { + ERR("%s: hexdata finished early (line %d)", devstr, i); + return 0; + } + if(hexline->d.content.header.tt == TT_DATA) { + len = hexline->d.content.header.ll; /* don't send checksum */ + if(len != 3) { + ERR("%s: Bad line len %d\n", devstr, len); + return 0; + } + data = hexline->d.content.tt_data.data; + check_sum ^= data[0] ^ data[1] ^ data[2]; + ret = send_picline(astribank, card_type, PIC_DATA_FLAG, + hexline->d.content.header.offset, data, len); + if(ret) { + perror("Failed sending data hexline"); + return 0; + } + } else if(hexline->d.content.header.tt == TT_EOF) { + break; + } else { + ERR("%s: Unexpected TT = %d in line %d\n", + devstr, hexline->d.content.header.tt, i); + return 0; + } + } + if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) { + perror("Failed sending end hexline"); + return 0; + } + DBG("Finished...\n"); + return 1; +} + +int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]) +{ + int i; + const char *devstr; + + devstr = xusb_devpath(astribank->xusb); + DBG("%s: Loading %d PIC files...\n", devstr, numfiles); + for(i = 0; i < numfiles; i++) { + struct hexdata *picdata; + const char *curr = filelist[i]; + + DBG("%s\n", curr); + if((picdata = parse_hexfile(curr, MAX_HEX_LINES)) == NULL) { + perror(curr); + return -errno; + } + if(!pic_burn(astribank, picdata)) { + ERR("%s: PIC %s burning failed\n", devstr, curr); + return -ENODEV; + } + free_hexdata(picdata); + } + if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) { + ERR("%s: PIC end burning failed\n", devstr); + return -ENODEV; + } + return 0; +} diff --git a/xpp/pic_loader.h b/xpp/pic_loader.h new file mode 100644 index 0000000..f871bca --- /dev/null +++ b/xpp/pic_loader.h @@ -0,0 +1,46 @@ +#ifndef PIC_LOADER_H +#define PIC_LOADER_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include "astribank_usb.h" + +/* + * Astribank PIC loading + */ + +enum pic_command { + PIC_DATA_FLAG = 0x00, + PIC_START_FLAG = 0x01, + PIC_END_FLAG = 0x02, + PIC_ENDS_FLAG = 0x04, +}; + +#define PIC_PACK_LEN 0x0B +#define PIC_LINE_LEN 0x03 + +int send_picline(struct astribank_device *astribank, uint8_t card_type, + enum pic_command pcmd, int offs, uint8_t *data, int data_len); +int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]); + +#endif /* PIC_LOADER_H */ diff --git a/xpp/test_parse.c b/xpp/test_parse.c new file mode 100644 index 0000000..4ae1038 --- /dev/null +++ b/xpp/test_parse.c @@ -0,0 +1,57 @@ +/* + * Written by Oron Peled + * Copyright (C) 2006, 2007, 2008, 2009 Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include "hexfile.h" + +static void default_report_func(int level, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); +} + +int main(int argc, char *argv[]) +{ + struct hexdata *hd; + int i; + + if(argc < 2) { + fprintf(stderr, "Usage: program hexfile...\n"); + return 1; + } + parse_hexfile_set_reporting(default_report_func); + for(i = 1; i < argc; i++) { + hd = parse_hexfile(argv[i], 2000); + if(!hd) { + fprintf(stderr, "Parsing failed\n"); + return 1; + } + fprintf(stderr, "=== %s === (version: %s)\n", argv[i], hd->version_info); + dump_hexfile2(hd, "-", 60 ); + free_hexdata(hd); + } + return 0; +} diff --git a/xpp/twinstar b/xpp/twinstar new file mode 100755 index 0000000..287c9ef --- /dev/null +++ b/xpp/twinstar @@ -0,0 +1,267 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +use Getopt::Std; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Hardware; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; +use Dahdi::Xpp::Mpp; + +$Getopt::Std::STANDARD_HELP_VERSION = 1; +$main::VERSION = '$Id$'; + +sub HELP_MESSAGE() { + eval(usage()); + return 0; +} + +sub usage { + die "Usage: $0 {status|jump|enable-wd|disable-wd|ports}\n"; +} + +our ($opt_v, $opt_x); +getopts('vx') || usage; +@ARGV == 1 or usage; + + +# Find USB bus toplevel +my $usb_top; +$usb_top = '/dev/bus/usb'; +$usb_top = '/proc/bus/usb' unless -d $usb_top; +die "No USB toplevel found\n" unless -d $usb_top; + +sub tws_devs() { + my @devs; + foreach my $dev (Dahdi::Hardware->device_list) { + next unless $dev->is_astribank; + next unless $dev->product =~ /116./; + push(@devs, $dev->hardware_name); + } + return @devs; +} + +sub tws_usb_devfile($) { + my $name = shift || die; + # Remove prefix + if($name !~ s/usb://) { + die "$name is not a USB name\n"; + } + return "$usb_top/$name"; +} + +sub tws_show(@) { + my @usb_devs = @_; + my $format = "%-15s %-10s %-15s %-10s %-10s\n"; + + printf $format, 'DEVICE', 'PORT', 'WATCHDOG', 'POWER0', 'POWER1'; + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + if(!defined $mppinfo->{TWINSTAR_PORT}) { + printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name; + next; + } + my $power = $mppinfo->twinstar_power; + printf $format, + $dev->hardware_name, + $mppinfo->twinstar_port, + ($mppinfo->twinstar_watchdog) ? "on" : "off", + ($power->[0]) ? "yes" : "no", + ($power->[1]) ? "yes" : "no"; + } +} + +sub tws_portnum($) { + my $dev = shift || die "Missing dev"; + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + return undef; + } + return $mppinfo->twinstar_port; +} + +sub tws_showports(@) { + my @usb_devs = @_; + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + if(!defined $mppinfo->{TWINSTAR_PORT}) { + printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name; + next; + } + printf "%s\n", $mppinfo->{TWINSTAR_PORT}; + } +} + +sub tws_watchdog($@) { + my $on = shift; + die "tws_watchdog() on/off?" unless defined $on; + my @usb_devs = @_; + + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + $mppinfo->mpp_setwatchdog($on); + } +} + +sub tws_jump(@) { + my @usb_devs = @_; + + foreach my $dev (@usb_devs) { + my $mppinfo = $dev->mppinfo; + if(!defined $mppinfo) { + printf STDERR "%s: no MPP information\n", $dev->hardware_name; + next; + } + eval { + $mppinfo->mpp_jump; + }; + warn $@ if $@; + } +} + +sub dev_list() { + my @devs; + foreach my $dev (Dahdi::Hardware->device_list) { + next unless $dev->is_astribank; + next unless $dev->product =~ /116./; + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + push(@devs, $dev); + } + return @devs; +} + +my @usb_devices = dev_list(); + +if($ARGV[0] eq 'status') { + tws_show(@usb_devices); +} elsif($ARGV[0] eq 'jump') { + tws_jump(@usb_devices); +} elsif($ARGV[0] eq 'disable-wd') { + tws_watchdog(0, @usb_devices); +} elsif($ARGV[0] eq 'enable-wd') { + tws_watchdog(1, @usb_devices); +} elsif($ARGV[0] eq 'ports') { + tws_showports(@usb_devices); +} else { + usage; +} + +__END__ + +=head1 NAME + +twinstar - Control the Twinstar feature of a Xorcom Astribank + +=head1 SYNOPSIS + +twinstar {status|jump|enable-wd|disable-wd|ports} + +=head1 DESCRIPTION + +B is a tool to control the Twinstar (dual USB port) of a +Xorcom Astribank. There is a single and mandatory argument which is the +command to run. That command operates on all the Astribanks connected to +the system. + +Technically all the commands are implemented using Dahdi::Xpp::Mpp which +in turn uses astribank_tool. Thus using thus tool will require root +permissions or otherwise read/write permissions to the USB device. + +The twinstar may be in I, which means that it will jump +to the remote host if it loses contact with the local host. This can +happen if the machine is powered down or hangs or even if the xpp +drivers are unloaded. Which is why the standard twinstar scripts put the +Astribanks in twinstar mode on startup and remove it on normal shutdown. + +An Astribank will only jump to the other host (either if asked +explicitly or by the watchdog) only if there is a different Astribank +connected to the other port and running. Which is why all of this has no +effect on systems that don't need this functionality. + +The command are: + +=head2 status + +Shows the current status of all Astribanks. Note that it only shows +Astribanks whose current active USB port is the one connected to this +computer. + +Example output: + + DEVICE PORT WATCHDOG POWER0 POWER1 + usb:001/010 0 on yes yes + usb:001/011 0 on yes yes + +For each Astribank on the system that has Twinstar support we get: + +=over 4 + +=item Device + +The address of the device. This is the bus address, e.g. the address you +see in lsusb / dahdi_hardware. + +=item Port + +The active USB port on the Astribank. This should be always '0' on the +master and always 1 on the slave. + +=item Watchdog + +I if the watchdog is triggered in the Atribank or I otherwise. + +=item Power0, Power1 + +Shows which ports of this Astribank are connected to a USB port of a +running computer. This only shows whether or not the USB host provides +power. + +=back + +=head2 ports + +Shows the same 'Port' column of the B command. + +=head2 jump + +Command all the Astribanks to jump to the other port. This works +regardless the watchdog mode is enabled or not. But requires that there +is power on the other port. + +=head2 enable-wd + +Enables watchdog mode. + +=head2 disable-wd + +Disables watchdog mode. + +=head1 FILES + +B mostly uses astribank_tool which in turn mostly uses USB +files under /dev/bus/usb . + diff --git a/xpp/twinstar_hook b/xpp/twinstar_hook new file mode 100755 index 0000000..712d572 --- /dev/null +++ b/xpp/twinstar_hook @@ -0,0 +1,86 @@ +#! /bin/sh +# +# twinstar_hook: Example twinstar-specific hook script +# $Id$ +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# +# This is an experimental script to activate an Astribank TwinStar +# during failover. +# +# The script assume that there is an /etc/dahdi/xpp_order file +# specifying the Astribanks' labels according to the required +# registration order. +# +# This file can be easily generated by running: +# dahdi_genconf xpporder +# after the system is configured and working. +# + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +#exec 2> /dev/console +## If you wish to trace this script: +#exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2 + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" + +set -e + +export XBUS_SORT='SORT_LABEL' + +case "$ACTION" in +online) + echo "$ACTION($XBUS_NAME): " | $LOGGER + twinstar enable-wd + sleep 1 # Just for visual effect + asterisk -rx 'module load chan_dahdi.so' 2>&1 | $LOGGER + xpp_blink bzzt xpd "$XBUS_NUM" + ports=`twinstar ports` + if [ "$ports" = 0 ]; then + play /usr/share/dahdi/primary-pbx-is-ready.wav || : + elif [ "$ports" = 1 ]; then + play /usr/share/dahdi/backup-pbx-is-ready.wav || : + fi + echo "online: READY" | $LOGGER + ;; +offline) + echo "$ACTION($XBUS_NAME): " | $LOGGER + twinstar disable-wd + # If we want to disconnect everybody + twinstar jump + asterisk -rx 'module unload chan_dahdi.so' + ;; +*) + echo "$0: Unknown ACTION='$ACTION'" | $LOGGER + echo "$0: ARGS='$*'" | $LOGGER + echo "$0: ENV:" | $LOGGER + env | $LOGGER + exit 1 +esac + diff --git a/xpp/twinstar_setup b/xpp/twinstar_setup new file mode 100755 index 0000000..0e53bdf --- /dev/null +++ b/xpp/twinstar_setup @@ -0,0 +1,155 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2009, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { + my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); + $ENV{PATH} = "$dir:$ENV{PATH}"; +} + +use Dahdi::Config::Gen qw(is_true); +use Dahdi::Hardware; +use Dahdi::Xpp::Mpp; +use Dahdi::Xpp::Xbus; + +my $xpporder_file = $ENV{XPPORDER_CONF} || "/etc/dahdi/xpp_order"; + +my @devices = Dahdi::Hardware->device_list; +my @xbuses = Dahdi::Xpp::xbuses; + +my $format = "%-20s %-10s # %s\n"; + +sub bad_xpds($) { + my $xbus = shift || die; + my $bad_xpds = 0; + + foreach my $xpd ($xbus->xpds) { + if(! $xpd->spanno) { + my $fqn = $xpd->fqn; + warn "\t$fqn -- Not registered with DAHDI\n"; + $bad_xpds++; + } + } + return $bad_xpds; +} + +sub twinstar_checks() { + my @twinstar_good; + my $first_port; + if(! -d "/sys/bus/astribanks") { + die "CANNOT generate TwinStar setup -- xpp drivers are not loaded\n"; + } + foreach my $dev (@devices) { + my $hwname = $dev->hardware_name; + my $xbus; + my $loaded; + my $tws_port; + my $tws_power; + my $tws_watchdog; + my $mppinfo; + if(! $dev->is_astribank) { + warn "SKIP $hwname -- Only Astribanks can be used for TwinStar\n"; + next; + } + Dahdi::Xpp::Mpp->mpp_addinfo($dev); + $mppinfo = $dev->mppinfo; + if(! defined $mppinfo) { + warn "SKIP $hwname -- is not TwinStar ready\n"; + next; + } + if(! defined $mppinfo->{MPP_TALK}) { + warn "SKIP $hwname -- USB firmware is not loaded\n"; + next; + } + if(! $mppinfo->{TWINSTAR_CAPABLE}) { + warn "SKIP $hwname -- is not TwinStar capable\n"; + next; + } + $xbus = $dev->xbus; + if(! defined $xbus) { + warn "SKIP $hwname -- No XBUS for this device (FPGA firmware? Initialization?)\n"; + next; + } + my $dev = $xbus->transport; + my $connector = $xbus->connector; + my $label = $xbus->label; + my $xbusstr = sprintf "%s (%s) [%s]", $xbus->name, $connector, $label; + if(bad_xpds($xbus)) { + warn "SKIP $xbusstr -- Not registered with DAHDI\n"; + next; + } + my $port = $mppinfo->{TWINSTAR_PORT}; + if(! defined $port) { + warn "SKIP $xbusstr -- Cannot read USB port info\n"; + next; + } + my $power = $mppinfo->{TWINSTAR_POWER}; + if(! defined $power) { + warn "SKIP $xbusstr -- Cannot read USB power info\n"; + next; + } + if(!$power->[0] || !$power->[1]) { + warn "WARNING: Only one cable: $xbusstr\n"; + } + $first_port = $port unless defined $first_port; + printf "GOOD: %-15s port=%d %s\n", $label, $port, $connector; + push(@twinstar_good, $xbus); + if($first_port != $port) { + die + "$0: ", + "XBUS($connector, $label) ", + "connected to PORT $port ", + "(others to $first_port)\n"; + } + } + return @twinstar_good; +} + +my @twinstar_good = twinstar_checks; +if(!@twinstar_good) { + print STDERR "Abort. No Twinstar capable Astribanks found\n"; + exit 1; +} +print "Generating Configuration\n"; +system("dahdi_genconf -v xpporder"); +die "Failed: $?\n" if $?; + +1; + +__END__ + +=head1 NAME + +twinstar_setup - Prepares a server for Astribank TwinStar operation. + +=head1 DESCRIPTION + +This script prepares a server for Astribank TwinStar operation. +The stages are: + +=over + +=item Preliminary checks + +Check that we have only TwinStar capable Astribanks, that the drivers are already loaded. + +=item Configuration Generation + +Indirectly generate the F file that describes the current configuration. +This is done by running C + +This configuration file is used by twinstar_hook(8) to know when all Astribanks has reconnected +to the backup server. + +=item Deployment to Backup Server + +Not implemented yet. Should be done manualy. + +=back diff --git a/xpp/waitfor_xpds b/xpp/waitfor_xpds new file mode 100755 index 0000000..876a0c8 --- /dev/null +++ b/xpp/waitfor_xpds @@ -0,0 +1,163 @@ +#! /bin/sh + +# waitfor_xpds: wait until all Astribanks were initialized +# $Id$ + +# Written by Oron Peled +# Copyright (C) 2008-2009, Xorcom +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + + +set -e + +# For lab testing +mydir=`dirname $0` +PATH="${mydir}:${PATH}" +XPP_WAIT_AB_TIMEOUT=100 + +[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf + +ab_list() { + find /sys/devices -name idVendor 2>/dev/null | \ + xargs grep -H 'e4e4' 2>/dev/null | \ + sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \ + sed 's,/[^/]*$,,' || : +} + +ab_serial_nums() { + for i in `ab_list`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo "NO-SERIAL" + else + echo "$s" + fi + done | sort -u || : +} + +detected_serial_nums() { + for i in `ls -1d /sys/bus/astribanks/devices/*/transport 2>/dev/null`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo "NO-SERIAL" + else + echo "$s" + fi + done | sort -u || : +} + +calc_union() { + echo "$@" | tr -s ' ' '\n' | sort -u +} + +detected_ab_list() { + # Only check /sys info (don't use /proc anymore). + find /sys/bus/astribanks/devices/*/ -name waitfor_xpds 2> /dev/null || : +} + +waitfor_ab_initialization() { + oldab='' + while + if ! ab=`detected_ab_list`; then + exit 1 + fi + test "$oldab" != "$ab" + do + if [ "$ab" = '' ]; then + echo >&2 "Astribanks disappeared" + break + fi + oldab="$ab" + cat $ab + #echo -n 1>&2 "_" + done +} + +# Any hardware? +if ! dahdi_hardware="`which dahdi_hardware 2>/dev/null`"; then + echo >&2 "$0: Missing dahdi_hardware" + exit 0 +fi + +# Just make sure +if [ "`$dahdi_hardware | grep xpp_usb`" != "" ]; then + astribank_is_starting -v -a +fi +if ! astribank_is_starting; then + # No Astribanks ever seen -- nothing to do + exit 0 +fi + +# Sanity check +for i in `ab_list`; do + s=`cat "$i/serial" 2>/dev/null` || : + if [ "$s" = '' ]; then + echo >&2 "WARNING! Astribank without serial number: $i" + fi +done + +serial_nums=`ab_serial_nums` + +# Loop until detected (hopefully) all astribanks and they are initialized +echo -n 1>&2 "Astribanks detection " +tries="$XPP_WAIT_AB_TIMEOUT" +last_detected=0 +while + new_serial_nums=`ab_serial_nums` + detected_serial_nums=`detected_serial_nums` + curr_union=`calc_union $curr_union $serial_nums $new_serial_nums` + num_detected=`detected_ab_list | wc -l` + if [ "$num_detected" != "$last_detected" ]; then + # Visual feedback (number of detected AB so far) + echo -n 1>&2 "[$num_detected]" + last_detected="$num_detected" + waitfor_ab_initialization > /dev/null + fi + # Break only when we have something and it's stable + test "$curr_union" != "$detected_serial_nums" -o "$detected_serial_nums" = '' +do + if [ "$tries" -le 0 ]; then + echo 1>&2 "TIMEOUT" + exit 1 + fi + echo -n 1>&2 "." + sleep 1 + : $((tries-=1)) + serial_nums="$new_serial_nums" +done + +# Finished: Show a nice output +echo "" +cat /sys/bus/astribanks/devices/*/waitfor_xpds 2> /dev/null || : + +# Wait for device to stabilize and XPD's to finish initalizations +echo 1>&2 "Astribanks initializing spans" +if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' -a \ + "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" != 'yes' ]; then + if [ -f /etc/dahdi/xpp_order ]; then + # Now we can wait until the hotplug run would remove the semaphore + echo -n 1>&2 "Other DAHDI initializations... " + astribank_is_starting -v -w 1>&2 + else + echo 1>&2 "WARNING: No ASTERISK_SUPPORTS_DAHDI_HOTPLUG" \ + " and no /etc/dahdi/xpp_order" + fi +fi +# All Astribanks initialized -- remove semaphore +astribank_is_starting -v -r 1>&2 diff --git a/xpp/xpp.rules b/xpp/xpp.rules new file mode 100644 index 0000000..93f772d --- /dev/null +++ b/xpp/xpp.rules @@ -0,0 +1,11 @@ +# Load firmware into the Xorcom Astribank device: +SUBSYSTEM=="usb", ACTION=="add", \ +ENV{PRODUCT}=="e4e4/11[3456][013]/*", ENV{DEVTYPE}!="usb_interface", \ + RUN+="/usr/share/dahdi/xpp_fxloader udev $env{PRODUCT}" + +# Hotplug hook for Astribank up/down +# If you need this functionality, copy the astribank_hook.sample +# to $XPP_INIT_DIR/astribank_hook +# +# By default XPP_INIT_DIR="/usr/share/dahdi" +KERNEL=="xbus*", RUN+="%E{XPP_INIT_DIR}/astribank_hook udev $kernel $sysfs{status} $sysfs{connector}" diff --git a/xpp/xpp_blink b/xpp/xpp_blink new file mode 100755 index 0000000..ff63ae7 --- /dev/null +++ b/xpp/xpp_blink @@ -0,0 +1,168 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } + +use Dahdi; +use Dahdi::Span; +use Dahdi::Xpp; +use Dahdi::Xpp::Xbus; + +sub usage { + die "Usage: $0 {on|off|bzzt} {span | chan | xpd [] | label . That file +shows the current xpp sync master. + +Writing to it, force XPP drivers to use a different sync master + +=back + +=head1 SEE ALSO + +dahdi_registration(1), dahdi_cfg(1), README.Astribank diff --git a/xpp/xpp_timing b/xpp/xpp_timing new file mode 100755 index 0000000..f87215c --- /dev/null +++ b/xpp/xpp_timing @@ -0,0 +1,6 @@ +#! /bin/sh +grep 'DRIFT:' /sys/bus/astribanks/devices/xbus-*/timing | sed \ + -e 's,/sys/bus/astribanks/devices/,,' \ + -e 's,/timing:,: ,' \ + -e 's,DRIFT: ,,' \ + -e 's/^[^:]*:/\U&/' diff --git a/xpp/xtalk/debug.c b/xpp/xtalk/debug.c new file mode 100644 index 0000000..d2d4e15 --- /dev/null +++ b/xpp/xtalk/debug.c @@ -0,0 +1,73 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include + +int verbose = LOG_INFO; +int debug_mask; + +void log_function(int level, int mask, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + if (verbose >= level) { + if (level < LOG_DEBUG || (mask & debug_mask)) + vfprintf(stderr, msg, ap); + } + va_end(ap); +} + +void dump_packet(int loglevel, int mask, const char *msg, + const char *buf, int len) +{ + int i; + + if (!mask || (mask & debug_mask)) { + log_function(loglevel, ~0, "%-15s:", msg); + for (i = 0; i < len; i++) + log_function(loglevel, ~0, " %02X", (uint8_t)buf[i]); + log_function(loglevel, ~0, "\n"); + } +} + +/* from glibc info(1) */ +void print_backtrace(FILE *fp) +{ + void *array[10]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, 10); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + fprintf(fp, "%s\n", strings[i]); + free(strings); +} diff --git a/xpp/xtalk/debug.h b/xpp/xtalk/debug.h new file mode 100644 index 0000000..076cf4a --- /dev/null +++ b/xpp/xtalk/debug.h @@ -0,0 +1,52 @@ +#ifndef DEBUG_H +#define DEBUG_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include + +/* + * Each module should define a unique DBG_MASK + */ + +extern int verbose; +extern int debug_mask; + +/* + * Logging + */ +void log_function(int level, int mask, const char *msg, ...) + __attribute__((format(printf, 3, 4))); + +#define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, \ + __FILE__, __LINE__, __func__, ## arg) +#define WARN(fmt, arg...) log_function(LOG_WARNING, 0, "WARNING: " fmt, ## arg) +#define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg) +#define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \ + "%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __func__, ## arg) + +void dump_packet(int loglevel, int mask, const char *msg, + const char *buf, int len); +void print_backtrace(FILE *fp); + +#endif /* DEBUG_H */ diff --git a/xpp/xtalk/xlist.c b/xpp/xtalk/xlist.c new file mode 100644 index 0000000..d8cd3df --- /dev/null +++ b/xpp/xtalk/xlist.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +struct xlist_node *xlist_new(void *data) +{ + struct xlist_node *list; + + list = malloc(sizeof(*list)); + if (!list) + return NULL; + list->next = list; + list->prev = list; + list->data = data; + return list; +} + +void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor) +{ + struct xlist_node *curr; + struct xlist_node *next; + + if (!list) + return; + curr = list->next; + while (curr != list) { + next = curr->next; + if (destructor) + destructor(curr->data); + memset(curr, 0, sizeof(*curr)); + free(curr); + curr = next; + } + memset(list, 0, sizeof(*list)); + free(list); +} + +void xlist_append_item(struct xlist_node *list, struct xlist_node *item) +{ + assert(list); + assert(xlist_empty(item)); + item->next = list; + item->prev = list->prev; + list->prev->next = item; + list->prev = item; +} + +void xlist_prepend_item(struct xlist_node *list, struct xlist_node *item) +{ + assert(list); + assert(xlist_empty(item)); + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; +} + +void xlist_remove_item(struct xlist_node *item) +{ + assert(item); + item->prev->next = item->next; + item->next->prev = item->prev; + item->next = item->prev = item; +} + +struct xlist_node *xlist_shift(struct xlist_node *list) +{ + struct xlist_node *item; + + if (!list) + return NULL; + if (xlist_empty(list)) + return NULL; + item = list->next; + xlist_remove_item(item); + return item; +} + +int xlist_empty(const struct xlist_node *list) +{ + assert(list); + return list->next == list && list->prev == list; +} + +size_t xlist_length(const struct xlist_node *list) +{ + struct xlist_node *curr; + size_t count = 0; + + for (curr = list->next; curr != list; curr = curr->next) + count++; + return count; +} diff --git a/xpp/xtalk/xlist.h b/xpp/xtalk/xlist.h new file mode 100644 index 0000000..4f7f818 --- /dev/null +++ b/xpp/xtalk/xlist.h @@ -0,0 +1,29 @@ +#ifndef XLIST_H +#define XLIST_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +struct xlist_node { + void *data; + struct xlist_node *next; + struct xlist_node *prev; +}; + +typedef void (*xlist_destructor_t)(void *data); + +struct xlist_node *xlist_new(void *data); +void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor); +void xlist_append_item(struct xlist_node *list, struct xlist_node *item); +void xlist_remove_item(struct xlist_node *item); +struct xlist_node *xlist_shift(struct xlist_node *list); +int xlist_empty(const struct xlist_node *list); +size_t xlist_length(const struct xlist_node *list); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XLIST_H */ diff --git a/xpp/xtalk/xtalk.c b/xpp/xtalk/xtalk.c new file mode 100644 index 0000000..ee2b520 --- /dev/null +++ b/xpp/xtalk/xtalk.c @@ -0,0 +1,497 @@ +/* + * Written by Oron Peled + * Copyright (C) 2009, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBG_MASK 0x02 + +#define TIMEOUT 6000 + +/* + * Base XTALK device. A pointer to this struct + * should be included in the struct representing + * the dialect. + */ +struct xtalk_device { + void *transport_priv; /* e.g: struct xusb */ + struct xtalk_ops ops; + struct xtalk_protocol xproto; + uint8_t xtalk_proto_version; + uint8_t status; + size_t packet_size; + uint16_t tx_sequenceno; +}; + +CMD_DEF(XTALK, ACK, + uint8_t stat; + ); + +CMD_DEF(XTALK, PROTO_GET, + uint8_t proto_version; + uint8_t reserved; + ); + +CMD_DEF(XTALK, PROTO_GET_REPLY, + uint8_t proto_version; + uint8_t reserved; + ); + +union XTALK_PDATA(XTALK) { + MEMBER(XTALK, ACK); + MEMBER(XTALK, PROTO_GET); + MEMBER(XTALK, PROTO_GET_REPLY); +} PACKED members; + +struct xtalk_protocol xtalk_base = { + .name = "XTALK", + .proto_version = 0, + .commands = { + CMD_RECV(XTALK, ACK, NULL), + CMD_SEND(XTALK, PROTO_GET), + CMD_RECV(XTALK, PROTO_GET_REPLY, NULL), + }, + .ack_statuses = { + ACK_STAT(OK, "Acknowledges previous command"), + ACK_STAT(FAIL, "Last command failed"), + ACK_STAT(RESET_FAIL, "reset failed"), + ACK_STAT(NODEST, "No destination is selected"), + ACK_STAT(MISMATCH, "Data mismatch"), + ACK_STAT(NOACCESS, "No access"), + ACK_STAT(BAD_CMD, "Bad command"), + ACK_STAT(TOO_SHORT, "Packet is too short"), + ACK_STAT(ERROFFS, "Offset error (not used)"), + ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"), + ACK_STAT(NO_EEPROM, "No EEPROM was found"), + ACK_STAT(WRITE_FAIL, "Writing to device failed"), + ACK_STAT(NOPWR_ERR, "No power on USB connector"), + } +}; + +void free_command(struct xtalk_command *cmd) +{ + if (!cmd) + return; + memset(cmd, 0, cmd->header.len); + free(cmd); +} + +static const struct xtalk_command_desc *get_command_desc( + const struct xtalk_protocol *xproto, uint8_t op) +{ + const struct xtalk_command_desc *desc; + + if (!xproto) + return NULL; + desc = &xproto->commands[op]; + if (!desc->name) + return NULL; +#if 0 + DBG("%s version=%d, op=0x%X (%s)\n", + xproto->name, xproto->proto_version, + op, desc->name); +#endif + return desc; +} + +static const char *ack_status_msg(const struct xtalk_protocol *xproto, + uint8_t status) +{ + const char *ack_status; + + if (!xproto) + return NULL; + ack_status = xproto->ack_statuses[status]; + DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status); + return ack_status; +} + +int xtalk_set_protocol(struct xtalk_device *xtalk_dev, + const struct xtalk_protocol *xproto) +{ + const char *protoname = (xproto) ? xproto->name : "GLOBAL"; + int i; + + DBG("%s\n", protoname); + memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto)); + for (i = 0; i < MAX_OPS; i++) { + const struct xtalk_command_desc *desc; + + desc = get_command_desc(xproto, i); + if (desc) { + if (!IS_PRIVATE_OP(i)) { + ERR("Bad op=0x%X " + "(should be in the range [0x%X-0x%X]\n", + i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); + return -EINVAL; + } + xtalk_dev->xproto.commands[i] = *desc; + DBG("private: op=0x%X (%s)\n", i, desc->name); + } else { + if (!IS_PRIVATE_OP(i)) { + const char *name; + + xtalk_dev->xproto.commands[i] = + xtalk_base.commands[i]; + name = xtalk_dev->xproto.commands[i].name; + if (name) + DBG("global: op=0x%X (%s)\n", i, name); + } + } + } + for (i = 0; i < MAX_STATUS; i++) { + const char *stat_msg; + + stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL; + if (stat_msg) { + if (!IS_PRIVATE_OP(i)) { + ERR("Bad status=0x%X " + "(should be in the range [0x%X-0x%X]\n", + i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); + return -EINVAL; + } + xtalk_dev->xproto.ack_statuses[i] = stat_msg; + DBG("private: status=0x%X (%s)\n", i, stat_msg); + } else { + if (!IS_PRIVATE_OP(i)) { + const char *stat_msg; + + xtalk_dev->xproto.ack_statuses[i] = + xtalk_base.ack_statuses[i]; + stat_msg = xtalk_dev->xproto.ack_statuses[i]; + if (stat_msg) + DBG("global: status=0x%X (%s)\n", + i, stat_msg); + } + } + } + xtalk_dev->xproto.name = protoname; + xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0; + return 0; +} + +struct xtalk_command *new_command( + const struct xtalk_device *xtalk_dev, + uint8_t op, uint16_t extra_data) +{ + const struct xtalk_protocol *xproto; + struct xtalk_command *cmd; + const struct xtalk_command_desc *desc; + uint16_t len; + + xproto = &xtalk_dev->xproto; + desc = get_command_desc(xproto, op); + if (!desc) { + ERR("Unknown op=0x%X.\n", op); + return NULL; + } + DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data); + len = desc->len + extra_data; + cmd = malloc(len); + if (!cmd) { + ERR("Out of memory\n"); + return NULL; + } + if (extra_data) { + uint8_t *ptr = (uint8_t *)cmd; + + DBG("clear extra_data (%d bytes)\n", extra_data); + memset(ptr + desc->len, 0, extra_data); + } + cmd->header.op = op; + cmd->header.len = len; + cmd->header.seq = 0; /* Overwritten in send_usb() */ + return cmd; +} + +void xtalk_dump_command(struct xtalk_command *cmd) +{ + uint16_t len; + int i; + + len = cmd->header.len; + if (len < sizeof(struct xtalk_header)) { + ERR("Command too short (%d)\n", len); + return; + } + INFO("DUMP: OP=0x%X len=%d seq=%d\n", + cmd->header.op, cmd->header.len, cmd->header.seq); + for (i = 0; i < len - sizeof(struct xtalk_header); i++) + INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); +} + +static int send_command(struct xtalk_device *xtalk_dev, + struct xtalk_command *cmd, int timeout) +{ + int ret; + int len; + void *priv = xtalk_dev->transport_priv; + + len = cmd->header.len; + cmd->header.seq = xtalk_dev->tx_sequenceno; + + ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout); + if (ret < 0) + DBG("send_func failed ret=%d\n", ret); + xtalk_dev->tx_sequenceno++; + return ret; +} + +static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev, + int timeout) +{ + struct xtalk_command *reply; + void *priv = xtalk_dev->transport_priv; + size_t psize = xtalk_dev->packet_size; + int ret; + + reply = malloc(psize); + if (!reply) { + ERR("Out of memory\n"); + goto err; + } + reply->header.len = 0; + ret = xtalk_dev->ops.recv_func(priv, (char *)reply, psize, timeout); + if (ret < 0) { + ERR("Receive from usb failed.\n"); + goto err; + } else if (ret == 0) { + goto err; /* No reply */ + } + if (ret != reply->header.len) { + ERR("Wrong length received: got %d bytes, " + "but length field says %d bytes%s\n", + ret, reply->header.len, + (ret == 1) ? ". Old USB firmware?" : ""); + goto err; + } + /* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */ + return reply; +err: + if (reply) { + memset(reply, 0, psize); + free_command(reply); + } + return NULL; +} + + +__attribute__((warn_unused_result)) +int process_command( + struct xtalk_device *xtalk_dev, + struct xtalk_command *cmd, + struct xtalk_command **reply_ref) +{ + const struct xtalk_protocol *xproto; + struct xtalk_command *reply = NULL; + const struct xtalk_command_desc *reply_desc; + const struct xtalk_command_desc *expected; + const struct xtalk_command_desc *cmd_desc; + uint8_t reply_op; + const char *protoname; + int ret; + + xproto = &xtalk_dev->xproto; + protoname = (xproto) ? xproto->name : "GLOBAL"; + /* So the caller knows if a reply was received */ + if (reply_ref) + *reply_ref = NULL; + reply_op = cmd->header.op | XTALK_REPLY_MASK; + cmd_desc = get_command_desc(xproto, cmd->header.op); + expected = get_command_desc(xproto, reply_op); + ret = send_command(xtalk_dev, cmd, TIMEOUT); + if (!reply_ref) { + DBG("No reply requested\n"); + goto out; + } + if (ret < 0) { + ERR("send_command failed: %d\n", ret); + goto out; + } + reply = recv_command(xtalk_dev, TIMEOUT); + if (!reply) { + ERR("recv_command failed\n"); + ret = -EPROTO; + goto out; + } + *reply_ref = reply; + if ((reply->header.op & 0x80) != 0x80) { + ERR("Unexpected reply op=0x%02X, should have MSB set.\n", + reply->header.op); + ret = -EPROTO; + goto out; + } + DBG("REPLY OP: 0x%X\n", reply->header.op); + reply_desc = get_command_desc(xproto, reply->header.op); + if (!reply_desc) { + ERR("Unknown reply (proto=%s) op=0x%02X\n", + protoname, reply->header.op); + ret = -EPROTO; + goto out; + } + DBG("REPLY NAME: %s\n", reply_desc->name); + if (reply->header.op == XTALK_ACK) { + int status = CMD_FIELD(reply, XTALK, ACK, stat); + + if (expected) { + ERR("Expected OP=0x%02X: Got ACK(%d): %s\n", + reply_op, + status, + ack_status_msg(xproto, status)); + ret = -EPROTO; + goto out; + } else if (status != STAT_OK) { + + ERR("Got ACK (for OP=0x%X [%s]): %d %s\n", + cmd->header.op, + cmd_desc->name, + status, ack_status_msg(xproto, status)); + ret = -EPROTO; + goto out; + } + /* Good expected ACK ... */ + } else if (reply->header.op != reply_op) { + ERR("Expected OP=0x%02X: Got OP=0x%02X\n", + reply_op, reply->header.op); + ret = -EPROTO; + goto out; + } + if (expected && expected->len > reply->header.len) { + ERR("Expected len=%d: Got len=%d\n", + expected->len, reply->header.len); + ret = -EPROTO; + goto out; + } + if (cmd->header.seq != reply->header.seq) { + ERR("Expected seq=%d: Got seq=%d\n", + cmd->header.seq, reply->header.seq); + ret = -EPROTO; + goto out; + } + ret = reply->header.len; /* All good, return the length */ + DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret); +out: + free_command(cmd); + if (!reply_ref && reply) + free_command(reply); + return ret; +} + +/* + * Protocol Commands + */ + +int xtalk_proto_query(struct xtalk_device *xtalk_dev) +{ + struct xtalk_command *cmd; + struct xtalk_command *reply; + uint8_t proto_version; + int ret; + + DBG("\n"); + assert(xtalk_dev != NULL); + proto_version = xtalk_dev->xproto.proto_version; + cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0); + if (!cmd) { + ERR("new_command failed\n"); + return -ENOMEM; + } + /* Protocol Version */ + CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version; + ret = process_command(xtalk_dev, cmd, &reply); + if (ret < 0) { + ERR("process_command failed: %d\n", ret); + goto out; + } + xtalk_dev->xtalk_proto_version = + CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version); + if (xtalk_dev->xtalk_proto_version != proto_version) { + DBG("Got %s protocol version: 0x%02x (expected 0x%02x)\n", + xtalk_dev->xproto.name, + xtalk_dev->xtalk_proto_version, + proto_version); + ret = xtalk_dev->xtalk_proto_version; + goto out; + } + DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version); + ret = xtalk_dev->xtalk_proto_version; +out: + free_command(reply); + return ret; +} + +/* + * Wrappers + */ + +struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, + size_t packet_size, void *priv) +{ + struct xtalk_device *xtalk_dev; + int ret; + + DBG("\n"); + assert(ops != NULL); + xtalk_dev = malloc(sizeof(*xtalk_dev)); + if (!xtalk_dev) { + ERR("Allocating XTALK device memory failed\n"); + return NULL; + } + memset(xtalk_dev, 0, sizeof(*xtalk_dev)); + memcpy((void *)&xtalk_dev->ops, (const void *)ops, + sizeof(xtalk_dev->ops)); + xtalk_dev->transport_priv = priv; + xtalk_dev->packet_size = packet_size; + xtalk_dev->tx_sequenceno = 1; + ret = xtalk_set_protocol(xtalk_dev, NULL); + if (ret < 0) { + ERR("GLOBAL Protocol registration failed: %d\n", ret); + goto err; + } + return xtalk_dev; + +err: + if (xtalk_dev) + xtalk_delete(xtalk_dev); + return NULL; +} + +void xtalk_delete(struct xtalk_device *xtalk_dev) +{ + void *priv; + + if (!xtalk_dev) + return; + DBG("\n"); + priv = xtalk_dev->transport_priv; + assert(priv); + xtalk_dev->tx_sequenceno = 0; + assert(&xtalk_dev->ops != NULL); + assert(&xtalk_dev->ops.close_func != NULL); + xtalk_dev->ops.close_func(priv); +} diff --git a/xpp/xtalk/xtalk.h b/xpp/xtalk/xtalk.h new file mode 100644 index 0000000..88f0260 --- /dev/null +++ b/xpp/xtalk/xtalk.h @@ -0,0 +1,178 @@ +#ifndef XTALK_H +#define XTALK_H +/* + * Written by Oron Peled + * Copyright (C) 2009, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * XTALK - Base protocol for our USB devices + * It is meant to provide a common base for layered + * protocols (dialects) + */ + +#include +#include +/* Definitions common to the firmware (in include/ directory) */ +#include + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#error "We do not know how your compiler packs structures" +#endif + +struct xtalk_device; +struct xtalk_command_desc; + +typedef int (*xtalk_cmd_callback_t)( + struct xtalk_device *xtalk_dev, + struct xtalk_command_desc *xtalk_cmd); + +/* Describe a single xtalk command */ +struct xtalk_command_desc { + uint8_t op; + const char *name; + xtalk_cmd_callback_t callback; + uint16_t len; /* Minimal length */ +}; + +/* Define a complete protocol */ +struct xtalk_protocol { + const char *name; + uint8_t proto_version; + struct xtalk_command_desc commands[MAX_OPS]; + const char *ack_statuses[MAX_STATUS]; +}; + +/* + * The common header of every xtalk command + * in every xtalk dialect. + */ +struct xtalk_header { + uint16_t len; + uint16_t seq; + uint8_t op; /* MSB: 0 - to device, 1 - from device */ +} PACKED; + +struct xtalk_command { + /* Common part */ + struct xtalk_header header; + /* Each dialect has its own data members */ + union private_data { + uint8_t raw_data[0]; + } PACKED alt; +} PACKED; + +/* + * Macros to unify access to protocol packets and fields: + * p - signify the dialect prefix (XTALK for base protocol) + * o - signify command op (e.g: ACK) + * cmd - A pointer to struct xtalk_command + * field - field name (e.g: raw_data) + */ +#define XTALK_STRUCT(p, o) p ## _struct_ ## o +#define XTALK_PDATA(o) xtalk_privdata_ ## o +#define XTALK_CMD_PTR(cmd, p) ((union XTALK_PDATA(p)*)&((cmd)->alt)) +#define CMD_FIELD(cmd, p, o, field) \ + (XTALK_CMD_PTR(cmd, p)->XTALK_STRUCT(p, o).field) +#define CMD_DEF(p, o, ...) struct XTALK_STRUCT(p, o) { \ + __VA_ARGS__ \ + } PACKED XTALK_STRUCT(p, o) +#define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o) + +/* Wrappers for transport (xusb) functions */ +struct xtalk_ops { + int (*send_func)(void *transport_priv, void *data, size_t len, + int timeout); + int (*recv_func)(void *transport_priv, void *data, size_t maxlen, + int timeout); + int (*close_func)(void *transport_priv); +}; + +/* + * Base XTALK device. A pointer to this struct + * should be included in the struct representing + * the dialect. + */ +struct xtalk_device; + +/* high-level */ +struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, + size_t packet_size, void *transport_priv); +void xtalk_delete(struct xtalk_device *dev); +int xtalk_set_protocol(struct xtalk_device *xtalk_dev, + const struct xtalk_protocol *xproto); +int xtalk_proto_query(struct xtalk_device *dev); +void xtalk_dump_command(struct xtalk_command *cmd); + +/* low-level */ +int process_command( + struct xtalk_device *dev, + struct xtalk_command *cmd, + struct xtalk_command **reply_ref); +struct xtalk_command *new_command( + const struct xtalk_device *xtalk_dev, + uint8_t op, uint16_t extra_data); +void free_command(struct xtalk_command *cmd); + +/* + * Convenience macros to define entries in a protocol command table: + * p - signify the dialect prefix (XTALK for base protocol) + * o - signify command op (e.g: ACK) + * cb - A callback function (type xtalk_cmd_callback_t) + */ +#define CMD_RECV(p, o, cb) \ + [p ## _ ## o | XTALK_REPLY_MASK] = { \ + .op = (p ## _ ## o) | XTALK_REPLY_MASK, \ + .name = (#o "_reply"), \ + .callback = (cb), \ + .len = \ + sizeof(struct xtalk_header) + \ + sizeof(struct XTALK_STRUCT(p, o)), \ + } + +#define CMD_SEND(p, o) \ + [p ## _ ## o] = { \ + .op = (p ## _ ## o), \ + .name = (#o), \ + .callback = NULL, \ + .len = \ + sizeof(struct xtalk_header) + \ + sizeof(struct XTALK_STRUCT(p, o)), \ + } + +/* + * Convenience macro to define statuses: + * x - status code (e.g: OK) + * m - status message (const char *) + */ +#define ACK_STAT(x, m) [STAT_ ## x] = (m) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XTALK_H */ diff --git a/xpp/xtalk/xtalk_defs.h b/xpp/xtalk/xtalk_defs.h new file mode 100644 index 0000000..826ad67 --- /dev/null +++ b/xpp/xtalk/xtalk_defs.h @@ -0,0 +1,41 @@ +#ifndef XTALK_DEFS_H +#define XTALK_DEFS_H + +#define MAX_OPS 256 /* single byte */ +#define MAX_STATUS 256 /* single byte */ + +#define XTALK_REPLY_MASK 0x80 /* Every reply has this bit */ + +#define PRIVATE_OP_FIRST 0x05 +#define PRIVATE_OP_LAST 0x7F +#define IS_PRIVATE_OP(x) ( \ + (((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \ + (((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \ + ) + +#define XTALK_ACK 0x80 +#define XTALK_PROTO_GET 0x01 +#define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK) +#define XTALK_FWVERS_GET 0x11 +#define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK) +/* Get EEPROM table contents Product/Vendor Id ... */ +#define XTALK_CAPS_GET 0x0E +#define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK) + +/*------------- XTALK: statuses in ACK ---------------------------------------*/ +#define STAT_OK 0x00 /* OK */ +#define STAT_FAIL 0x01 /* last command failed */ +#define STAT_RESET_FAIL 0x02 /* reset failed */ +#define STAT_NODEST 0x03 /* No destination is selected */ +#define STAT_MISMATCH 0x04 /* Data mismatch */ +#define STAT_NOACCESS 0x05 /* No access */ +#define STAT_BAD_CMD 0x06 /* Bad command */ +#define STAT_TOO_SHORT 0x07 /* Packet is too short */ +#define STAT_ERROFFS 0x08 /* Offset error (not used) */ +#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ +#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ +#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ +#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ + + +#endif /* XTALK_DEFS_H */ diff --git a/xpp/xtalk/xusb.c b/xpp/xtalk/xusb.c new file mode 100644 index 0000000..d33f013 --- /dev/null +++ b/xpp/xtalk/xusb.c @@ -0,0 +1,943 @@ +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define _GNU_SOURCE /* for memrchr() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBG_MASK 0x01 +#define TIMEOUT 500 +#define MAX_RETRIES 10 + +struct xusb { + struct usb_device *dev; + usb_dev_handle *handle; + const struct xusb_spec *spec; + char iManufacturer[BUFSIZ]; + char iProduct[BUFSIZ]; + char iSerialNumber[BUFSIZ]; + char iInterface[BUFSIZ]; + char devpath_tail[PATH_MAX + 1]; + int bus_num; + int device_num; + int interface_num; + int ep_out; + int ep_in; + int is_usb2; + int is_claimed; + int is_open; + size_t packet_size; +}; + +static void xusb_init(); + +/* + * XTALK_OPTIONS: + * A white-space separated list of options, read from the environment + * variable of that name. Existing options: + * + * - "use-clear-halt" -- force USB "clear_halt" operation during + * device initialization (this is the default) + * - "no-use-clear-halt" -- force no USB "clear_halt" operation during + * device initialization + * - "no-lock" -- prevent using global sempahore to serialize libusb + * initialization. Previously done via "XUSB_NOLOCK" + * environment variable. + */ +int xtalk_parse_options(void); +int xtalk_option_use_clear_halt(void); +int xtalk_option_no_lock(void); + +void xusb_init_spec(struct xusb_spec *spec, char *name, + uint16_t vendor_id, uint16_t product_id, + int nifaces, int iface, int nep, int ep_out, int ep_in) +{ + DBG("Initialize %s: interfaces=%d using interface num=%d endpoints=%d " + "(OUT=0x%02X, IN=0x%02X)\n", + name, nifaces, iface, nep, ep_out, ep_in); + memset(spec, 0, sizeof(*spec)); + spec->name = name; + spec->num_interfaces = nifaces; + spec->my_interface_num = iface; + spec->num_endpoints = nep; + spec->my_vendor_id = vendor_id; + spec->my_product_id = product_id; + spec->my_ep_in = ep_in; + spec->my_ep_out = ep_out; +} + +#define EP_OUT(xusb) ((xusb)->spec->my_ep_out) +#define EP_IN(xusb) ((xusb)->spec->my_ep_in) + +/* + * USB handling + */ + +static int get_usb_string(struct xusb *xusb, uint8_t item, char *buf) +{ + char tmp[BUFSIZ]; + int ret; + + assert(xusb->handle); + if (!item) + return 0; + ret = usb_get_string_simple(xusb->handle, item, tmp, BUFSIZ); + if (ret <= 0) + return ret; + return snprintf(buf, BUFSIZ, "%s", tmp); +} + +static const struct usb_interface_descriptor *get_interface( + const struct usb_device *dev, + int my_interface_num, + int num_interfaces) +{ + const struct usb_interface *interface; + const struct usb_interface_descriptor *iface_desc; + const struct usb_config_descriptor *config_desc; + int num_altsetting; + + config_desc = dev->config; + if (!config_desc) { + ERR("No configuration descriptor: strange USB1 controller?\n"); + return NULL; + } + if (num_interfaces && config_desc->bNumInterfaces != num_interfaces) { + DBG("Wrong number of interfaces: have %d need %d\n", + config_desc->bNumInterfaces, num_interfaces); + return NULL; + } + interface = &config_desc->interface[my_interface_num]; + assert(interface != NULL); + iface_desc = interface->altsetting; + num_altsetting = interface->num_altsetting; + assert(num_altsetting != 0); + assert(iface_desc != NULL); + return iface_desc; +} + +static int match_interface(const struct usb_device *dev, + const struct xusb_spec *spec) +{ + const struct usb_device_descriptor *dev_desc; + const struct usb_interface_descriptor *iface_desc; + + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("Checking: %04X:%04X interfaces=%d interface num=%d endpoints=%d: " + "\"%s\"\n", + spec->my_vendor_id, + spec->my_product_id, + spec->num_interfaces, + spec->my_interface_num, + spec->num_endpoints, + spec->name); + if (dev_desc->idVendor != spec->my_vendor_id) { + DBG("Wrong vendor id 0x%X\n", dev_desc->idVendor); + return 0; + } + if (dev_desc->idProduct != spec->my_product_id) { + DBG("Wrong product id 0x%X\n", dev_desc->idProduct); + return 0; + } + iface_desc = get_interface(dev, spec->my_interface_num, + spec->num_interfaces); + if (!iface_desc) { + ERR("Could not get interface descriptor of device: %s\n", + usb_strerror()); + return 0; + } + if (iface_desc->bInterfaceClass != 0xFF) { + DBG("Wrong interface class 0x%X\n", + iface_desc->bInterfaceClass); + return 0; + } + if (iface_desc->bInterfaceNumber != spec->my_interface_num) { + DBG("Wrong interface number %d (expected %d)\n", + iface_desc->bInterfaceNumber, spec->my_interface_num); + return 0; + } + if (iface_desc->bNumEndpoints != spec->num_endpoints) { + DBG("Wrong number of endpoints %d\n", + iface_desc->bNumEndpoints); + return 0; + } + return 1; +} + +#define GET_USB_STRING(xusb, from, item) \ + get_usb_string((xusb), (from)->item, xusb->item) + +static int xusb_fill_strings(struct xusb *xusb) +{ + const struct usb_device_descriptor *dev_desc; + const struct usb_interface_descriptor *iface_desc; + + + dev_desc = &xusb->dev->descriptor; + assert(dev_desc); + if (GET_USB_STRING(xusb, dev_desc, iManufacturer) < 0) { + ERR("Failed reading iManufacturer string: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, dev_desc, iProduct) < 0) { + ERR("Failed reading iProduct string: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, dev_desc, iSerialNumber) < 0) { + ERR("Failed reading iSerialNumber string: %s\n", + usb_strerror()); + return 0; + } + iface_desc = get_interface(xusb->dev, xusb->interface_num, 0); + if (!iface_desc) { + ERR("Could not get interface descriptor of device: %s\n", + usb_strerror()); + return 0; + } + if (GET_USB_STRING(xusb, iface_desc, iInterface) < 0) { + ERR("Failed reading iInterface string: %s\n", usb_strerror()); + return 0; + } + return 1; +} + +static int xusb_open(struct xusb *xusb) +{ + assert(xusb); + if (xusb->is_open) + return 1; + xusb->handle = usb_open(xusb->dev); + if (!xusb->handle) { + ERR("Failed to open usb device '%s': %s\n", + xusb->devpath_tail, usb_strerror()); + return 0; + } + xusb->is_open = 1; + return 1; +} + +int xusb_claim_interface(struct xusb *xusb) +{ + const struct usb_device_descriptor *dev_desc; + int ret; + + assert(xusb); + xusb_open(xusb); /* If it's not open yet... */ + if (usb_claim_interface(xusb->handle, xusb->interface_num) != 0) { + ERR("usb_claim_interface %d in '%s': %s\n", + xusb->interface_num, + xusb->devpath_tail, + usb_strerror()); + return 0; + } + xusb->is_claimed = 1; + xusb_fill_strings(xusb); + dev_desc = &xusb->dev->descriptor; + DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] " + "SerialNumber=[%s] Interface=[%s]\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber, + xusb->iInterface); + if (xtalk_option_use_clear_halt()) { + DBG("Using clear_halt()\n"); + if (usb_clear_halt(xusb->handle, EP_OUT(xusb)) != 0) { + ERR("Clearing output endpoint: %s\n", usb_strerror()); + return 0; + } + if (usb_clear_halt(xusb->handle, EP_IN(xusb)) != 0) { + ERR("Clearing input endpoint: %s\n", usb_strerror()); + return 0; + } + } + ret = xusb_flushread(xusb); + if (ret < 0) { + ERR("xusb_flushread failed: %d\n", ret); + return 0; + } + return 1; +} + +static void xusb_list_dump(struct xlist_node *xusb_list) +{ + struct xlist_node *curr; + struct xusb *xusb; + + for (curr = xusb_list->next; curr != xusb_list; curr = curr->next) { + struct usb_device *dev; + struct usb_bus *bus; + struct usb_device_descriptor *dev_desc; + + xusb = curr->data; + assert(xusb); + dev = xusb->dev; + assert(dev); + bus = dev->bus; + assert(bus); + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("usb:ID=%04X:%04X [%s / %s / %s], (%s/%s)\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber, + bus->dirname, + dev->filename + ); + } +} + +void xusb_destroy(struct xusb *xusb) +{ + if (xusb) { + xusb_close(xusb); + memset(xusb, 0, sizeof(*xusb)); + free(xusb); + } +} + +static struct xusb *xusb_new(struct usb_device *dev, + const struct xusb_spec *spec) +{ + struct usb_device_descriptor *dev_desc; + struct usb_config_descriptor *config_desc; + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t max_packet_size; + int i; + struct xusb *xusb = NULL; + + /* + * Get information from the usb_device + */ + dev_desc = &dev->descriptor; + if (!dev_desc) { + ERR("usb device without a device descriptor\n"); + goto fail; + } + config_desc = dev->config; + if (!config_desc) { + ERR("usb device without a configuration descriptor\n"); + goto fail; + } + interface = &config_desc->interface[spec->my_interface_num]; + iface_desc = interface->altsetting; + endpoint = iface_desc->endpoint; + /* Calculate max packet size */ + max_packet_size = PACKET_SIZE; + for (i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { + DBG("Validating endpoint @ %d (interface %d)\n", + i, spec->my_interface_num); + if (endpoint->bEndpointAddress == spec->my_ep_out || + endpoint->bEndpointAddress == spec->my_ep_in) { + if (endpoint->wMaxPacketSize > PACKET_SIZE) { + ERR("EP #%d wMaxPacketSize too large (%d)\n", + i, endpoint->wMaxPacketSize); + goto fail; + } + if (endpoint->wMaxPacketSize < max_packet_size) + max_packet_size = endpoint->wMaxPacketSize; + } + } + /* Fill xusb */ + xusb = malloc(sizeof(*xusb)); + if (!xusb) { + ERR("Out of memory"); + goto fail; + } + memset(xusb, 0, sizeof(*xusb)); + xusb->dev = dev; + xusb->spec = spec; + sscanf(dev->bus->dirname, "%d", &xusb->bus_num); + sscanf(dev->filename, "%d", &xusb->device_num); + snprintf(xusb->devpath_tail, PATH_MAX, "%03d/%03d", + xusb->bus_num, xusb->device_num); + xusb->interface_num = spec->my_interface_num; + xusb->ep_out = spec->my_ep_out; + xusb->ep_in = spec->my_ep_in; + xusb->packet_size = max_packet_size; + xusb->is_usb2 = (max_packet_size == 512); + if (!xusb_open(xusb)) { + ERR("Failed opening device: %04X:%04X - %s\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->devpath_tail); + goto fail; + } + DBG("%04X:%04X - %s\n", + dev_desc->idVendor, + dev_desc->idProduct, + xusb->devpath_tail); + return xusb; +fail: + xusb_destroy(xusb); + return NULL; +} + +struct xusb *xusb_find_iface(const char *devpath, + int iface_num, + int ep_out, + int ep_in, + struct xusb_spec *dummy_spec) +{ + struct usb_bus *bus; + + DBG("\n"); + xusb_init(); + for (bus = usb_get_busses(); bus; bus = bus->next) { + int bus_num; + char tmppath[PATH_MAX + 1]; + struct usb_device *dev; + + tmppath[0] = '\0'; + sscanf(bus->dirname, "%d", &bus_num); + snprintf(tmppath, sizeof(tmppath), "%03d", bus_num); + DBG("Check bus %d: %s ? %s\n", bus_num, tmppath, devpath); + if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) + continue; + DBG("Matched bus %d\n", bus_num); + for (dev = bus->devices; dev; dev = dev->next) { + struct usb_device_descriptor *dev_desc; + struct usb_config_descriptor *config_desc; + struct usb_interface *interface; + struct xusb *xusb; + int device_num; + + sscanf(dev->filename, "%d", &device_num); + DBG("Check device %d\n", device_num); + snprintf(tmppath, sizeof(tmppath), "%03d/%03d", + bus_num, device_num); + if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) + continue; + dev_desc = &dev->descriptor; + assert(dev_desc); + config_desc = dev->config; + assert(config_desc); + interface = config_desc->interface; + assert(interface); + DBG("Matched device %s: %X:%X\n", tmppath, + dev_desc->idVendor, dev_desc->idProduct); + assert(dummy_spec); + xusb_init_spec(dummy_spec, "", + dev_desc->idVendor, dev_desc->idProduct, + config_desc->bNumInterfaces, + iface_num, + interface->altsetting->bNumEndpoints, + ep_out, ep_in); + xusb = xusb_new(dev, dummy_spec); + if (!xusb) + ERR("xusb allocation failed\n"); + return xusb; + } + } + return NULL; +} + +static const char *path_tail(const char *path) +{ + const char *p; + + assert(path != NULL); + /* Find last '/' */ + p = memrchr(path, '/', strlen(path)); + if (!p) { + ERR("Missing a '/' in %s\n", path); + return NULL; + } + /* Search for a '/' before that */ + p = memrchr(path, '/', p - path); + if (!p) + p = path; /* No more '/' */ + else + p++; /* skip '/' */ + return p; +} + +int xusb_filter_bypath(const struct xusb *xusb, void *data) +{ + const char *p; + const char *path = data; + + DBG("%s\n", path); + assert(path != NULL); + p = path_tail(path); + if (strcmp(xusb->devpath_tail, p) != 0) { + DBG("device path missmatch: '%s' != '%s'\n", + xusb->devpath_tail, p); + return 0; + } + return 1; +} + +struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, + const char *path) +{ + struct xlist_node *xlist; + struct xlist_node *head; + struct xusb *xusb; + + xlist = xusb_find_byproduct(specs, numspecs, + xusb_filter_bypath, (void *)path); + head = xlist_shift(xlist); + if (!head) + return NULL; + if (!xlist_empty(xlist)) { + ERR("Too many matches (extra %zd) to '%s'\n", + xlist_length(xlist), path); + return NULL; + } + xusb = head->data; + xlist_destroy(xlist, NULL); + return xusb; +} + +struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, + int numspecs, xusb_filter_t filterfunc, void *data) +{ + struct xlist_node *xlist; + struct usb_bus *bus; + struct usb_device *dev; + + DBG("specs(%d)\n", numspecs); + xlist = xlist_new(NULL); + if (!xlist) { + ERR("Failed allocation new xlist"); + goto fail_xlist; + } + xusb_init(); + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + struct usb_device_descriptor *dev_desc; + struct xlist_node *item; + int i; + + dev_desc = &dev->descriptor; + assert(dev_desc); + DBG("usb:%s/%s: ID=%04X:%04X\n", + dev->bus->dirname, + dev->filename, + dev_desc->idVendor, + dev_desc->idProduct); + for (i = 0; i < numspecs; i++) { + struct xusb *xusb; + const struct xusb_spec *sp = &specs[i]; + + if (!match_interface(dev, sp)) + continue; + xusb = xusb_new(dev, sp); + if (!xusb) { + ERR("xusb allocation failed\n"); + goto fail_malloc; + } + if (filterfunc && !filterfunc(xusb, data)) { + xusb_destroy(xusb); + continue; + } + item = xlist_new(xusb); + xlist_append_item(xlist, item); + break; + } + } + } + xusb_list_dump(xlist); + return xlist; +fail_malloc: + xlist_destroy(xlist, NULL); +fail_xlist: + return NULL; +} + +struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, + xusb_filter_t filterfunc, void *data) +{ + struct xlist_node *xusb_list; + struct xlist_node *curr; + int num; + struct xusb *xusb = NULL; + + xusb_list = xusb_find_byproduct(specs, numspecs, filterfunc, data); + num = xlist_length(xusb_list); + DBG("total %d devices\n", num); + switch (num) { + case 0: + ERR("No matching device.\n"); + break; + case 1: + curr = xlist_shift(xusb_list); + xusb = curr->data; + xlist_destroy(curr, NULL); + xlist_destroy(xusb_list, NULL); + if (!xusb_claim_interface(xusb)) { + xusb_destroy(xusb); + return NULL; + } + xusb_showinfo(xusb); + break; + default: + ERR("Too many devices (%d). Aborting.\n", num); + break; + } + return xusb; +} + +int xusb_interface(struct xusb *xusb) +{ + return xusb->interface_num; +} + +size_t xusb_packet_size(const struct xusb *xusb) +{ + return xusb->packet_size; +} + +/* + * MP device handling + */ +void xusb_showinfo(const struct xusb *xusb) +{ + struct usb_device_descriptor *dev_desc; + struct usb_device *dev; + + assert(xusb != NULL); + dev = xusb->dev; + dev_desc = &dev->descriptor; + if (verbose <= LOG_INFO) { + INFO("usb:%s/%s: ID=%04X:%04X [%s / %s / %s]\n", + dev->bus->dirname, + dev->filename, + dev_desc->idVendor, + dev_desc->idProduct, + xusb->iManufacturer, + xusb->iProduct, + xusb->iSerialNumber); + } else { + printf("USB Bus/Device: [%s/%s] (%s,%s)\n", + dev->bus->dirname, + dev->filename, + (xusb->is_open) ? "open" : "closed", + (xusb->is_claimed) ? "claimed" : "unused"); + printf("USB Spec name: [%s]\n", xusb->spec->name); + printf("USB iManufacturer: [%s]\n", xusb->iManufacturer); + printf("USB iProduct: [%s]\n", xusb->iProduct); + printf("USB iSerialNumber: [%s]\n", xusb->iSerialNumber); + } +} + +const char *xusb_serial(const struct xusb *xusb) +{ + return xusb->iSerialNumber; +} + +const char *xusb_devpath(const struct xusb *xusb) +{ + return xusb->devpath_tail; +} + +const char *xusb_manufacturer(const struct xusb *xusb) +{ + return xusb->iManufacturer; +} + +const char *xusb_product(const struct xusb *xusb) +{ + return xusb->iProduct; +} + +uint16_t xusb_vendor_id(const struct xusb *xusb) +{ + return xusb->dev->descriptor.idVendor; +} + +uint16_t xusb_product_id(const struct xusb *xusb) +{ + return xusb->dev->descriptor.idProduct; +} + +const struct xusb_spec *xusb_spec(const struct xusb *xusb) +{ + return xusb->spec; +} + +int xusb_close(struct xusb *xusb) +{ + if (xusb) { + if (xusb->handle) { + assert(xusb->spec); + assert(xusb->spec->name); + DBG("Closing interface \"%s\"\n", xusb->spec->name); + if (xusb->is_claimed) { + if (usb_release_interface(xusb->handle, + xusb->spec->my_interface_num) != 0) + ERR("Releasing interface: usb: %s\n", + usb_strerror()); + xusb->is_claimed = 0; + } + if (xusb->is_open) { + if (usb_close(xusb->handle) != 0) { + ERR("Closing device: usb: %s\n", + usb_strerror()); + } + xusb->is_open = 0; + } + xusb->handle = NULL; + } + xusb = NULL; + } + return 0; +} + +int xusb_send(struct xusb *xusb, char *buf, int len, int timeout) +{ + int ret; + int retries = 0; + + dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, len); + if (EP_OUT(xusb) & USB_ENDPOINT_IN) { + ERR("%s called with an input endpoint 0x%x\n", + __func__, EP_OUT(xusb)); + return -EINVAL; + } +retry_write: + ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout); + if (ret < 0) { + /* + * If the device was gone, it may be the + * result of renumeration. Ignore it. + */ + if (ret != -ENODEV) { + ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n", + EP_OUT(xusb), ret, usb_strerror()); + dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", + buf, len); + /*exit(2);*/ + } else { + DBG("bulk_write to endpoint 0x%x got ENODEV\n", + EP_OUT(xusb)); + xusb_close(xusb); + } + return ret; + } + if (!ret) { + ERR("bulk_write to endpoint 0x%x short write[%d]: (%d)\n", + EP_OUT(xusb), retries, ret); + if (retries++ > MAX_RETRIES) + return -EFAULT; + usleep(100); + goto retry_write; + } + if (ret != len) { + ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n", + EP_OUT(xusb), ret, usb_strerror()); + dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len); + return -EFAULT; + } + return ret; +} + +int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout) +{ + int ret; + int retries = 0; + + if (EP_IN(xusb) & USB_ENDPOINT_OUT) { + ERR("%s called with an output endpoint 0x%x\n", + __func__, EP_IN(xusb)); + return -EINVAL; + } +retry_read: + ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout); + if (ret < 0) { + DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n", + EP_IN(xusb), ret, usb_strerror()); + memset(buf, 0, len); + return ret; + } + if (!ret) { + ERR("bulk_read to endpoint 0x%x short read[%d]: (%d)\n", + EP_IN(xusb), retries, ret); + if (retries++ > MAX_RETRIES) + return -EFAULT; + usleep(100); + goto retry_read; + } + dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, ret); + return ret; +} + +int xusb_flushread(struct xusb *xusb) +{ + char tmpbuf[BUFSIZ]; + int ret; + + DBG("starting...\n"); + memset(tmpbuf, 0, BUFSIZ); + ret = xusb_recv(xusb, tmpbuf, BUFSIZ, 1); + if (ret < 0 && ret != -ETIMEDOUT) { + ERR("ret=%d\n", ret); + return ret; + } else if (ret > 0) { + DBG("Got %d bytes:\n", ret); + dump_packet(LOG_DEBUG, DBG_MASK, __func__, tmpbuf, ret); + } + return 0; +} + +/* + * Serialize calls to usb_find_busses()/usb_find_devices() + */ + +static const key_t SEM_KEY = 0x1a2b3c4d; +static int semid = -1; /* Failure */ + +static void xusb_lock_usb() +{ + struct sembuf sembuf; + + while (semid < 0) { + /* Maybe it was already created? */ + semid = semget(SEM_KEY, 1, 0); + if (semid < 0) { + /* No, let's create ourselves */ + semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0644); + if (semid < 0) { + /* Someone else won the race to create it */ + if (errno != ENOENT) + ERR("%s: semget() failed: %s\n", + __func__, strerror(errno)); + /* Retry */ + continue; + } + /* Initialize */ + if (semctl(semid, 0, SETVAL, 1) < 0) + ERR("%s: SETVAL() failed: %s\n", + __func__, strerror(errno)); + } + } + DBG("%d: LOCKING\n", getpid()); + sembuf.sem_num = 0; + sembuf.sem_op = -1; + sembuf.sem_flg = SEM_UNDO; + if (semop(semid, &sembuf, 1) < 0) + ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); + DBG("%d: LOCKED\n", getpid()); +} + +static void xusb_unlock_usb() +{ + struct sembuf sembuf; + + DBG("%d: UNLOCKING\n", getpid()); + sembuf.sem_num = 0; + sembuf.sem_op = 1; + sembuf.sem_flg = SEM_UNDO; + if (semop(semid, &sembuf, 1) < 0) + ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); + DBG("%d: UNLOCKED\n", getpid()); +} + +static int initizalized; + +static void xusb_init() +{ + if (!initizalized) { + xtalk_parse_options(); + if (!xtalk_option_no_lock()) + xusb_lock_usb(); + usb_init(); + usb_find_busses(); + usb_find_devices(); + initizalized = 1; + if (!xtalk_option_no_lock()) + xusb_unlock_usb(); + } +} + +/* XTALK option handling */ +static int use_clear_halt = 1; +static int libusb_no_lock = 0; + +static int xtalk_one_option(const char *option_string) +{ + if (strcmp(option_string, "use-clear-halt") == 0) { + use_clear_halt = 1; + return 0; + } + if (strcmp(option_string, "no-use-clear-halt") == 0) { + use_clear_halt = 0; + return 0; + } + if (strcmp(option_string, "no-lock") == 0) { + libusb_no_lock = 1; + return 0; + } + ERR("Unknown XTALK_OPTIONS content: '%s'\n", option_string); + return -EINVAL; +} + +int xtalk_option_use_clear_halt(void) +{ + return use_clear_halt; +} + +int xtalk_option_no_lock(void) +{ + return libusb_no_lock; +} + +int xtalk_parse_options(void) +{ + char *xtalk_options; + char *saveptr; + char *token; + int ret; + + xtalk_options = getenv("XTALK_OPTIONS"); + if (!xtalk_options) + return 0; + token = strtok_r(xtalk_options, " \t", &saveptr); + while (token) { + ret = xtalk_one_option(token); + if (ret < 0) + return ret; + token = strtok_r(NULL, " \t", &saveptr); + } + return 0; +} + diff --git a/xpp/xtalk/xusb.h b/xpp/xtalk/xusb.h new file mode 100644 index 0000000..01e1861 --- /dev/null +++ b/xpp/xtalk/xusb.h @@ -0,0 +1,102 @@ +#ifndef XUSB_H +#define XUSB_H +/* + * Written by Oron Peled + * Copyright (C) 2008, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * Xorcom usb handling + */ + +#define PACKET_SIZE 512 + +/* + * Specify the wanted interface + */ +struct xusb_spec { + /* Sanity checks so we know it is our device indeed */ + int num_interfaces; + int num_endpoints; + char *name; /* For debug/output purpose */ + /* What we will actually use */ + uint16_t my_vendor_id; + uint16_t my_product_id; + int my_interface_num; + int my_ep_out; + int my_ep_in; +}; + +void xusb_init_spec(struct xusb_spec *xusb_spec, char *name, + uint16_t vendor_id, uint16_t product_id, + int nifaces, int iface, int nep, int ep_out, int ep_in); + +struct xusb; + +/* + * Prototypes + */ +typedef int (*xusb_filter_t)(const struct xusb *xusb, void *data); +struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, + int numspecs, xusb_filter_t filterfunc, void *data); +struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, + const char *path); +struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, + xusb_filter_t filterfunc, void *data); +struct xusb *xusb_find_iface(const char *devpath, int iface_num, + int ep_out, int ep_in, struct xusb_spec *dummy); + +/* + * A convenience filter + */ +int xusb_filter_bypath(const struct xusb *xusb, void *data); + +int xusb_interface(struct xusb *xusb); +int xusb_claim_interface(struct xusb *xusb); +void xusb_destroy(struct xusb *xusb); +int xusb_close(struct xusb *xusb); +size_t xusb_packet_size(const struct xusb *xusb); +void xusb_showinfo(const struct xusb *xusb); +const char *xusb_serial(const struct xusb *xusb); +const char *xusb_manufacturer(const struct xusb *xusb); +const char *xusb_product(const struct xusb *xusb); +uint16_t xusb_vendor_id(const struct xusb *xusb); +uint16_t xusb_product_id(const struct xusb *xusb); +const char *xusb_devpath(const struct xusb *xusb); +const struct xusb_spec *xusb_spec(const struct xusb *xusb); +int xusb_send(struct xusb *xusb, char *buf, int len, int timeout); +int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout); +int xusb_flushread(struct xusb *xusb); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XUSB_H */ diff --git a/zonedata.c b/zonedata.c new file mode 100644 index 0000000..1d314b1 --- /dev/null +++ b/zonedata.c @@ -0,0 +1,1069 @@ +/* + * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 + * + * Working with the "Tormenta ISA" Card + * + * Primary Author: Mark Spencer + * + * This information from ITU E.180 Supplement 2. + * UK information from BT SIN 350 Issue 1.1 + * Helpful reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU Lesser General Public License Version 2.1 as published + * by the Free Software Foundation. See the LICENSE.LGPL file + * included with this program for more details. + * + * In addition, when this program is distributed with Asterisk in + * any form that would qualify as a 'combined work' or as a + * 'derivative work' (but not mere aggregation), you can redistribute + * and/or modify the combination under the terms of the license + * provided with that copy of Asterisk, instead of the license + * terms granted here. + */ + +#include "tonezone.h" + +struct tone_zone builtin_zones[] = +{ + { .zone = 0, + .country = "us", + .description = "United States / North America", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440+480/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 1, + .country = "au", + .description = "Australia", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + + { DAHDI_TONE_DIALTONE, "415+440" }, + { DAHDI_TONE_BUSY, "425/375,0/375" }, + { DAHDI_TONE_RINGTONE, "413+438/400,0/200,413+438/400,0/2000" }, + /* The Australian congestion tone is 425Hz, 375ms On, 375ms Off, with the + * second cadence being half the amplitude of the first; so the first cadence + * is approximately -10dB with the second one being -20dB. Using the update + * ToneZone.c file, this can be accomplished by adding the "@" symbol in front + * of the frequency to reduce amplification, as in the following entry for + * Congestion: + */ + { DAHDI_TONE_CONGESTION, "425/375,0/375,425@/375,0/375" }, + { DAHDI_TONE_CALLWAIT, "425/100,0/200,425/200,0/4400" }, + { DAHDI_TONE_DIALRECALL, "413+428" }, + { DAHDI_TONE_RECORDTONE, "!425/1000,!0/15000,425/360,0/15000" }, + { DAHDI_TONE_INFO, "425/2500,0/500" }, + { DAHDI_TONE_STUTTER, "413+438/100,0/40" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 2, + .country = "fr", + .description = "France", + .ringcadence = { 1500, 3500 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + /* Dialtone can also be 440+330 */ + { DAHDI_TONE_DIALTONE, "440" }, + { DAHDI_TONE_BUSY, "440/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440/1500,0/3500" }, + /* CONGESTION - not specified */ + { DAHDI_TONE_CONGESTION, "440/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 3, + .country = "nl", + .description = "Netherlands", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + /* Most of these 425's can also be 450's */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/500,0/9500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/500,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 4, + .country = "uk", + .description = "United Kingdom", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* From British Telecom SIN350 v1.2 */ + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "400/375,0/375" }, + { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/400,0/350,400/225,0/525" }, + { DAHDI_TONE_CALLWAIT, "400/100,0/4000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, + { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "350+440/750,440/750" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 5, + .country = "fi", + .description = "Finland", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, + { DAHDI_TONE_STUTTER, "425/650,0/25" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 6, + .country = "es", + .description = "Spain", + .ringcadence = { 1500, 3000}, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/200,0/200" }, + { DAHDI_TONE_RINGTONE, "425/1500,0/3000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200,425/200,0/200,425/200,0/600" }, + { DAHDI_TONE_CALLWAIT, "425/175,0/175,425/175,0/3500" }, + { DAHDI_TONE_DIALRECALL, "!425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/500,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 7, + .country = "jp", + .description = "Japan", + .ringcadence = { 1000, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400+15/1000,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "400+16/500,0/8000" }, + { DAHDI_TONE_DIALRECALL, "!400/200,!0/200,!400/200,!0/200,!400/200,!0/200,400" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -7, + .dtmf_low_level = -7, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 8, + .country = "no", + .description = "Norway", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, + { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "470/400,425/400" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 9, + .country = "at", + .description = "Austria", + .ringcadence = { 1000, 5000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "420" }, + { DAHDI_TONE_BUSY, "420/400,0/400" }, + { DAHDI_TONE_RINGTONE, "420/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "420/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, + { DAHDI_TONE_DIALRECALL, "420" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, + { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, + { DAHDI_TONE_STUTTER, "380+420" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 10, + .country = "nz", + .description = "New Zealand", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400/250,0/250,400/250,0/3250" }, + { DAHDI_TONE_DIALRECALL, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, + { DAHDI_TONE_INFO, "400/750,0/100,400/750,0/100,400/750,0/100,400/750,0/400" }, + { DAHDI_TONE_STUTTER, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 11, + .country = "it", + .description = "Italy", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425/200,0/200,425/600,0/1000" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/400,0/100,425/250,0/100,425/150,0/14000" }, + { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "470/400,425/400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 12, + .country = "us-old", + .description = "United States Circa 1950 / North America", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "600*120" }, + { DAHDI_TONE_BUSY, "500*100/500,0/500" }, + { DAHDI_TONE_RINGTONE, "420*40/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "500*100/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 13, + .country = "gr", + .description = "Greece", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425/200,0/300,425/700,0/800" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "425/650,0/25" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 14, + .country = "tw", + .description = "Taiwan", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "440+480/1000,0/2000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "350+440/250,0/250,350+440/250,0/3250" }, + { DAHDI_TONE_DIALRECALL, "300/1500,0/500" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 15, + .country = "cl", + .description = "Chile", + .ringcadence = { 1000, 3000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "400/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "400/250,0/8750" }, + { DAHDI_TONE_DIALRECALL, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/333,!1400/333,!1800/333,0" }, + { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 16, + .country = "se", + .description = "Sweden", + .ringcadence = { 1000, 5000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/750" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/500,425/200,0/9100" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," + "!950/332,!0/24,!1400/332,!0/24,!1800/332,0" }, + /*{ DAHDI_TONE_STUTTER, "425/320,0/20" }, Real swedish standard, not used for now */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 17, + .country = "be", + .description = "Belgium", + .ringcadence = { 1000, 3000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "425/167,0/167" }, + { DAHDI_TONE_CALLWAIT, "1400/175,0/175,1400/175,0/3500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "900/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/1000,0/250" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 18, + .country = "sg", + .description = "Singapore", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* Reference: http://www.ida.gov.sg/idaweb/doc/download/I397/ida_ts_pstn1_i4r2.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/750,0/750" }, + { DAHDI_TONE_RINGTONE, "425*24/400,0/200,425*24/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425*24/300,0/200,425*24/300,0/3200" }, + /* DIALRECALL - not specified - use repeating Holding Tone A,B*/ + { DAHDI_TONE_DIALRECALL, "425*24/500,0/500,425/500,0/2500" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,425" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 19, + .country = "il", + .description = "Israel", + .ringcadence = { 1000, 3000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "414" }, + { DAHDI_TONE_BUSY, "414/500,0/500" }, + { DAHDI_TONE_RINGTONE, "414/1000,0/3000" }, + { DAHDI_TONE_CONGESTION, "414/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "414/100,0/100,414/100,0/100,414/600,0/3000" }, + { DAHDI_TONE_DIALRECALL, "!414/100,!0/100,!414/100,!0/100,!414/100,!0/100,414" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "1000/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,414" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 20, + .country = "br", + .description = "Brazil", + .ringcadence = { 1000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250,425/750,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/50,0/1000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "425/250,0/250" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, + { DAHDI_TONE_STUTTER, "350+440" } }, + .dtmf_high_level = -10, + .dtmf_low_level = -12, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 21, + .country = "hu", + .description = "Hungary", + .ringcadence = { 1250, 3750 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1250,0/3750" }, + { DAHDI_TONE_CONGESTION, "425/300,0/300" }, + { DAHDI_TONE_CALLWAIT, "425/40,0/1960" }, + { DAHDI_TONE_DIALRECALL, "425+450" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + { DAHDI_TONE_STUTTER, "350+375+400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 22, + .country = "lt", + .description = "Lithuania", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/350,0/350" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 23, + .country = "pl", + .description = "Poland", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 24, + .country = "za", + .description = "South Africa", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "400*33" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400*33/400,0/200,400*33/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400*33/250,0/250,400*33/250,0/250,400*33/250,0/250,400*33/250,0/250" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,400*33" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -13, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 25, + .country = "pt", + .description = "Portugal", + .ringcadence = { 1000, 5000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,425/200,425/200,0/5000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "425/1000,0/200" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 26, + .country = "ee", + .description = "Estonia", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/0,0/325,950/325,0/30,1400/1300,0/2600" }, + /* STUTTER not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 27, + .country = "mx", + .description = "Mexico", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/250,0/250" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -8, + .dtmf_low_level = -6, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 28, + .country = "in", + .description = "India", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "400*25" }, + { DAHDI_TONE_BUSY, "400/750,0/750" }, + { DAHDI_TONE_RINGTONE, "400*25/400,0/200,400*25/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "400/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400/200,0/100,400/200,0/7500" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO - not specified */ + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 29, + .country = "de", + .description = "Germany", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/480,0/480" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/240,0/240" }, + { DAHDI_TONE_CALLWAIT, "!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,0" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425+400" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 30, + .country = "ch", + .description = "Switzerland", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/200,425/200,0/4000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425+340/1100,0/1100" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 31, + .country = "dk", + .description = "Denmark", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/200,0/200" }, + { DAHDI_TONE_CALLWAIT, "!425/200,!0/600,!425/200,!0/3000,!425/200,!0/200,!425/200,0" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 32, + .country = "cz", + .description = "Czech Republic", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425/330,0/330,425/660,0/660" }, + { DAHDI_TONE_BUSY, "425/330,0/330" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/165,0/165" }, + { DAHDI_TONE_CALLWAIT, "425/330,0/9000" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, + { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 33, + .country = "cn", + .description = "China", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/350,0/350" }, + { DAHDI_TONE_RINGTONE, "450/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "450/700,0/700" }, + { DAHDI_TONE_CALLWAIT, "450/400,0/4000" }, + { DAHDI_TONE_DIALRECALL, "450" }, + { DAHDI_TONE_RECORDTONE, "950/400,0/10000" }, + { DAHDI_TONE_INFO, "450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "450+425" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 34, + .country = "ar", + .description = "Argentina", + .ringcadence = { 1000, 4500 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/300,0/300" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4500" }, + { DAHDI_TONE_CONGESTION, "425/200,0/300" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/9000" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, + { DAHDI_TONE_INFO, "425/100,0/100" }, + { DAHDI_TONE_STUTTER, "425/450,0/50" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 35, + .country = "my", + .description = "Malaysia", + .ringcadence = { 400, 200, 400, 2000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/400,0/200,425/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/500,0/500" }, + { DAHDI_TONE_CALLWAIT, "425/100,0/4000" }, + { DAHDI_TONE_DIALRECALL, "350+440" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, + { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "450+425" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 36, + .country = "th", + .description = "Thailand", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "400*50" }, + { DAHDI_TONE_BUSY, "400/500,0/500" }, + { DAHDI_TONE_RINGTONE, "400/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "400/300,0/300" }, + { DAHDI_TONE_CALLWAIT, "1000/400,10000/400,1000/400" }, + /* DIALRECALL - not specified - use special dial tone instead. */ + { DAHDI_TONE_DIALRECALL, "400*50/400,0/100,400*50/400,0/100" }, + /* RECORDTONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO - specified as an announcement - use tones instead. */ + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,400" }, + }, + .dtmf_high_level = -11, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 37, + .country = "bg", + .description = "Bulgaria", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "425/1500,0/100" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 38, + .country = "ve", + .description = "Venezuela", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "400+450/300,0/6000" }, + { DAHDI_TONE_DIALRECALL, "425" }, + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1440/330,!1800/330,0/1000" }, + /* STUTTER - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -7, + .dtmf_low_level = -9, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { .zone = 39, + .country = "ph", + .description = "Philippines", + .ringcadence = { 1000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "480+620/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425+480/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, + /* DIAL RECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + /* INFO TONE - not specified */ + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = 40, + .country = "ru", + .description = "Russian Federation", + .ringcadence = { 1000, 4000 }, + .tones = { + /* References: + http://www.minsvyaz.ru/site.shtml?id=1806 + http://www.aboutphone.info/lib/gost/45-223-2001.html */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/350,0/350" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/175,0/175" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/5000" }, + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "950/330,1440/330,1800/330,0/1000" }, + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 41, + .country = "tr", + .description = "Turkey", + .ringcadence = { 2000, 4000 }, + .tones = { + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/500,0/500" }, + { DAHDI_TONE_RINGTONE, "450/2000,0/4000" }, + { DAHDI_TONE_CONGESTION, "!450/200,!0/200,!450/200,!0/200,!450/200,!0/200,450/600,0/200" }, + { DAHDI_TONE_CALLWAIT, "450/200,0/600,450/200,0/800" }, + /* This should actually be 950+1400+1800, but we only support 2 tones at a time */ + { DAHDI_TONE_INFO, "!950+1400/300,!0/1000,!950+1400/300,!0/1000,!950+1400/1000,0" }, + { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 42, + .country = "pa", + .description = "Panama", + .ringcadence = { 2000, 4000 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/320,0/320" }, + { DAHDI_TONE_RINGTONE, "425/1200,0/4650" }, + { DAHDI_TONE_CONGESTION, "425/320,0/320" }, + { DAHDI_TONE_CALLWAIT, "425/180,0/180,425/180" }, + /* RECALL DIAL TONE - not specified */ + { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { + .zone = 43, + .country = "mo", + .description = "Macao,China", + .ringcadence = { 1000, 4000 }, + .tones = { + /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "425" }, + { DAHDI_TONE_BUSY, "425/500,0/500" }, + { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, + { DAHDI_TONE_CONGESTION, "425/250,0/250" }, + { DAHDI_TONE_CALLWAIT, "425/200,0/600" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, + { DAHDI_TONE_INFO, "950/333,1400/333,1800/333,0/1000" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { + .zone = 44, + .country = "cr", + .description = "Costa Rica", + .ringcadence = { 1203, 4797 }, + .tones = { + /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf [^] */ + { DAHDI_TONE_DIALTONE, "450" }, + { DAHDI_TONE_BUSY, "450/330,0/330" }, + { DAHDI_TONE_RINGTONE, "450/1203,0/4900" }, + { DAHDI_TONE_CONGESTION, "450/330,0/330" }, + { DAHDI_TONE_CALLWAIT, "450/150,0/150,450/150,450/8000" }, + /* RECALL DIAL TONE - not specified */ + { DAHDI_TONE_DIALRECALL, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + /* RECORD TONE - not specified */ + { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, + { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, + /* STUTTER TONE - not specified */ + { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, + }, + .dtmf_high_level = -9, + .dtmf_low_level = -11, + .mfr1_level = -7, + .mfr2_level = -8, + }, + { + .zone = 45, + .country = "ae", + .description = "United Arab Emirates", + .ringcadence = { 1500, 4000 }, + .tones = { + /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ + { DAHDI_TONE_DIALTONE, "350+440" }, + { DAHDI_TONE_BUSY, "400/375,0/375" }, + { DAHDI_TONE_RINGTONE, "400+425/400,0/200,400+425/400,0/2000" }, + { DAHDI_TONE_CONGESTION, "425/400,0/350,425/225,0/525" }, + { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, + /* RECORD TONE */ + { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, + { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, + /* STUTTER TONE */ + { DAHDI_TONE_STUTTER, "380+420" }, + /* DIALRECALL - not specified */ + { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, + }, + .dtmf_high_level = -10, + .dtmf_low_level = -10, + .mfr1_level = -10, + .mfr2_level = -8, + }, + { .zone = -1 } +};