[Pkg-voip-commits] [dahdi-tools] 02/285: Import DAHDI-Tools r9159
tzafrir at debian.org
tzafrir at debian.org
Thu Jul 7 19:18:17 UTC 2016
This is an automated email from the git hooks/post-receive script.
tzafrir pushed a commit to branch master
in repository dahdi-tools.
commit 466357f5c28253c4f72799431f2033a3e82dea6b
Author: Asterisk Development Team <asteriskteam at digium.com>
Date: Wed Aug 18 13:49:24 2010 +0000
Import DAHDI-Tools r9159
This revision of DAHDI-Tools is the base revision for the switch to
git.
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/tools/trunk@9159
---
LICENSE | 341 ++
LICENSE.LGPL | 504 ++
Makefile | 420 ++
README | 233 +
UPGRADE.txt | 103 +
acinclude.m4 | 1113 ++++
autoconfig.h.in | 102 +
bittest.h | 17 +
blacklist.sample | 13 +
bootstrap.sh | 48 +
build_tools/dahdi_svn_tarball | 90 +
build_tools/dump_sys_state | 147 +
build_tools/make_firmware_object.in | 11 +
build_tools/make_tree | 7 +
build_tools/make_version | 56 +
build_tools/make_version_c | 10 +
build_tools/menuselect-deps.in | 2 +
build_tools/test_kernel_git | 80 +
build_tools/uninstall-modules | 41 +
config.guess | 1526 ++++++
config.sub | 1658 ++++++
configure | 6991 ++++++++++++++++++++++++
configure.ac | 215 +
dahdi.init | 333 ++
dahdi.xml | 26 +
dahdi_cfg.c | 1662 ++++++
dahdi_diag.c | 55 +
dahdi_maint.c | 236 +
dahdi_monitor.c | 783 +++
dahdi_scan.c | 205 +
dahdi_speed.c | 65 +
dahdi_test.c | 164 +
dahdi_tool.c | 541 ++
dahdi_tools_version.h | 21 +
doc/dahdi_cfg.8 | 70 +
doc/dahdi_diag.8 | 52 +
doc/dahdi_monitor.8 | 43 +
doc/dahdi_scan.8 | 101 +
doc/dahdi_test.8 | 49 +
doc/dahdi_tool.8 | 25 +
doc/fxotune.8 | 207 +
doc/fxstest.8 | 60 +
doc/patgen.8 | 44 +
doc/pattest.8 | 49 +
fxotune.c | 1272 +++++
fxotune.h | 119 +
fxstest.c | 337 ++
hdlcgen.c | 135 +
hdlcstress.c | 233 +
hdlctest.c | 302 +
hdlcverify.c | 136 +
ifup-hdlc | 39 +
init.conf.sample | 19 +
install-sh | 323 ++
makeopts.in | 47 +
modprobe.conf.sample | 4 +
modules.sample | 48 +
patgen.c | 164 +
patlooptest.c | 295 +
pattest.c | 170 +
ppp/Makefile | 29 +
ppp/dahdi.c | 293 +
sethdlc.c | 704 +++
system.conf.sample | 330 ++
timertest.c | 78 +
tonezone.c | 518 ++
tonezone.h | 90 +
wavformat.h | 48 +
xpp/Makefile | 140 +
xpp/README.Astribank | 1656 ++++++
xpp/astribank_allow.8 | 70 +
xpp/astribank_allow.c | 384 ++
xpp/astribank_hexload.8 | 66 +
xpp/astribank_hexload.c | 229 +
xpp/astribank_hook | 114 +
xpp/astribank_is_starting.8 | 100 +
xpp/astribank_is_starting.c | 190 +
xpp/astribank_tool.8 | 86 +
xpp/astribank_tool.c | 274 +
xpp/astribank_upgrade | 150 +
xpp/astribank_usb.c | 555 ++
xpp/astribank_usb.h | 103 +
xpp/dahdi.cgi | 265 +
xpp/dahdi_drivers | 23 +
xpp/dahdi_genconf | 196 +
xpp/dahdi_hardware | 196 +
xpp/dahdi_registration | 166 +
xpp/debug.c | 53 +
xpp/debug.h | 46 +
xpp/fpga_load.8 | 86 +
xpp/fpga_load.c | 1052 ++++
xpp/genconf_parameters | 169 +
xpp/hexfile.c | 568 ++
xpp/hexfile.h | 87 +
xpp/lsdahdi | 110 +
xpp/mpp.h | 344 ++
xpp/mpp_funcs.c | 1109 ++++
xpp/mpp_funcs.h | 80 +
xpp/perl_modules/Dahdi.pm | 79 +
xpp/perl_modules/Dahdi/Chans.pm | 264 +
xpp/perl_modules/Dahdi/Config/Gen.pm | 275 +
xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm | 299 +
xpp/perl_modules/Dahdi/Config/Gen/Modules.pm | 62 +
xpp/perl_modules/Dahdi/Config/Gen/System.pm | 278 +
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 | 245 +
xpp/perl_modules/Dahdi/Hardware/USB.pm | 206 +
xpp/perl_modules/Dahdi/Span.pm | 364 ++
xpp/perl_modules/Dahdi/Utils.pm | 66 +
xpp/perl_modules/Dahdi/Xpp.pm | 343 ++
xpp/perl_modules/Dahdi/Xpp/Line.pm | 89 +
xpp/perl_modules/Dahdi/Xpp/Mpp.pm | 222 +
xpp/perl_modules/Dahdi/Xpp/Xbus.pm | 213 +
xpp/perl_modules/Dahdi/Xpp/Xpd.pm | 387 ++
xpp/pic_loader.c | 276 +
xpp/pic_loader.h | 46 +
xpp/test_parse.c | 57 +
xpp/twinstar | 267 +
xpp/twinstar_hook | 86 +
xpp/twinstar_setup | 155 +
xpp/waitfor_xpds | 93 +
xpp/xpp_blink | 168 +
xpp/xpp_fxloader | 364 ++
xpp/xpp_fxloader.usermap | 10 +
xpp/xpp_modprobe | 10 +
xpp/xpp_sync | 226 +
xpp/xpp_timing | 6 +
zonedata.c | 983 ++++
132 files changed, 39890 insertions(+)
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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 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.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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..835e410
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,420 @@
+#
+# Makefile for DAHDI tools
+#
+# Copyright (C) 2001-2010 Digium, Inc.
+#
+#
+
+# If the file .dahdi.makeopts is present in your home directory, you can
+# include all of your favorite menuselect options so that every time you download
+# a new version of Asterisk, you don't have to run menuselect to set them.
+# The file /etc/dahdi.makeopts will also be included but can be overridden
+# by the file in your home directory.
+
+GLOBAL_MAKEOPTS=$(wildcard /etc/dahdi.makeopts)
+USER_MAKEOPTS=$(wildcard ~/.dahdi.makeopts)
+
+ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),)
+ ifneq ($(wildcard menuselect.makeopts),)
+ include menuselect.makeopts
+ endif
+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
+
+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
+
+ifneq ($(wildcard .version),)
+ TOOLSVERSION:=$(shell cat .version)
+else
+ifneq ($(wildcard .svn),)
+ TOOLSVERSION=$(shell build_tools/make_version . dahdi/tools)
+endif
+endif
+
+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
+CONFIG_DIR:=$(sysconfdir)/dahdi
+CONFIG_FILE:=$(CONFIG_DIR)/system.conf
+
+# 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 fxstest sethdlc dahdi_cfg dahdi_diag dahdi_monitor dahdi_speed dahdi_test dahdi_scan dahdi_tool dahdi_maint
+BINS:=$(filter-out $(MENUSELECT_UTILS),$(BINS))
+MAN_PAGES:=$(wildcard $(BINS:%=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: menuselect.makeopts
+ @$(MAKE) _all
+
+_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
+
+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
+ $(ASCIIDOC) -n -a toc -a toclevels=3 $<
+
+README.Astribank.html: xpp/README.Astribank
+ $(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $<
+
+# on Debian: this requires the full groof, 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-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
+
+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
+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
+
+clean:
+ -@$(MAKE) -C menuselect 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
+
+distclean: dist-clean
+
+dist-clean: clean
+ @$(MAKE) -C menuselect dist-clean
+ rm -f makeopts menuselect.makeopts menuselect-tree build_tools/menuselect-deps
+ 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
+
+menuselect.makeopts: menuselect/menuselect menuselect-tree makeopts
+ menuselect/menuselect --check-deps $@ $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
+
+menuconfig: menuselect
+
+cmenuconfig: cmenuselect
+
+gmenuconfig: gmenuselect
+
+nmenuconfig: nmenuselect
+
+menuselect: menuselect/cmenuselect menuselect/nmenuselect menuselect/gmenuselect
+ @if [ -x menuselect/nmenuselect ]; then \
+ $(MAKE) nmenuselect; \
+ elif [ -x menuselect/cmenuselect ]; then \
+ $(MAKE) cmenuselect; \
+ elif [ -x menuselect/gmenuselect ]; then \
+ $(MAKE) gmenuselect; \
+ else \
+ echo "No menuselect user interface found. Install ncurses,"; \
+ echo "newt or GTK libraries to build one and re-rerun"; \
+ echo "'make menuselect'."; \
+ fi
+
+cmenuselect: menuselect/cmenuselect menuselect-tree
+ - at menuselect/cmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
+
+gmenuselect: menuselect/gmenuselect menuselect-tree
+ - at menuselect/gmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
+
+nmenuselect: menuselect/nmenuselect menuselect-tree
+ - at menuselect/nmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
+
+# options for make in menuselect/
+MAKE_MENUSELECT=CC="$(HOST_CC)" CXX="$(CXX)" LD="" AR="" RANLIB="" CFLAGS="" $(MAKE) -C menuselect CONFIGURE_SILENT="--silent"
+
+menuselect/menuselect: menuselect/makeopts
+ +$(MAKE_MENUSELECT) menuselect
+
+menuselect/cmenuselect: menuselect/makeopts
+ +$(MAKE_MENUSELECT) cmenuselect
+
+menuselect/gmenuselect: menuselect/makeopts
+ +$(MAKE_MENUSELECT) gmenuselect
+
+menuselect/nmenuselect: menuselect/makeopts
+ +$(MAKE_MENUSELECT) nmenuselect
+
+menuselect/makeopts: makeopts
+ +$(MAKE_MENUSELECT) makeopts
+
+menuselect-tree: dahdi.xml
+ @echo "Generating input for menuselect ..."
+ @build_tools/make_tree > $@
+
+.PHONY: menuselect distclean dist-clean clean all _all install programs tests devel data config update install-programs install-libs install-utils-subdirs utils-subdirs prereq
+
+FORCE:
+
+ifneq ($(wildcard .*.d),)
+ include .*.d
+endif
diff --git a/README b/README
new file mode 100644
index 0000000..a298a6b
--- /dev/null
+++ b/README
@@ -0,0 +1,233 @@
+DAHDI Telephony Interface Driver
+=================================
+Asterisk Development Team <asteriskteam at digium.com>
+$Revision$, $Date$
+
+DAHDI stands for Digium Asterisk Hardware Device Interface. This
+package contains the userspace 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
+# optional step: select custom configuration:
+#make menuselect
+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 userspace programs. partial
+ targets of it:
+ * make 'utilname': builds 'utilname' alone (e.g: `make dahdi_diag`)
+ * make utils: Build libtonezone.
+ * make libs: Build libtonezone.
+. Install targets:
+ - make install: Installs user space tools into /usr/sbin/ (TODO - list
+ partial targets)
+ - make config: should be run once to configure
+
+
+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 th 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 various several tests and based on them generates
+some files ( build_tools/menuselect-deps and 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:
+
+ ./ocnfig.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.
+
+/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[]
+
+
+Tonezones
+~~~~~~~~~
+The file zonedata.c contains the information about the tone zones used
+in libtonezone (and hence also in ztcfg). 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
+docuemntation. 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 modprobed 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 plugin 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 .
+
+
+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..f26e09d
--- /dev/null
+++ b/UPGRADE.txt
@@ -0,0 +1,103 @@
+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 unless the interface cards in use
+have echo canceler modules available and enabled. There is *no*
+default software echo canceler with DAHDI. 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 <ptlib.h>])
+ 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 <ptlib.h>])
+ 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 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AST_PROG_LD_GNU
+])# AST_PROG_LD
+
+
+# AST_PROG_LD_GNU
+# --------------
+AC_DEFUN([AST_PROG_LD_GNU],
+[AC_REQUIRE([AST_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AST_PROG_LD_GNU
+
+# AST_PROG_EGREP
+# -------------
+m4_ifndef([AST_PROG_EGREP], [AC_DEFUN([AST_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+ [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])]) # 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 <stevenj at alum.mit.edu>
+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.h>],
+ [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 <pthread.h>], [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/autoconfig.h.in b/autoconfig.h.in
new file mode 100644
index 0000000..d95e19c
--- /dev/null
+++ b/autoconfig.h.in
@@ -0,0 +1,102 @@
+/* autoconfig.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if your system has the DAHDI headers. */
+#undef HAVE_DAHDI
+
+/* Define DAHDI headers version */
+#undef HAVE_DAHDI_VERSION
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <linux/soundcard.h> header file. */
+#undef HAVE_LINUX_SOUNDCARD_H
+
+/* Define to 1 if you have the <memory.h> 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 <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+#undef HAVE_SYS_SOUNDCARD_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> 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 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..3e918a2
--- /dev/null
+++ b/blacklist.sample
@@ -0,0 +1,13 @@
+# 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 wct1xxp
+blacklist wcte11xp
+blacklist wctdm24xxp
+blacklist wcfxo
+blacklist wctdm
+blacklist wctc4xxp
+blacklist wcb4xxp
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/dump_sys_state b/build_tools/dump_sys_state
new file mode 100755
index 0000000..97456d5
--- /dev/null
+++ b/build_tools/dump_sys_state
@@ -0,0 +1,147 @@
+#!/bin/sh
+
+# dump_sys_state: dump some /sys and /proc files to a directory.
+# $Id$
+#
+# Written by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+# 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
+
+name=dahdi_sys_state_dump
+
+usage() {
+ echo "$0: dump system data for Dahdi-Perl"
+ echo "Usage: $0 [<name>]]"
+ echo ""
+ echo "<name>: name of directory/tarball to create. Default: $name"
+}
+
+output_tar() {
+ gzip -9 >$name.tar.gz
+}
+
+output_cpio() {
+ gzip -9 >$name.cpio.gz
+}
+
+output_dir() {
+ rm -rf $name
+ mkdir -p $name
+ cd $name
+ #tar xf -
+ cpio -id
+}
+
+# Give usage message on expected texts
+case $1 in
+ help | -* ) usage; exit 1;;
+esac
+
+if [ "$1" != '' ]; then
+ name="$1"
+fi
+
+# funky permissions on procfs. Sadly rm -f does not kill them.
+if [ -d "$name" ]; then
+ chmod -R u+w "$name"
+fi
+rm -rf "$name"
+mkdir -p "$name"
+
+# delete a (potentially empty) list of files
+rm_files() {
+ xargs rm -f rm_files_non_existing_file
+}
+
+if [ -r /proc/bus/usb/devices ]; then
+ mkdir -p "$name/proc/bus/usb"
+ cp -a /proc/bus/usb/devices "$name/proc/bus/usb/"
+fi
+
+if [ -d /proc/dahdi ]; then
+ mkdir -p "$name/proc/dahdi"
+ if find /proc/dahdi -type f >/dev/null; then
+ cp -a /proc/dahdi/* "$name/proc/dahdi/"
+ fi
+fi
+
+if [ -d /proc/xpp ]; then
+ mkdir -p "$name/proc/xpp"
+ if find /proc/xpp -type f >/dev/null; then
+ cp -a /proc/xpp/* "$name/proc/xpp/"
+ find "$name/proc/xpp" -type f -name command | rm_files
+ fi
+fi
+
+# FIXME: the following grab tons of files from sysfs. Any way to do with
+# less information?
+pci_dev_pat='/sys/devices/pci*'
+mkdir -p "$name/sys/devices"
+cp -a $pci_dev_pat "$name/sys/devices/" 2>/dev/null
+
+for bus in astribanks xpds pci pci_express usb; do
+ if [ -d /sys/bus/$bus ]; then
+ mkdir -p "$name/sys/bus/"
+ cp -a /sys/bus/$bus "$name/sys/bus/" 2>/dev/null
+ fi
+done
+
+# Remove PCI devices of irelevan classes:
+irrelevant_devs() {
+ grep . "$name"/$pci_dev_pat/0*/class "$name"/$pci_dev_pat/0*/0*/class \
+ | perl -n -e '# Perl provides commented regexes:
+ next unless m{/class:( # The following is a list of device classes
+ # that can be safely removed:
+ 0x060000 | # Host bridge
+ 0x030000 | # VGA compatible controller
+ 0x038000 | # Display controller
+ 0x040300 | # Audio device
+ 0x060401 | # PCI bridge
+ 0x060100 | # ISA bridge
+ 0x01018a | # IDE interface
+ 0x01018f | # IDE interface
+ 0x0c0500 | # SMBus
+ 0x060700 | # CardBus bridge
+ 0x0c0010 | # FireWire (IEEE 1394)
+ # The following are not to be removed:
+ #0x0c0300 | # USB Controller (UHCI?)
+ #0x060400 | # PCI bridge
+ #0x0c0320 | # USB Controller (EHCI?)
+ #0x020000 | # Ethernet controller
+ #0x0c0010 | # Network controller: (Wifi?)
+ )$}x;
+ # Leave out just the name of the node:
+ s{/[^/]*$}{};
+ print;
+ print "\n"
+ '
+}
+
+# FIXME: deleting those seems to remove common 'vendor' directories
+# and mess things up. Skip it for now.
+#rm -rf `irrelevant_devs`
+
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..01af666
--- /dev/null
+++ b/build_tools/make_tree
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+echo "<?xml version=\"1.0\"?>"
+echo
+echo "<menu name=\"DAHDI Tools Selection\">"
+cat dahdi.xml
+echo "</menu>"
diff --git a/build_tools/make_version b/build_tools/make_version
new file mode 100755
index 0000000..e6caaa2
--- /dev/null
+++ b/build_tools/make_version
@@ -0,0 +1,56 @@
+#!/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 .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}
+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..d8ff845
--- /dev/null
+++ b/build_tools/menuselect-deps.in
@@ -0,0 +1,2 @@
+LIBNEWT=@PBX_NEWT@
+HDLC=@PBX_HDLC@
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 <kerneldir> Pull a kernel version into <kerneldir>"
+ echo " $me update Update (pull) the kernel tree."
+ echo " $me setver <kernel_ver> 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 <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>. 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 <config-patches at gnu.org>."
+
+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 at 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 at 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 <stdio.h> /* 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 <sys/systemcfg.h>
+
+ 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 <stdlib.h>
+ #include <unistd.h>
+
+ 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 <unistd.h>
+ 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 <features.h>
+ #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' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/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 <Richard.M.Bartel at ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes at openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf at swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green at stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green at 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 <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#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 <sys/param.h>
+ 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 <sys/param.h>
+# 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 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> 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 <config-patches at gnu.org>. 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 <config-patches at gnu.org>."
+
+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..883e545
--- /dev/null
+++ b/configure
@@ -0,0 +1,6991 @@
+#! /bin/sh
+# From configure.ac Revision: 8266 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.61.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 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=:
+ # Zsh 3.x and 4.x performs 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
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+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.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+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
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+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
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell autoconf at gnu.org about your system,
+ echo including any error possibly output before this
+ echo message
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. 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" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+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
+fi
+echo >conf$$.file
+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 -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# 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 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="dahdi"
+ac_unique_file="dahdi_cfg.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+CPP
+GREP
+EGREP
+LD
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+LN_S
+GNU_MAKE
+BDFNAME
+BDFARCH
+HOSTCC
+LN
+WGET
+FETCH
+DOWNLOAD
+DAHDI_DEVMODE
+DAHDI_DECLARATION_AFTER_STATEMENT
+DAHDI_LIB
+DAHDI_INCLUDE
+DAHDI_DIR
+PBX_DAHDI
+NEWT_LIB
+NEWT_INCLUDE
+NEWT_DIR
+PBX_NEWT
+USB_LIB
+USB_INCLUDE
+USB_DIR
+PBX_USB
+PBX_DAHDI23
+PBX_HDLC
+USE_SELINUX
+ASCIIDOC
+PPPD_VERSION
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+ 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
+# 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}'
+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=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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=no ;;
+
+ -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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+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
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { echo "$as_me: error: Working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# 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 -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ 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 this package 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/PACKAGE]
+ --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
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --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<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ 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.
+
+_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" || continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`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
+ 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
+configure
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 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
+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 $as_me, which was
+generated by GNU Autoconf 2.61. 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=.
+ 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: 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
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_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
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ 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'; { (exit 1); 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
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+ set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+ set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+ set x "$ac_default_prefix/share/config.site" \
+ "$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $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,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# 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
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+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
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort. b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions. Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; 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 | *.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
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; 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 ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+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
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* 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"
+ 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+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)
+ { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+ xno)
+ { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+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
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ 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"
+ { test -f "$ac_path_GREP" && $as_test_x "$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
+ echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ 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
+ ac_count=`expr $ac_count + 1`
+ 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
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+ { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ 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"
+ { test -f "$ac_path_EGREP" && $as_test_x "$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
+ echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ 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
+ ac_count=`expr $ac_count + 1`
+ 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
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+ { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f 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 >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#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
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+for ac_header in sys/soundcard.h linux/soundcard.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LD="${ac_tool_prefix}ld"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_LD="ld"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $ac_ct_LD" >&5
+echo "${ECHO_T}$ac_ct_LD" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_LD" = x; then
+ LD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+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
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+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
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* 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"
+ 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+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)
+ { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+ xno)
+ { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+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
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# 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.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+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
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking for GNU make" >&5
+echo $ECHO_N "checking for GNU make... $ECHO_C" >&6; }
+if test "${ac_cv_GNU_MAKE+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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
+{ echo "$as_me:$LINENO: result: $ac_cv_GNU_MAKE" >&5
+echo "${ECHO_T}$ac_cv_GNU_MAKE" >&6; } ;
+if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then
+ { { echo "$as_me:$LINENO: error: *** Please install GNU make. It is required to build Asterisk!" >&5
+echo "$as_me: error: *** Please install GNU make. It is required to build Asterisk!" >&2;}
+ { (exit 1); exit 1; }; }
+ exit 1
+fi
+GNU_MAKE=$ac_cv_GNU_MAKE
+
+
+
+test_obj=conftest.o
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; 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/"`
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+# 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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $GREP" >&5
+echo "${ECHO_T}$GREP" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "sh", so it can be a program name with args.
+set dummy sh; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_SHELL+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_SHELL="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $SHELL" >&5
+echo "${ECHO_T}$SHELL" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "ln", so it can be a program name with args.
+set dummy ln; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_LN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $LN" >&5
+echo "${ECHO_T}$LN" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+# Extract the first word of "wget", so it can be a program name with args.
+set dummy wget; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_WGET+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $WGET" >&5
+echo "${ECHO_T}$WGET" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_FETCH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_FETCH="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$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
+ { echo "$as_me:$LINENO: result: $FETCH" >&5
+echo "${ECHO_T}$FETCH" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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 ;;
+ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-dev-mode" >&5
+echo "$as_me: error: bad value ${enableval} for --enable-dev-mode" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+fi
+
+
+
+{ echo "$as_me:$LINENO: checking for -Wdeclaration-after-statement support" >&5
+echo $ECHO_N "checking for -Wdeclaration-after-statement support... $ECHO_C" >&6; }
+if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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
+ { echo "$as_me:$LINENO: checking for DAHDI_CODE in dahdi/user.h" >&5
+echo $ECHO_N "checking for DAHDI_CODE in dahdi/user.h... $ECHO_C" >&6; }
+ saved_cppflags="${CPPFLAGS}"
+ if test "x${DAHDI_DIR}" != "x"; then
+ DAHDI_INCLUDE="-I${DAHDI_DIR}/include"
+ fi
+ CPPFLAGS="${CPPFLAGS} ${DAHDI_INCLUDE}"
+
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <dahdi/user.h>
+int
+main ()
+{
+#if defined(DAHDI_CODE)
+ int foo = 0;
+ #else
+ int foo = bar;
+ #endif
+ 0
+
+ ;
+ return 0;
+}
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ PBX_DAHDI=1
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DAHDI 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DAHDI_VERSION
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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
+ { echo "$as_me:$LINENO: checking for DAHDI_CONFIG_NTTE in dahdi/user.h" >&5
+echo $ECHO_N "checking for DAHDI_CONFIG_NTTE in dahdi/user.h... $ECHO_C" >&6; }
+ saved_cppflags="${CPPFLAGS}"
+ if test "x${DAHDI23_DIR}" != "x"; then
+ DAHDI23_INCLUDE="-I${DAHDI23_DIR}/include"
+ fi
+ CPPFLAGS="${CPPFLAGS} ${DAHDI23_INCLUDE}"
+
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <dahdi/user.h>
+int
+main ()
+{
+#if defined(DAHDI_CONFIG_NTTE)
+ int foo = 0;
+ #else
+ int foo = bar;
+ #endif
+ 0
+
+ ;
+ return 0;
+}
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ PBX_DAHDI23=1
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DAHDI23 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DAHDI23_VERSION
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}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=`echo "ac_cv_lib_newt_${pbxfuncname}" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for ${pbxfuncname} in -lnewt" >&5
+echo $ECHO_N "checking for ${pbxfuncname} in -lnewt... $ECHO_C" >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnewt ${pbxlibdir} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any 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
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ eval "$as_ac_Lib=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Lib=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+ac_res=`eval echo '${'$as_ac_Lib'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Lib'}'` = 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} "
+ if test "${ac_cv_header_newt_h+set}" = set; then
+ { echo "$as_me:$LINENO: checking for newt.h" >&5
+echo $ECHO_N "checking for newt.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_newt_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_newt_h" >&5
+echo "${ECHO_T}$ac_cv_header_newt_h" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking newt.h usability" >&5
+echo $ECHO_N "checking newt.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <newt.h>
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking newt.h presence" >&5
+echo $ECHO_N "checking newt.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <newt.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: newt.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: newt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: newt.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: newt.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: newt.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: newt.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: newt.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: newt.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: newt.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: newt.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: newt.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for newt.h" >&5
+echo $ECHO_N "checking for newt.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_newt_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_newt_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_newt_h" >&5
+echo "${ECHO_T}$ac_cv_header_newt_h" >&6; }
+
+fi
+if test $ac_cv_header_newt_h = yes; 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=`echo "ac_cv_lib_usb_${pbxfuncname}" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for ${pbxfuncname} in -lusb" >&5
+echo $ECHO_N "checking for ${pbxfuncname} in -lusb... $ECHO_C" >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lusb ${pbxlibdir} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any 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
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ eval "$as_ac_Lib=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Lib=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+ac_res=`eval echo '${'$as_ac_Lib'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Lib'}'` = 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} "
+ if test "${ac_cv_header_usb_h+set}" = set; then
+ { echo "$as_me:$LINENO: checking for usb.h" >&5
+echo $ECHO_N "checking for usb.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_usb_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_usb_h" >&5
+echo "${ECHO_T}$ac_cv_header_usb_h" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking usb.h usability" >&5
+echo $ECHO_N "checking usb.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <usb.h>
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking usb.h presence" >&5
+echo $ECHO_N "checking usb.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <usb.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: usb.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: usb.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: usb.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: usb.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: usb.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: usb.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: usb.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: usb.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: usb.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: usb.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: usb.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for usb.h" >&5
+echo $ECHO_N "checking for usb.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_usb_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_usb_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_usb_h" >&5
+echo "${ECHO_T}$ac_cv_header_usb_h" >&6; }
+
+fi
+if test $ac_cv_header_usb_h = yes; 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
+
+
+PBX_HDLC=0
+{ echo "$as_me:$LINENO: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h" >&5
+echo $ECHO_N "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/hdlc.h>
+int
+main ()
+{
+#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4
+ int foo = 0;
+ #else
+ int foo = bar;
+ #endif
+ 0
+ ;
+ return 0;
+}
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ PBX_HDLC=1
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test $PBX_HDLC = 0; then
+ { echo "$as_me:$LINENO: checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h" >&5
+echo $ECHO_N "checking for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+ #include <sys/socket.h>
+ #include <linux/if.h>
+int
+main ()
+{
+#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4
+ int foo = 0;
+ #else
+ int foo = bar;
+ #endif
+ 0
+ ;
+ return 0;
+}
+_ACEOF
+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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ PBX_HDLC=1
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "x${PBX_HDLC}" != "x1"; then
+ { echo "$as_me:$LINENO: GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc." >&5
+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
+ { { echo "$as_me:$LINENO: error: failed to find pppd/patchlevel.h: no ppp support." >&5
+echo "$as_me: error: failed to find pppd/patchlevel.h: no ppp support." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ;;
+esac
+
+if test "x${PBX_DAHDI}" != "x1"; then
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ { echo "$as_me:$LINENO: *** Building this package requires DAHDI support. *** " >&5
+echo "$as_me: *** Building this package requires DAHDI support. *** " >&6;}
+ { echo "$as_me:$LINENO: *** Please install the dahdi-linux package. ***" >&5
+echo "$as_me: *** Please install the dahdi-linux package. ***" >&6;}
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ exit 1
+fi
+
+if test "x${PBX_DAHDI23}" != "x1"; then
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ { echo "$as_me:$LINENO: *** Building this package requires DAHDI support (>= 2.3) *** " >&5
+echo "$as_me: *** Building this package requires DAHDI support (>= 2.3) *** " >&6;}
+ { echo "$as_me:$LINENO: *** Please install a recent dahdi-linux package. ***" >&5
+echo "$as_me: *** Please install a recent dahdi-linux package. ***" >&6;}
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ exit 1
+fi
+
+
+
+ac_config_files="$ac_config_files build_tools/menuselect-deps 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_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
+ test "x$cache_file" != "x/dev/null" &&
+ { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+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=
+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=`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.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be 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=:
+ # Zsh 3.x and 4.x performs 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
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+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.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+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
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+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
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. 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" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+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
+fi
+echo >conf$$.file
+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 -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# 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
+
+# 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 $as_me, which was
+generated by GNU Autoconf 2.61. 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
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf at gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.61,
+ with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 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'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ 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 )
+ echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ 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
+if \$ac_cs_recheck; then
+ echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ CONFIG_SHELL=$SHELL
+ export CONFIG_SHELL
+ exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# 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" ;;
+ "build_tools/menuselect-deps") CONFIG_FILES="$CONFIG_FILES build_tools/menuselect-deps" ;;
+ "makeopts") CONFIG_FILES="$CONFIG_FILES makeopts" ;;
+
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_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=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+LD!$LD$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+LN_S!$LN_S$ac_delim
+GNU_MAKE!$GNU_MAKE$ac_delim
+BDFNAME!$BDFNAME$ac_delim
+BDFARCH!$BDFARCH$ac_delim
+HOSTCC!$HOSTCC$ac_delim
+LN!$LN$ac_delim
+WGET!$WGET$ac_delim
+FETCH!$FETCH$ac_delim
+DOWNLOAD!$DOWNLOAD$ac_delim
+DAHDI_DEVMODE!$DAHDI_DEVMODE$ac_delim
+DAHDI_DECLARATION_AFTER_STATEMENT!$DAHDI_DECLARATION_AFTER_STATEMENT$ac_delim
+DAHDI_LIB!$DAHDI_LIB$ac_delim
+DAHDI_INCLUDE!$DAHDI_INCLUDE$ac_delim
+DAHDI_DIR!$DAHDI_DIR$ac_delim
+PBX_DAHDI!$PBX_DAHDI$ac_delim
+NEWT_LIB!$NEWT_LIB$ac_delim
+NEWT_INCLUDE!$NEWT_INCLUDE$ac_delim
+NEWT_DIR!$NEWT_DIR$ac_delim
+PBX_NEWT!$PBX_NEWT$ac_delim
+USB_LIB!$USB_LIB$ac_delim
+USB_INCLUDE!$USB_INCLUDE$ac_delim
+USB_DIR!$USB_DIR$ac_delim
+PBX_USB!$PBX_USB$ac_delim
+PBX_DAHDI23!$PBX_DAHDI23$ac_delim
+PBX_HDLC!$PBX_HDLC$ac_delim
+USE_SELINUX!$USE_SELINUX$ac_delim
+ASCIIDOC!$ASCIIDOC$ac_delim
+PPPD_VERSION!$PPPD_VERSION$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 81; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+ ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+ ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[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="$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 ||
+ { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ ac_file_inputs="$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 "`IFS=:
+ echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ fi
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin";;
+ 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 ||
+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"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`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 ||
+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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`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
+# 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=
+
+case `sed -n '/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ 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
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;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
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+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 "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out"; rm -f "$tmp/out";;
+ *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+ esac
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status. If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless. But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*'
+ac_dB='\\)[ (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+ sed -n '
+ t rset
+ :rset
+ s/^[ ]*#[ ]*define[ ][ ]*//
+ t ok
+ d
+ :ok
+ s/[\\&,]/\\&/g
+ s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+ s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+ ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then 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.
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[ #]*u.*,/* & */,' >>conftest.defines
+
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
+do
+ # Write a here document:
+ cat >>$CONFIG_STATUS <<_ACEOF
+ # First, check the format of the line:
+ cat >"\$tmp/defines.sed" <<\\CEOF
+/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def
+/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def
+b
+:def
+_ACEOF
+ sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+ ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+ sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+ grep . conftest.tail >/dev/null || break
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+ if test x"$ac_file" != x-; then
+ echo "/* $configure_input */" >"$tmp/config.h"
+ cat "$ac_result" >>"$tmp/config.h"
+ if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f $ac_file
+ mv "$tmp/config.h" $ac_file
+ fi
+ else
+ echo "/* $configure_input */"
+ cat "$ac_result"
+ fi
+ rm -f "$tmp/out12"
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+{ echo "$as_me:$LINENO: *** dahdi-tools build successfully configured ***" >&5
+echo "$as_me: *** dahdi-tools build successfully configured ***" >&6;}
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..35e51e1
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,215 @@
+# 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])
+
+PBX_HDLC=0
+AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h])
+AC_COMPILE_IFELSE(
+ [ AC_LANG_PROGRAM( [#include <linux/hdlc.h>],
+ [#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 <sys/socket.h>
+ #include <linux/if.h>],
+ [#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([build_tools/menuselect-deps makeopts])
+AC_OUTPUT
+
+AC_MSG_NOTICE(*** dahdi-tools build successfully configured ***)
diff --git a/dahdi.init b/dahdi.init
new file mode 100755
index 0000000..874fa46
--- /dev/null
+++ b/dahdi.init
@@ -0,0 +1,333 @@
+#!/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
+# 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() {
+ # do nothing if there are no astribank devices:
+ if ! /usr/share/dahdi/waitfor_xpds; then return 0; fi
+
+ hotplug_exit_after_load
+
+ # overriding locales for the above two, as perl can be noisy
+ # when locales are missing.
+ # No register all the devices if they didn't auto-register:
+ LC_ALL=C dahdi_registration on
+}
+
+
+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 ""
+}
+
+if [ ! -x "$DAHDI_CFG" ]; then
+ echo "dahdi_cfg not executable"
+ exit 0
+fi
+
+if [ ! -f /etc/dahdi/system.conf ]; then
+ echo "/etc/dahdi/system.conf not found. Nothing to do."
+ exit 0
+fi
+
+RETVAL=0
+
+# See how we were called.
+case "$1" in
+ start)
+ 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
+
+ if [ ! -e /proc/dahdi/1 ]; then
+ echo "No hardware timing source found in /proc/dahdi, loading dahdi_dummy"
+ modprobe dahdi_dummy 2> /dev/null
+ fi
+
+ 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
+
+ # Set the right Astribanks ticker:
+ LC_ALL=C xpp_sync "$XPP_SYNC"
+
+ 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.xml b/dahdi.xml
new file mode 100644
index 0000000..f071f5d
--- /dev/null
+++ b/dahdi.xml
@@ -0,0 +1,26 @@
+<category name="MENUSELECT_UTILS" displayname="Utilities">
+ <member name="fxotune" remove_on_change="fxotune fxotune.o">
+ </member>
+ <member name="fxstest" remove_on_change="fxstest fxstest.o">
+ <defaultenabled>no</defaultenabled>
+ </member>
+ <member name="sethdlc" remove_on_change="sethdlc sethdlc.o">
+ <depend>hdlc</depend>
+ </member>
+ <member name="dahdi_cfg" remove_on_change="dahdi_cfg dahdi_cfg.o">
+ </member>
+ <member name="dahdi_diag" remove_on_change="dahdi_diag dahdi_diag.o">
+ <defaultenabled>no</defaultenabled>
+ </member>
+ <member name="dahdi_monitor" remove_on_change="dahdi_monitor dahdi_monitor.o">
+ </member>
+ <member name="dahdi_scan" remove_on_change="dahdi_scan dahdi_scan.o">
+ </member>
+ <member name="dahdi_speed" remove_on_change="dahdi_speed dahdi_speed.o">
+ </member>
+ <member name="dahdi_test" remove_on_change="dahdi_test dahdi_test.o">
+ </member>
+ <member name="dahdi_tool" remove_on_change="dahdi_tool dahdi_tool.o">
+ <depend>libnewt</depend>
+ </member>
+</category>
diff --git a/dahdi_cfg.c b/dahdi_cfg.c
new file mode 100644
index 0000000..9386e00
--- /dev/null
+++ b/dahdi_cfg.c
@@ -0,0 +1,1662 @@
+/*
+ * Configuration program for DAHDI Telephony Interface
+ *
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <dahdi/user.h>
+#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 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 fo_real = 1;
+
+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 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";
+ }
+}
+
+int ind_ioctl(int channo, int fd, int op, void *data)
+{
+ struct dahdi_indirect_data ind;
+
+ ind.chan = channo;
+ ind.op = op;
+ ind.data = data;
+ return ioctl(fd, DAHDI_INDIRECT, &ind);
+}
+
+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 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 argc;
+ int res;
+ int chans;
+ int timing;
+ argc = res = parseargs(args, realargs, 4, ',');
+ if (res != 4) {
+ error("Incorrect number of arguments to 'dynamic' (should be <driver>,<address>,<num channels>, <timing>)\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 <spanno>,<timing>,<lbo>,<framing>,<coding>[, 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;
+ }
+ 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<res;x++) {
+ if (strchr(args[x], '-')) {
+ /* It's a range */
+ dahdi_copy_string(argcopy, args[x], sizeof(argcopy));
+ res2 = parseargs(argcopy, range, 2, '-');
+ if (res2 != 2) {
+ error("Syntax error in range '%s'. Should be <val1>-<val2>.\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;
+ 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_MAX_CHANNELS;x++) {
+ if (chans[x]) {
+ if (slineno[x]) {
+ error("Channel %d already configured as '%s' at line %d\n", x, sig[x], slineno[x]);
+ continue;
+ }
+ if ((!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) && slineno[dacschan]) {
+ error("DACS Destination channel %d already configured as '%s' at line %d\n", dacschan, sig[dacschan], slineno[dacschan]);
+ continue;
+ } else {
+ cc[dacschan].chan = dacschan;
+ cc[dacschan].master = dacschan;
+ slineno[dacschan] = lineno;
+ }
+ cc[x].chan = x;
+ cc[x].master = x;
+ slineno[x] = lineno;
+ if (!strcasecmp(keyword, "e&m")) {
+ cc[x].sigtype = DAHDI_SIG_EM;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "e&me1")) {
+ cc[x].sigtype = DAHDI_SIG_EM_E1;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxsls")) {
+ cc[x].sigtype = DAHDI_SIG_FXSLS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxsgs")) {
+ cc[x].sigtype = DAHDI_SIG_FXSGS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxsks")) {
+ cc[x].sigtype = DAHDI_SIG_FXSKS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxols")) {
+ cc[x].sigtype = DAHDI_SIG_FXOLS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxogs")) {
+ cc[x].sigtype = DAHDI_SIG_FXOGS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "fxoks")) {
+ cc[x].sigtype = DAHDI_SIG_FXOKS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "cas") || !strcasecmp(keyword, "user")) {
+ if (parse_idle(&cc[x].idlebits, idle))
+ return -1;
+ cc[x].sigtype = DAHDI_SIG_CAS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "dacs")) {
+ /* Setup channel for monitor */
+ cc[x].idlebits = dacschan;
+ cc[x].sigtype = DAHDI_SIG_DACS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ /* Setup inverse */
+ cc[dacschan].idlebits = x;
+ cc[dacschan].sigtype = DAHDI_SIG_DACS;
+ sig[x] = sigtype_to_str(cc[dacschan].sigtype);
+ dacschan++;
+ } else if (!strcasecmp(keyword, "dacsrbs")) {
+ /* Setup channel for monitor */
+ cc[x].idlebits = dacschan;
+ cc[x].sigtype = DAHDI_SIG_DACS_RBS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ /* Setup inverse */
+ cc[dacschan].idlebits = x;
+ cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
+ sig[x] = sigtype_to_str(cc[dacschan].sigtype);
+ dacschan++;
+ } else if (!strcasecmp(keyword, "unused")) {
+ cc[x].sigtype = 0;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
+ cc[x].sigtype = DAHDI_SIG_CLEAR;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
+ } else if (!strcasecmp(keyword, "clear")) {
+ sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
+ if (master) {
+ cc[x].sigtype = DAHDI_SIG_SLAVE;
+ cc[x].master = master;
+ } else {
+ cc[x].sigtype = DAHDI_SIG_CLEAR;
+ master = x;
+ }
+ } else if (!strcasecmp(keyword, "rawhdlc")) {
+ sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
+ if (master) {
+ cc[x].sigtype = DAHDI_SIG_SLAVE;
+ cc[x].master = master;
+ } else {
+ cc[x].sigtype = DAHDI_SIG_HDLCRAW;
+ master = x;
+ }
+ } else if (!strcasecmp(keyword, "nethdlc")) {
+ sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
+ memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
+ if (master) {
+ cc[x].sigtype = DAHDI_SIG_SLAVE;
+ cc[x].master = master;
+ } else {
+ cc[x].sigtype = DAHDI_SIG_HDLCNET;
+ if (idle) {
+ dahdi_copy_string(cc[x].netdev_name, idle, sizeof(cc[x].netdev_name));
+ }
+ master = x;
+ }
+ } else if (!strcasecmp(keyword, "fcshdlc")) {
+ sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
+ if (master) {
+ cc[x].sigtype = DAHDI_SIG_SLAVE;
+ cc[x].master = master;
+ } else {
+ cc[x].sigtype = DAHDI_SIG_HDLCFCS;
+ master = x;
+ }
+ } else if (!strcasecmp(keyword, "dchan")) {
+ sig[x] = "D-channel";
+ cc[x].sigtype = DAHDI_SIG_HDLCFCS;
+ } else if (!strcasecmp(keyword, "hardhdlc")) {
+ sig[x] = "Hardware assisted D-channel";
+ cc[x].sigtype = DAHDI_SIG_HARDHDLC;
+ } else if (!strcasecmp(keyword, "mtp2")) {
+ sig[x] = "MTP2";
+ cc[x].sigtype = DAHDI_SIG_MTP2;
+ } else {
+ fprintf(stderr, "Huh? (%s)\n", keyword);
+ }
+ }
+ }
+ return 0;
+}
+
+static int setlaw(char *keyword, char *args)
+{
+ int res;
+ int law;
+ int x;
+ int chans[DAHDI_MAX_CHANNELS];
+
+ bzero(chans, sizeof(chans));
+ res = apply_channels(chans, args);
+ if (res <= 0)
+ return -1;
+ if (!strcasecmp(keyword, "alaw")) {
+ law = DAHDI_LAW_ALAW;
+ } else if (!strcasecmp(keyword, "mulaw")) {
+ law = DAHDI_LAW_MULAW;
+ } else if (!strcasecmp(keyword, "deflaw")) {
+ law = DAHDI_LAW_DEFAULT;
+ } else {
+ fprintf(stderr, "Huh??? Don't know about '%s' law\n", keyword);
+ return -1;
+ }
+ for (x=0;x<DAHDI_MAX_CHANNELS;x++) {
+ if (chans[x])
+ cc[x].deflaw = law;
+ }
+ return 0;
+}
+
+static int setfiftysixkhdlc(char *keyword, char *args)
+{
+ int res;
+
+ res = apply_channels(fiftysixkhdlc, args);
+ if (res <= 0)
+ return -1;
+
+ return 0;
+}
+
+static void apply_fiftysix(void)
+{
+ int x;
+ int rate;
+ int chanfd;
+
+ for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
+ chanfd = open("/dev/dahdi/channel", O_RDWR);
+ if (chanfd == -1) {
+ fprintf(stderr,
+ "Couldn't open /dev/dahdi/channel: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+
+ if (ioctl(chanfd, DAHDI_SPECIFY, &x)) {
+ close(chanfd);
+ continue;
+ }
+
+ if (fiftysixkhdlc[x]) {
+ printf("Setting channel %d to 56K mode (only valid on HDLC channels)\n", x);
+ rate = 56;
+ } else {
+ rate = 64;
+ }
+
+ if (ioctl(chanfd, DAHDI_HDLC_RATE, &rate)) {
+ fprintf(stderr, "Error setting HDLC rate\n");
+ exit(-1);
+ }
+ close(chanfd);
+ }
+}
+
+static int setechocan(char *keyword, char *args)
+{
+ int res;
+ int chans[DAHDI_MAX_CHANNELS] = { 0, };
+ char *echocan, *chanlist;
+ unsigned int x;
+
+ echocan = strtok(args, ",");
+
+ while ((chanlist = strtok(NULL, ","))) {
+ res = apply_channels(chans, chanlist);
+ if (res <= 0) {
+ return -1;
+ }
+ }
+
+ for (x = 0; x < DAHDI_MAX_CHANNELS; x++) {
+ if (chans[x]) {
+ dahdi_copy_string(ae[x].echocan, echocan, sizeof(ae[x].echocan));
+ }
+ }
+
+ return 0;
+}
+
+static int registerzone(char *keyword, char *args)
+{
+ if (numzones >= 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 argc;
+ int res;
+ int rxtone;
+ int rxtag;
+ int txtone;
+ int isdcs = 0;
+ argc = res = parseargs(args, realargs, 3, ',');
+ if (res != 3) {
+ error("Incorrect number of arguments to 'ctcss' (should be <rxtone>,<rxtag>,<txtone>)\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 argc;
+ int res;
+ int rxtone;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'dcsrx' (should be <rxtone>)\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 argc;
+ int res;
+ int txtone;
+ int isdcs = 0;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'tx' (should be <txtone>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'debouncetime' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'bursttime' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'txgain' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'rxgain' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'de-emp' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'pre_emp' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'invertcor' (should be <value>)\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 argc;
+ int res;
+ int val;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'exttone' (should be <value>)\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 argc;
+ int res;
+ int val;
+ int x = 0;
+ argc = res = parseargs(args, realargs, 1, ',');
+ if (res != 1) {
+ error("Incorrect number of arguments to 'corthresh' (should be <value>)\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;
+
+ toneindex = 1;
+ bzero(chans, sizeof(chans));
+ res = apply_channels(chans, args);
+ if (res <= 0)
+ return -1;
+ for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ if (chans[x]) {
+ p.radpar = DAHDI_RADPAR_NUMTONES;
+ if (ind_ioctl(x,fd,DAHDI_RADIO_GETPARAM,&p) == -1)
+ n = 0;
+ else
+ n = p.data;
+
+ if (n)
+ {
+ p.radpar = DAHDI_RADPAR_INITTONE;
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1) {
+ error("Cannot init tones for channel %d\n",x);
+ }
+ if (!rxtones[0]) for(i = 1; i <= n; i++)
+ {
+ if (rxtones[i])
+ {
+ p.radpar = DAHDI_RADPAR_RXTONE;
+ p.index = i;
+ p.data = rxtones[i];
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set rxtone on channel %d\n",x);
+ }
+ if (rxtags[i])
+ {
+ p.radpar = DAHDI_RADPAR_RXTONECLASS;
+ p.index = i;
+ p.data = rxtags[i];
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set rxtag on channel %d\n",x);
+ }
+ if (txtones[i])
+ {
+ p.radpar = DAHDI_RADPAR_TXTONE;
+ p.index = i;
+ p.data = txtones[i];
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set txtone on channel %d\n",x);
+ }
+ } else { /* if we may have DCS receive */
+ if (rxtones[0])
+ {
+ p.radpar = DAHDI_RADPAR_RXTONE;
+ p.index = 0;
+ p.data = rxtones[0];
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set DCS rxtone on channel %d\n",x);
+ }
+ }
+ if (txtones[0])
+ {
+ p.radpar = DAHDI_RADPAR_TXTONE;
+ p.index = 0;
+ p.data = txtones[0];
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set default txtone on channel %d\n",x);
+ }
+ }
+ if (debouncetime)
+ {
+ p.radpar = DAHDI_RADPAR_DEBOUNCETIME;
+ p.data = debouncetime;
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set debouncetime on channel %d\n",x);
+ }
+ if (bursttime)
+ {
+ p.radpar = DAHDI_RADPAR_BURSTTIME;
+ p.data = bursttime;
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set bursttime on channel %d\n",x);
+ }
+ p.radpar = DAHDI_RADPAR_DEEMP;
+ p.data = deemp;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ p.radpar = DAHDI_RADPAR_PREEMP;
+ p.data = preemp;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ p.radpar = DAHDI_RADPAR_TXGAIN;
+ p.data = txgain;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ p.radpar = DAHDI_RADPAR_RXGAIN;
+ p.data = rxgain;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ p.radpar = DAHDI_RADPAR_INVERTCOR;
+ p.data = invertcor;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ p.radpar = DAHDI_RADPAR_EXTRXTONE;
+ p.data = exttone;
+ ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p);
+ if (corthresh)
+ {
+ p.radpar = DAHDI_RADPAR_CORTHRESH;
+ p.data = corthresh - 1;
+ if (ind_ioctl(x,fd,DAHDI_RADIO_SETPARAM,&p) == -1)
+ error("Cannot set corthresh on channel %d\n",x);
+ }
+ }
+ }
+ clear_fields();
+ return 0;
+}
+
+/* End Radio functions */
+
+static void printconfig(int fd)
+{
+ int x,y;
+ int ps;
+ int configs=0;
+ struct dahdi_versioninfo vi;
+
+ strcpy(vi.version, "Unknown");
+ strcpy(vi.echo_canceller, "Unknown");
+
+ if (ioctl(fd, DAHDI_GETVERSION, &vi))
+ error("Unable to read DAHDI version information.\n");
+
+ printf("\nDAHDI Version: %s\n"
+ "Echo Canceller(s): %s\n"
+ "Configuration\n"
+ "======================\n\n", vi.version, vi.echo_canceller);
+ for (x = 0; x < spans; x++) {
+ printf("SPAN %d: %3s/%4s Build-out: %s\n",
+ lc[x].span,
+ (lc[x].lineconfig & DAHDI_CONFIG_D4 ? "D4" :
+ lc[x].lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
+ lc[x].lineconfig & DAHDI_CONFIG_CCS ? "CCS" : "CAS"),
+ (lc[x].lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
+ lc[x].lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
+ lc[x].lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : "???"),
+ lbostr[lc[x].lbo]);
+ }
+ for (x=0;x<numdynamic;x++) {
+ printf("Dynamic span %d: driver %s, addr %s, channels %d, timing %d\n",
+ x +1, zds[x].driver, zds[x].addr, zds[x].numchans, zds[x].timing);
+ }
+ if (verbose > 1) {
+ printf("\nChannel map:\n\n");
+ for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
+ configs++;
+ ps = 0;
+ if ((cc[x].sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS)
+ printf("Channel %02d %s to %02d", x, sig[x], cc[x].idlebits);
+ else {
+ printf("Channel %02d: %s (%s)", x, sig[x], laws[cc[x].deflaw]);
+ printf(" (Echo Canceler: %s)", ae[x].echocan[0] ? ae[x].echocan : "none");
+ for (y=1;y<DAHDI_MAX_CHANNELS;y++) {
+ if (cc[y].master == x) {
+ printf("%s%02d", ps++ ? " " : " (Slaves: ", y);
+ }
+ }
+ }
+ if (ps)
+ printf(")\n");
+ else
+ printf("\n");
+ } else
+ if (cc[x].sigtype) configs++;
+ }
+ } else {
+ for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ if (cc[x].sigtype)
+ configs++;
+ }
+ }
+ printf("\n%d channels to configure.\n\n", configs);
+}
+
+static struct handler {
+ char *keyword;
+ int (*func)(char *keyword, char *args);
+} handlers[] = {
+ { "span", spanconfig },
+ { "dynamic", dspanconfig },
+ { "loadzone", registerzone },
+ { "defaultzone", defaultzone },
+ { "e&m", chanconfig },
+ { "e&me1", chanconfig },
+ { "fxsls", chanconfig },
+ { "fxsgs", chanconfig },
+ { "fxsks", chanconfig },
+ { "fxols", chanconfig },
+ { "fxogs", chanconfig },
+ { "fxoks", chanconfig },
+ { "rawhdlc", chanconfig },
+ { "nethdlc", chanconfig },
+ { "fcshdlc", chanconfig },
+ { "hardhdlc", chanconfig },
+ { "mtp2", chanconfig },
+ { "dchan", chanconfig },
+ { "bchan", chanconfig },
+ { "indclear", chanconfig },
+ { "clear", chanconfig },
+ { "unused", chanconfig },
+ { "cas", chanconfig },
+ { "dacs", chanconfig },
+ { "dacsrbs", chanconfig },
+ { "user", chanconfig },
+ { "alaw", setlaw },
+ { "mulaw", setlaw },
+ { "deflaw", setlaw },
+ { "ctcss", ctcss },
+ { "dcsrx", dcsrx },
+ { "rxdcs", dcsrx },
+ { "tx", tx },
+ { "debouncetime", debounce_time },
+ { "bursttime", burst_time },
+ { "exttone", ext_tone },
+ { "invertcor", invert_cor },
+ { "corthresh", cor_thresh },
+ { "rxgain", rx_gain },
+ { "txgain", tx_gain },
+ { "deemp", de_emp },
+ { "preemp", pre_emp },
+ { "channel", rad_chanconfig },
+ { "channels", rad_chanconfig },
+ { "echocanceller", setechocan },
+ { "56k", setfiftysixkhdlc },
+};
+
+static char *readline()
+{
+ static char buf[256];
+ char *c;
+ do {
+ if (!fgets(buf, sizeof(buf), cf))
+ return NULL;
+ /* Strip comments */
+ c = strchr(buf, '#');
+ if (c)
+ *c = '\0';
+ trim(buf);
+ lineno++;
+ } while (!strlen(buf));
+ return buf;
+}
+
+static void usage(char *argv0, int exitcode)
+{
+ char *c;
+ c = strrchr(argv0, '/');
+ if (!c)
+ c = argv0;
+ else
+ c++;
+ fprintf(stderr, "%s\n", dahdi_tools_version);
+ fprintf(stderr,
+ "Usage: %s [options]\n"
+ " Valid options are:\n"
+ " -c <filename> -- Use <filename> 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"
+ " -v -- Verbose (more -v's means more verbose)\n"
+ ,c);
+ exit(exitcode);
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ char *buf;
+ char *key, *value;
+ int x,found;
+
+ while((c = getopt(argc, argv, "fthc:vsd::")) != -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':
+ fo_real = 0;
+ break;
+ case 's':
+ stopmode = 1;
+ break;
+ case 'd':
+ if (optarg)
+ debug = atoi(optarg);
+ else
+ debug = 1;
+ break;
+ }
+ }
+
+ if (verbose) {
+ fprintf(stderr, "%s\n", dahdi_tools_version);
+ }
+
+ if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR);
+ if (fd < 0) {
+ error("Unable to open master device '%s'\n", MASTER_DEVICE);
+ goto finish;
+ }
+ 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 <keyword>=<value>\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, "<End of File>\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 (!fo_real)
+ exit(0);
+
+
+ if (debug & DEBUG_APPLY) {
+ printf("About to open Master device\n");
+ fflush(stdout);
+ }
+ for (x=0;x<numdynamic;x++) {
+ /* destroy them all */
+ ioctl(fd, DAHDI_DYNAMIC_DESTROY, &zds[x]);
+ }
+ if (stopmode) {
+ for (x=0;x<spans;x++) {
+ if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
+ fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
+ close(fd);
+ exit(1);
+ }
+ }
+ exit(1);
+ }
+ for (x=0;x<spans;x++) {
+ if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
+ fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
+ close(fd);
+ exit(1);
+ }
+ }
+ for (x=0;x<numdynamic;x++) {
+ if (ioctl(fd, DAHDI_DYNAMIC_CREATE, &zds[x])) {
+ fprintf(stderr, "DAHDI dynamic span creation failed: %s\n", strerror(errno));
+ close(fd);
+ exit(1);
+ }
+ }
+ for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ struct dahdi_params current_state;
+ int master;
+ int needupdate = force;
+
+ if (debug & DEBUG_APPLY) {
+ printf("Configuring device %d\n", x);
+ fflush(stdout);
+ }
+ if (!cc[x].sigtype)
+ continue;
+
+ if (!needupdate) {
+ memset(¤t_state, 0, sizeof(current_state));
+ current_state.channo = cc[x].chan | DAHDI_GET_PARAMS_RETURN_MASTER;
+ if (ioctl(fd, DAHDI_GET_PARAMS, ¤t_state))
+ needupdate = 1;
+ }
+
+ if (!needupdate) {
+ master = current_state.channo >> 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(1);
+ }
+
+ 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(1);
+ }
+ }
+ 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<numzones;x++) {
+ if (debug & DEBUG_APPLY) {
+ printf("Loading tone zone for %s\n", zonestoload[x]);
+ fflush(stdout);
+ }
+ if (tone_zone_register(fd, zonestoload[x])) {
+ if (errno != EBUSY)
+ error("Unable to register tone zone '%s'\n", zonestoload[x]);
+ }
+ }
+ if (debug & DEBUG_APPLY) {
+ printf("Doing startup\n");
+ fflush(stdout);
+ }
+ if (deftonezone > -1) {
+ if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) {
+ fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno);
+ close(fd);
+ exit(1);
+ }
+ }
+ for (x=0;x<spans;x++) {
+ if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
+ fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
+ close(fd);
+ exit(1);
+ }
+ }
+ apply_fiftysix();
+ exit(0);
+}
diff --git a/dahdi_diag.c b/dahdi_diag.c
new file mode 100644
index 0000000..ec1a587
--- /dev/null
+++ b/dahdi_diag.c
@@ -0,0 +1,55 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dahdi/user.h>
+#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 <channel>\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..f9c9083
--- /dev/null
+++ b/dahdi_maint.c
@@ -0,0 +1,236 @@
+/*
+ * Performance and Maintenance utility
+ *
+ * Written by Russ Meyerriecks <rmeyerriecks at digium.com>
+ *
+ * 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 <stdio.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <dahdi/user.h>
+#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 <span num> <options>\n", c);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -h, --help display help\n");
+ fprintf(stderr, " -s, --span <span num> specify the span\n");
+ fprintf(stderr, " -l, --loopback <localhost|networkline|"\
+ "networkpayload|off>\n"\
+ "\t\tlocalhost - loop back towards host\n"\
+ "\t\tnetworkline - network line loopback\n"\
+ "\t\tnetworkpayload - network payload loopback\n");
+ fprintf(stderr, " -i, --insert <fas|multi|crc|cas|prbs|bipolar>"\
+ "\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 sflag = 0;
+ 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': /* local host loopback */
+ display_help(argv[0], 0);
+ break;
+ case 'l': /* network line loopback */
+ larg = optarg;
+ doloopback = 1;
+ break;
+ case 's': /* specify a span */
+ span = atoi(optarg);
+ sflag = 1;
+ 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)
+ printf("Error counters not supported by the driver"\
+ " for this span\n");
+ printf("Span %d:\n", span);
+ printf(">FEC : %d:\n", s.fecount);
+ printf(">CEC : %d:\n", s.crc4count);
+ printf(">CVC : %d:\n", s.cvcount);
+ printf(">EBC : %d:\n", s.ebitcount);
+ printf(">BEC : %d:\n", s.becount);
+ printf(">PRBS: %d:\n", s.prbs);
+ printf(">GES : %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, "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");
+ }
+
+ 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..e61b610
--- /dev/null
+++ b/dahdi_monitor.c
@@ -0,0 +1,783 @@
+/*
+ * Monitor a DAHDI Channel
+ *
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * 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 <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include <dahdi/user.h>
+#include "dahdi_tools_version.h"
+#include "wavformat.h"
+#include "autoconfig.h"
+
+#ifdef HAVE_SYS_SOUNDCARD_H
+# include <sys/soundcard.h>
+#else
+# ifdef HAVE_LINUX_SOUNDCARD_H
+# include <linux/soundcard.h>
+# 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 <channel num> [-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);
+ 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;
+
+ rewind(ofh[i]);
+
+ if (fread(&wavheaders[i], 1, sizeof(struct wavheader), ofh[i]) != sizeof(struct wavheader)) {
+ fprintf(stderr, "Failed to read in a full wav header. Expect bad things.\n");
+ }
+
+ 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_scan.c b/dahdi_scan.c
new file mode 100644
index 0000000..582f44d
--- /dev/null
+++ b/dahdi_scan.c
@@ -0,0 +1,205 @@
+/*
+ * Scan and output information about DAHDI spans and ports.
+ *
+ * Written by Brandon Kruse <bkruse at digium.com>
+ * and Kevin P. Fleming <kpfleming at digium.com>
+ * Copyright (C) 2007 Digium, Inc.
+ *
+ * Based on zttool written by Mark Spencer <markster at digium.com>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <dahdi/user.h>
+
+#include "dahdi_tools_version.h"
+
+static inline int is_digital_span(struct dahdi_spaninfo *s)
+{
+ return (s->linecompat > 0);
+}
+
+int main(int argc, char *argv[])
+{
+ int ctl;
+ int x, y, z;
+ struct dahdi_params params;
+ unsigned int basechan = 1;
+ 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;
+ }
+ }
+
+ 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/");
+#ifdef DAHDI_ALARM_LFA
+ if (s.alarms & DAHDI_ALARM_LFA)
+ strcat(alarms, "LFA/");
+ if (s.alarms & DAHDI_ALARM_LMFA)
+ strcat(alarms, "LMFA/");
+#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)
+ strcpy(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 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_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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ *
+ * 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 <stdio.h>
+#include <sys/signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#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..ed71443
--- /dev/null
+++ b/dahdi_test.c
@@ -0,0 +1,164 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <math.h>
+#include <getopt.h>
+
+#include "dahdi_tools_version.h"
+
+#define SIZE 8000
+
+static int pass = 0;
+static float best = 0.0;
+static float worst = 100.0;
+static double total = 0.0;
+static double delay_total = 0.0;
+
+void hup_handler(int sig)
+{
+ printf("\n--- Results after %d passes ---\n", pass);
+ printf("Best: %.3f -- Worst: %.3f -- Average: %f, Difference: %f\n",
+ best, worst, pass ? total/pass : 100.00, pass ? delay_total/pass : 100);
+ 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;
+ int verbose = 0;
+ char buf[8192];
+ float score;
+ 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) {
+ double percent = 100.0 * (count - ms) / count;
+ if (verbose) {
+ printf("\n%d samples in %0.3f system clock sample intervals (%.3f%%)",
+ count, ms, 100 - percent);
+ } else if (pass > 0 && (pass % 8) == 0) {
+ printf("\n");
+ }
+ score = 100.0 - fabs(percent);
+ if (score > best)
+ best = score;
+ if (score < worst)
+ worst = score;
+ if (!verbose)
+ printf("%.3f%% ", score);
+ total += score;
+ delay_total += 100 - percent;
+ fflush(stdout);
+ 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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * 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
+ <depend>newt</depend>
+ ***/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <newt.h>
+
+#include <dahdi/user.h>
+#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, "<unknown>/");
+ 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<DAHDI_MAX_SPANS;x++) {
+ s = getalarms(x, 0);
+ if (s && spans) {
+ /* Found one! */
+ newtListboxAppendEntry(spans, s, (void *)(long)x);
+ }
+ }
+ if (spans)
+ newtListboxSetCurrentByKey(spans, prev);
+
+}
+
+static void sel_callback(newtComponent c, void *cbdata)
+{
+ int span;
+ char info[256];
+ char info2[256];
+ cbdata = newtListboxGetCurrent(c);
+ if (cbdata) {
+ span = (long)(cbdata);
+ snprintf(info, sizeof (info), "Span %d: %d total channels, %d configured", span, s[span].totalchans, s[span].numchans);
+ snprintf(info2, sizeof(info2), "%-59s F1=Details F10=Quit", info);
+ } else {
+ span = -1;
+ strcpy(info, "There are no DAHDI spans on this system.");
+ snprintf(info2, sizeof(info2), "%-59s F10=Quit", info);
+ }
+ newtPopHelpLine();
+ newtPushHelpLine(info2);
+}
+
+static void show_bits(int span, newtComponent bitbox, newtComponent inuse, newtComponent levels, newtComponent bpvcount,
+ newtComponent alarms, newtComponent syncsrc, newtComponent irqmisses)
+{
+ struct dahdi_params zp;
+ int x;
+ int res;
+ char c;
+ char tabits[80];
+ char tbbits[80];
+ char tcbits[80];
+ char tdbits[80];
+ char rabits[80];
+ char rbbits[80];
+ char rcbits[80];
+ char rdbits[80];
+ char tmp[1024];
+
+ int use = 0;
+
+ memset(tabits,0, sizeof(tabits));
+ memset(tbbits,0, sizeof(tbbits));
+ memset(rabits,0, sizeof(rabits));
+ memset(rbbits,0, sizeof(rbbits));
+ memset(tcbits,0, sizeof(tcbits));
+ memset(tdbits,0, sizeof(tdbits));
+ memset(rcbits,0, sizeof(rcbits));
+ memset(rdbits,0, sizeof(rdbits));
+ memset(tabits,32, span_max_chan_pos);
+ memset(tbbits,32, span_max_chan_pos);
+ memset(rabits,32, span_max_chan_pos);
+ memset(rbbits,32, span_max_chan_pos);
+ memset(tcbits,32, span_max_chan_pos);
+ memset(tdbits,32, span_max_chan_pos);
+ memset(rcbits,32, span_max_chan_pos);
+ memset(rdbits,32, span_max_chan_pos);
+
+ for (x=0;x<DAHDI_MAX_CHANNELS;x++) {
+ memset(&zp, 0, sizeof(zp));
+ zp.channo = x;
+ res = ioctl(ctl, DAHDI_GET_PARAMS, &zp);
+ if (!res) {
+ if (zp.spanno == span) {
+ if (zp.sigtype && (zp.rxbits > -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<DAHDI_MAX_CHANNELS;x++) {
+ struct dahdi_params zp;
+ int res;
+ memset(&zp, 0, sizeof(zp));
+ zp.channo = x;
+ res = ioctl(ctl, DAHDI_GET_PARAMS, &zp);
+ if (!res && zp.spanno == span && zp.chanpos > 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/doc/dahdi_cfg.8 b/doc/dahdi_cfg.8
new file mode 100644
index 0000000..7a1fe88
--- /dev/null
+++ b/doc/dahdi_cfg.8
@@ -0,0 +1,70 @@
+.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] [\-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
+.RE
+
+.B \-s
+.RS
+Only shutdown spans.
+.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
+<santiago at unicauca.edu.co> 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 <tzafrir.cohen at xorcom.com>
+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_monitor.8 b/doc/dahdi_monitor.8
new file mode 100644
index 0000000..17adc64
--- /dev/null
+++ b/doc/dahdi_monitor.8
@@ -0,0 +1,43 @@
+.TH "DAHDI_MONITOR" "8" "16 June 2008" "" ""
+
+.SH NAME
+dahdi_monitor \- checks the rx/tx levels of DAHDI channels
+.SH SYNOPSIS
+
+.B dahdi_monitor \fIchannel number\fB [\-v] [\-f \fIFILE\fB]
+
+.SH DESCRIPTION
+
+dahdi_monitor monitors a DAHDI channel. It gives you a visual
+representation of the sound strengths and makes it easy to see if
+the received or transmitted signals are too high or out of
+balance
+
+.SH OPTIONS
+The first (mandatory) parameter is the number of the channel
+to monitor.
+
+.B \-v
+.RS
+Display visual audio levels.
+.RE
+
+.B \-f \fIFILE
+.RS
+Write output to FILE
+.RE
+
+Some extra, yet undocumented, options.
+
+.SH SEE ALSO
+.PP
+dahdi_tool(8), dahdi_cfg(8), asterisk(8).
+
+.SH AUTHOR
+.PP
+This manual page was written by Santiago Ruano Rinc\['o]n
+<santiago at unicauca.edu.co> 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 <tzafrir.cohen at xorcom.com>
+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_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 <tzafrir.cohen at xorcom.com>
+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
+<santiago at unicauca.edu.co> 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/fxotune.8 b/doc/fxotune.8
new file mode 100644
index 0000000..efa94c3
--- /dev/null
+++ b/doc/fxotune.8
@@ -0,0 +1,207 @@
+.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
+\- 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 <tzafrir.cohen at xorcom.com>
+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 <tzafrir.cohen at xorcom.com> .
+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 <http://issues.asterisk.org> .
+
+.SH SEE ALSO
+pattest(8), dahdi_cfg(8), asterisk(8).
+
+.SH AUTHOR
+
+This manual page was written by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+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 <tzafrir.cohen at xorcom.com>
+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..08a9e9b
--- /dev/null
+++ b/fxotune.c
@@ -0,0 +1,1272 @@
+/*
+ * fxotune.c -- A utility for tuning the various settings on the fxo
+ * modules for the TDM400 cards.
+ *
+ * by Matthew Fredrickson <creslin at digium.com>
+ *
+ * (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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/time.h>
+
+#include <dahdi/user.h>
+#include <dahdi/wctdm_user.h>
+
+#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 *dahdipath = "/dev/dahdi";
+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 <options> | -d <options>)\n"
+"\n"
+" -s : set previously calibrated echo settings\n"
+" -i : calibrate echo settings\n"
+" options : [<dialstring>] [-t <calibtype>]\n"
+" [-b <startdev>][-e <stopdev>]\n"
+" [-n <dialstring>][-l <delaytosilence>][-m <silencegoodfor>]\n"
+" -d : dump input and output waveforms to ./fxotune_dump.vals\n"
+" options : [-b <device>][-w <waveform>]\n"
+" [-n <dialstring>][-l <delaytosilence>][-m <silencegoodfor>]\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 <path> : Write the received raw 16-bit signed linear audio that is\n"
+" used in processing to the file specified by <path>\n"
+" -c <config_file>\n"
+"\n"
+" <calibtype> - type of calibration\n"
+" (default 2, old method 1)\n"
+" <startdev>\n"
+" <stopdev> - defines a range of devices to test\n"
+" (default: 1-252)\n"
+" <dialstring> - string to dial to clear the line\n"
+" (default 5)\n"
+" <delaytosilence> - seconds to wait for line to clear (default 0)\n"
+" <silencegoodfor> - seconds before line will no longer be clear\n"
+" (default 18)\n"
+" <device> - the device to perform waveform dump on\n"
+" (default 1)\n"
+" <waveform> - -1 for multitone waveform, or frequency of\n"
+" single tone (default -1)\n"
+" <config_file> - 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;
+}
+
+/**
+ * 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)
+{
+ 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;
+ }
+
+ /* 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;
+
+ snprintf(completedahdipath, sizeof(completedahdipath), "%s/%d", dahdipath, mydahdi);
+ fd = open(completedahdipath, O_RDWR);
+
+ if (fd < 0) {
+ fprintf(stdout, "open error on %s: %s\n", completedahdipath, strerror(errno));
+ 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;
+ snprintf(dahdidev, sizeof(dahdidev), "%s/%d", dahdipath, dahdimodule);
+
+ fd = open(dahdidev, O_RDWR);
+ if (fd < 0) {
+ fprintf(stdout, "%s absent: %s\n", dahdidev, strerror(errno));
+ 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;
+ char dahdidev[80] = "";
+ 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++) {
+ snprintf(dahdidev, sizeof(dahdidev), "%s/%d", dahdipath, devno);
+
+ fd = open(dahdidev, O_RDWR);
+ if (fd < 0) {
+ fprintf(stdout, "%s absent: %s\n", dahdidev, strerror(errno));
+ continue;
+ }
+
+ fprintf(stdout, "Tuning module %s\n", dahdidev);
+
+ 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 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 <dialstr> */
+ 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;
+ break;
+ case 'e':
+ stopdev = moreargs ? atoi(argv[++i]) : stopdev;
+ 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);
+ else
+ return -1;
+ }
+
+ if (doset)
+ return do_set(configfile);
+
+ 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 <creslin at digium.com>
+ *
+ * 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..130fad5
--- /dev/null
+++ b/fxstest.c
@@ -0,0 +1,337 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <dahdi/user.h>
+#include <dahdi/wctdm_user.h>
+
+#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 main(int argc, char *argv[])
+{
+ int fd;
+ int res;
+ int x;
+ if (argc < 3) {
+ fprintf(stderr, "Usage: fxstest <dahdi device> <cmd>\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 <sequence> [<duration>]- Send a sequence of dtmf tones (\"-\" denotes no tone)\n"
+ " dtmfcid - create a dtmf cid spill without polarity reversal\n");
+ exit(1);
+ }
+ fd = open(argv[1], O_RDWR);
+ 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<NUM_REGS;x++) {
+ if (regs.direct[x])
+ break;
+ }
+ if (x == NUM_REGS)
+ numregs = 60;
+ printf("Direct registers: \n");
+ for (x=0;x<numregs;x++) {
+ printf("%3d. %02x ", x, regs.direct[x]);
+ if ((x % 8) == 7)
+ printf("\n");
+ }
+ if (numregs == NUM_REGS) {
+ printf("\n\nIndirect registers: \n");
+ for (x=0;x<NUM_INDIRECT_REGS;x++) {
+ printf("%3d. %04x ", x, regs.indirect[x]);
+ if ((x % 6) == 5)
+ printf("\n");
+ }
+ }
+ printf("\n\n");
+ }
+ } else if (!strcasecmp(argv[2], "setdirect") ||
+ !strcasecmp(argv[2], "setindirect")) {
+ struct wctdm_regop regop;
+ int val;
+ int reg;
+ if ((argc < 5) || (sscanf(argv[3], "%i", ®) != 1) ||
+ (sscanf(argv[4], "%i", &val) != 1)) {
+ fprintf(stderr, "Need a register and value...\n");
+ } else {
+ regop.reg = reg;
+ regop.val = val;
+ if (!strcasecmp(argv[2], "setindirect")) {
+ regop.indirect = 1;
+ } else {
+ regop.indirect = 0;
+ }
+ res = ioctl(fd, WCTDM_SET_REG, ®op);
+ if (res)
+ fprintf(stderr, "Unable to get registers on channel %s\n", argv[1]);
+ else
+ printf("Success.\n");
+ }
+ } else if (!strcasecmp(argv[2], "dtmf")) {
+ int duration = 50; /* default to 50 mS duration */
+ char * outstring = "";
+ int dtmftone;
+
+ if(argc < 4) { /* user supplied string */
+ fprintf(stderr, "You must specify a string of dtmf characters to send\n");
+ } else {
+ outstring = argv[3];
+ if(argc >= 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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define FAST_HDLC_NEED_TABLES
+#include <dahdi/fasthdlc.h>
+
+#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<cnt;x++) {
+ res = fasthdlc_tx_load(&transmitter, buf[x]);
+ if (res < 0) {
+ fprintf(stderr, "Unable to load byte :(\n");
+ exit(1);
+ }
+ while(transmitter.bits >= 8) {
+ outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter);
+ }
+ }
+ flags = (rand() % 4);
+ for (x=0;x<flags;x++) {
+ if (transmitter.bits < 8)
+ fasthdlc_tx_frame(&transmitter);
+ else
+ fprintf(stderr, "Huh? Don't need a frame?\n");
+ outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter);
+ }
+ if (argc > 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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dahdi/user.h>
+
+#define FAST_HDLC_NEED_TABLES
+#include <dahdi/fasthdlc.h>
+
+#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<len;x++)
+ printf("%02x ",buf[x]);
+ printf("}\n");
+}
+
+static int fd;
+static struct fasthdlc_state fs;
+
+void send_packet(unsigned char *buf, int len)
+{
+ int res;
+ int x;
+ unsigned char outbuf[BLOCK_SIZE];
+ int pos=0;
+ unsigned int fcs = PPP_INITFCS;
+ if (hdlcmode)
+ res = write(fd, buf, len + 2);
+ else {
+ for (x=0;x<len;x++) {
+ if (fasthdlc_tx_load(&fs, buf[x]))
+ printf("Load error\n");
+ fcs = PPP_FCS(fcs, buf[x]);
+ outbuf[pos++] = fasthdlc_tx_run(&fs);
+ if (fs.bits > 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] <DAHDI device>\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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dahdi/user.h>
+
+#define FAST_HDLC_NEED_TABLES
+#include <dahdi/fasthdlc.h>
+
+#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 <DAHDI device>\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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define FAST_HDLC_NEED_TABLES
+#include <dahdi/fasthdlc.h>
+
+#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<hdlccnt;x++) {
+ if (actual[x] != decbuf[x]) {
+ fprintf(stderr, "Found discrepancy at offset %d\n", x);
+ exit(1);
+ }
+ }
+ /* Reset message receiver */
+ hdlccnt = 0;
+ }
+ } else if (res & RETURN_DISCARD_FLAG) {
+ if (1 || hdlccnt) {
+ fprintf(stderr, "Detected abort :(\n");
+ exit(1);
+ }
+ } else {
+ decbuf[hdlccnt++] = res;
+ }
+ }
+}
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..58edec5
--- /dev/null
+++ b/init.conf.sample
@@ -0,0 +1,19 @@
+#
+# 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
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..9d01d76
--- /dev/null
+++ b/makeopts.in
@@ -0,0 +1,47 @@
+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@
+
+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..96053b3
--- /dev/null
+++ b/modules.sample
@@ -0,0 +1,48 @@
+# 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 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 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
+
+# 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..e816dd9
--- /dev/null
+++ b/patgen.c
@@ -0,0 +1,164 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "bittest.h"
+
+#include <dahdi/user.h>
+#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 <dahdi_chan>\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<len;x++)
+ printf("%02x ",buf[x]);
+ printf("}\n");
+}
+
+int channel_open(char *name, int *bs)
+{
+ int channo;
+ int fd;
+ struct dahdi_params tp;
+ char *dev;
+
+ channo = atoi(name);
+ /* channo==0: The user passed a file name to be opened. */
+ dev = channo ? DEVICE : name;
+
+ fd = open(dev, O_RDWR, 0600);
+
+ if (fd < 0) {
+ perror(DEVICE);
+ return -1;
+ }
+
+ /* If we got a channel number, get it from /dev/dahdi/channel: */
+ if(channo && ioctl(fd, DAHDI_SPECIFY, &channo) < 0) {
+ perror("SPECIFY");
+ 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<bs;x++) {
+ outbuf[x] = c;
+ c = bit_next(c);
+ }
+ res1 = write(fd, outbuf, res);
+ if (res1 < res) {
+ 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 0
+ printf("(%d) Wrote %d bytes\n", packets++, res);
+#endif
+ }
+
+}
diff --git a/patlooptest.c b/patlooptest.c
new file mode 100644
index 0000000..4be399c
--- /dev/null
+++ b/patlooptest.c
@@ -0,0 +1,295 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <dahdi/user.h>
+#include "dahdi_tools_version.h"
+
+#define BLOCK_SIZE 2039
+
+#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<len;x++)
+ printf("%02x ",buf[x]);
+ printf("}\n");
+}
+
+/* Shows data immediately before and after the specified byte to provide context for an error */
+static void show_error_context(unsigned char *buf, int offset, int bufsize)
+{
+ int low;
+ int total = CONTEXT_SIZE;
+
+ if (offset >= 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 <dahdi device> [-t <secs>] [-r <count>] [-b <count>] [-vh?] \n", progname);
+ printf("\t-? - Print this usage summary\n");
+ printf("\t-t <secs> - # of seconds for the test to run\n");
+ printf("\t-r <count> - # of test loops to run before a summary is printed\n");
+ printf("\t-s <count> - # 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 <device name> [<timeout in secs>]\n", progname);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ int res, x;
+ int i;
+ struct dahdi_params tp;
+ 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;
+
+ /* 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 = open(device, O_RDWR, 0600);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open %s: %s\n", device, 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);
+ }
+ 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++;
+ }
+
+ res = write(fd,outbuf,bs);
+ if (res != bs) {
+ printf("Res is %d: %s\n", res, strerror(errno));
+ ioctl(fd, DAHDI_GETEVENT, &x);
+ printf("Event: %d\n", x);
+ exit(1);
+ }
+
+ /* 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");
+ }
+ continue;
+ }
+
+ res = read(fd, inbuf, bs);
+ if (res < bs) {
+ printf("read error: returned %d\n", res);
+ exit(1);
+ }
+ /* 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..7e33a5c
--- /dev/null
+++ b/pattest.c
@@ -0,0 +1,170 @@
+/*
+ * Written by Mark Spencer <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "bittest.h"
+
+#include <dahdi/user.h>
+#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 <dahdi_chan>\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<len;x++)
+ printf("%02x ",buf[x]);
+ printf("}\n");
+}
+
+int channel_open(char *name, int *bs)
+{
+ int channo;
+ int fd;
+ struct dahdi_params tp;
+ char *dev;
+
+ channo = atoi(name);
+ /* channo==0: The user passed a file name to be opened. */
+ dev = channo ? DEVICE : name;
+
+ fd = open(dev, O_RDWR, 0600);
+
+ if (fd < 0) {
+ perror(DEVICE);
+ return -1;
+ }
+
+ /* If we got a channel number, get it from /dev/dahdi/channel: */
+ if(channo && ioctl(fd, DAHDI_SPECIFY, &channo) < 0) {
+ perror("SPECIFY");
+ 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<bs;x++) {
+ if (outbuf[x] != c) {
+ printf("(Error %d): Unexpected result, %d != %d, %d bytes since last error.\n", ++errors, outbuf[x], c, bytes);
+ c = outbuf[x];
+ bytes=0;
+ }
+ c = bit_next(c);
+ bytes++;
+ }
+#if 0
+ printf("(%d) Wrote %d bytes\n", packets++, res);
+#endif
+ }
+
+}
diff --git a/ppp/Makefile b/ppp/Makefile
new file mode 100644
index 0000000..0ff55c2
--- /dev/null
+++ b/ppp/Makefile
@@ -0,0 +1,29 @@
+#COPTS = -O2 -g
+
+-include ../makeopts
+
+CFLAGS += $(COPTS) -fPIC
+LDFLAGS += -shared
+
+INCLUDE_DIR = $(includedir)/pppd
+
+LIBDIR = $(libdir)/pppd/$(PPPD_VERSION)
+
+PLUGINS := dahdi.so
+
+all: $(PLUGINS)
+
+%.so: %.c
+ifeq (,$(PPPD_VERSION))
+ @echo "pppd version not found (in patchlevel.h)."
+ @echo "Install ppp source/headers and/or ./configure --with-ppp=PATH."
+ exit 1
+endif
+ $(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS)
+
+install: $(PLUGINS)
+ $(INSTALL) -d $(DESTDIR)$(LIBDIR)
+ $(INSTALL) -m 0644 $? $(DESTDIR)$(LIBDIR)
+
+clean:
+ rm -f *.o *.so *.a
diff --git a/ppp/dahdi.c b/ppp/dahdi.c
new file mode 100644
index 0000000..6991ccf
--- /dev/null
+++ b/ppp/dahdi.c
@@ -0,0 +1,293 @@
+/* dahdi.c - pppd plugin to implement PPP over DAHDI HDLC channel.
+ *
+ * Copyright 2002 Digium, Inc.
+ * Mark Spencer <markster at digium.inc>
+ *
+ * Borrows from PPPoE by Michal Ostrowski <mostrows at styx.uwaterloo.ca>,
+ * Jamal Hadi Salim <hadi at cyberus.ca>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <pppd/pppd.h>
+#include <pppd/fsm.h>
+#include <pppd/lcp.h>
+#include <pppd/ipcp.h>
+#include <pppd/ccp.h>
+#include <pppd/pathnames.h>
+
+#include <dahdi/user.h>
+
+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 : "<stdin>");
+ }
+
+ 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 <khc at pm.waw.pl>
+ *
+ */
+
+/*
+ * 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 <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <asm/types.h>
+#include <linux/hdlc.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <linux/sockios.h>
+
+#include <dahdi/user.h>
+#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 <khc at pm.waw.pl>\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/system.conf.sample b/system.conf.sample
new file mode 100644
index 0000000..ff6e3b9
--- /dev/null
+++ b/system.conf.sample
@@ -0,0 +1,330 @@
+#
+# DAHDI Configuration File
+#
+# This file is parsed by the DAHDI Configurator, dahdi_cfg
+#
+# Span Configuration
+# ^^^^^^^^^^^^^^^^^^
+# First come the span definitions, in the format
+#
+# span=<span num>,<timing source>,<line build out (LBO)>,<framing>,<coding>[,yellow]
+#
+# All T1/E1/BRI spans generate a clock signal on their transmit side. The
+# <timing source> 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.
+#
+# 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=<driver>,<address>,<numchans>,<timing>
+#
+# Where <driver> is the name of the driver (e.g. eth), <address> is the
+# driver specific address (like a MAC for eth), <numchans> is the number
+# of channels, and <timing> 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:
+# <device>=<channel list>
+#
+# 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.
+# sf::
+# Channel(s) are signalled using in-band single freq tone.
+# Syntax as follows:
+#
+# channel# => sf:<rxfreq>,<rxbw>,<rxflag>,<txfreq>,<txlevel>,<txflag>
+#
+# rxfreq is rx tone freq in Hz, rxbw is rx notch (and decode)
+# bandwith in hz (typically 10.0), rxflag is either 'normal' or
+# 'inverted', txfreq is tx tone freq in hz, txlevel is tx tone
+# level in dbm, txflag is either 'normal' or 'inverted'. Set
+# rxfreq or txfreq to 0.0 if that tone is not desired.
+#
+# 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=<channel list>[: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=<zone>" where the zone is a two letter country code.
+#
+# You may also specify a default zone with "defaultzone=<zone>" 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 if you do
+# not have hardware echo cancellers and need echo cancellation.
+#
+# Valid echo cancellers are: mg2, kb1, sec2, and sec.
+# If compiled, 'hpec' is also a valid echo canceller.
+#
+# To configure the default echo cancellers, use the format:
+# echocanceller=<echocanceller name>,<channel(s)>
+#
+# 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 <markster at digium.com>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001-2008 Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ * Radio Support by Jim Dixon <jim at lambdatel.com>
+ */
+
+/*
+ * 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 <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include <dahdi/user.h>
+#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..afdec99
--- /dev/null
+++ b/tonezone.c
@@ -0,0 +1,518 @@
+/*
+ * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * Working with the "Tormenta ISA" Card
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ *
+ */
+
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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 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", &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 = 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 <markster at digium.com>
+ *
+ */
+
+/*
+ * 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 <dahdi/user.h>
+
+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 at 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 <stdint.h>
+
+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..38b5956
--- /dev/null
+++ b/xpp/Makefile
@@ -0,0 +1,140 @@
+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
+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)
+
+
+CFLAGS += -g -Wall $(USB_INCLUDE)
+
+%.8: %
+ pod2man --section 8 $^ > $@ || $(RM) $@
+PERL_SCRIPTS = \
+ dahdi_registration \
+ xpp_sync \
+ lsdahdi \
+ xpp_blink \
+ dahdi_genconf \
+ dahdi_hardware \
+ twinstar \
+ #
+
+PERL_MANS = $(PERL_SCRIPTS:%=%.8)
+
+ABHEXLOAD_OBJS = astribank_hexload.o hexfile.o pic_loader.o astribank_usb.o mpp_funcs.o debug.o
+ABTOOL_OBJS = astribank_tool.o astribank_usb.o mpp_funcs.o debug.o
+ABALLOW_OBJS = astribank_allow.o astribank_usb.o mpp_funcs.o debug.o
+
+TARGETS = .perlcheck astribank_is_starting
+PROG_INSTALL = astribank_is_starting
+MAN_INSTALL = $(PROG_INSTALL:%=%.8)
+ifeq (1,$(PBX_USB))
+TARGETS += fpga_load \
+ astribank_tool \
+ astribank_hexload \
+ astribank_allow \
+ test_parse
+PROG_INSTALL += fpga_load 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)$(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
+
+fpga_load: fpga_load.o hexfile.o
+fpga_load: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
+
+astribank_hexload: $(ABHEXLOAD_OBJS)
+astribank_hexload: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
+
+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)
+
+fpga_load.o: CFLAGS+=-D_GNU_SOURCE # We use memrchr()
+
+test_parse: test_parse.o hexfile.o
+test_parse: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
+
+%: %.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 *.o $(TARGETS)
+
+.PHONY: depend
+depend: .depend
+.depend: *.c *.h
+ @$(CC) -MM *.c > $@ || rm -f $@
+
+include .depend
diff --git a/xpp/README.Astribank b/xpp/README.Astribank
new file mode 100644
index 0000000..cd46144
--- /dev/null
+++ b/xpp/README.Astribank
@@ -0,0 +1,1656 @@
+Xorcom Astribank Documentation
+==============================
+Xorcom Team <support at xorcom.com>
+$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 fpga_load firmware loader. This is
+typically the package libusb-dev on Debian (and derivatives like Ubuntu)
+or libusb-devel on RedHat (and derivatives like CentOS/Trixbox).
+
+Patch for BRI
+~~~~~~~~~~~~~
+(As of DAHDI 2.2 this patch is no longer needed. Furthermore, it does
+not apply. The same directory has a newer patch that applies. This
+section is kept in the document for the time being for the benefit of
+those with older versions)
+
+In order for the BRI module (xpd_bri.ko) to build, you still need an
+external patch:
+
+http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff[]
+
+You need to apply it to the dahdi-linux tarball before building:
+
+ wget http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff
+ patch -p1 <dahdi_bri_dchan.diff
+
+
+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
+ fpga_load. 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 'load module 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
+fpga_load) 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 fpga_load,
+which is 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
+ # 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
+
+With older USB firmwares (before the one included in e.g. dahdi-linux
+2.2) you needed to use instead of all the above:
+
+ # pick the right name according to the device ID. FPGA_1151.hex is for
+ # 115x Astribanks:
+ fpga_load -D /dev/bus/usb/MMM/NNN -I /usr/share/dahdi/FPGA_1151.hex
+
+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.
+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:
+
+<number>::
+ Make the Astribank XBUS-<number> 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>:<module>:<subunit>
+
+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
+<module><subunit>.
+
+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..0fd48cc
--- /dev/null
+++ b/xpp/astribank_allow.8
@@ -0,0 +1,70 @@
+.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. On modern UDEV-based system
+this is usually /dev/bus/usb/\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).
+On older systems that use usbfs, it is usually
+/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 \-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..b87f6fa
--- /dev/null
+++ b/xpp/astribank_allow.c
@@ -0,0 +1,384 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il> and
+ * Alex Landau <alex.landau at xorcom.com>
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <time.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include "mpp.h"
+#include "mpp_funcs.h"
+#include "debug.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}/<bus>/<dev> 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");
+ 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;
+}
+
+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;
+}
+
+static int write_to_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *key, FILE *f)
+{
+ fprintf(f, "-----BEGIN XORCOM LICENSE BLOCK-----\n");
+ 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.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, "-----END XORCOM LICENSE BLOCK-----\n");
+ 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.
+ */
+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;
+}
+
+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;
+}
+
+static int read_from_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *capkey, FILE *f)
+{
+ char buf[256];
+ char *line, *key, *value;
+ int state = 0;
+ int lineno = 0;
+ struct table {
+ struct eeprom_table eeprom_table;
+ struct capabilities capabilities;
+ struct capkey capkey;
+ } PACKED table;
+
+ 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 > 0 && state < 4) {
+ ERR("Line %d: Empty line\n", lineno);
+ return -1;
+ }
+ else
+ continue;
+ }
+ switch (state) {
+ case 0:
+ if (strcmp(line, "-----BEGIN XORCOM LICENSE BLOCK-----") == 0)
+ state = 1;
+ else {
+ ERR("Line %d: Invalid license begin block\n", lineno);
+ return -1;
+ }
+ break;
+ case 1:
+ 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 = 2;
+ } 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 2:
+ 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 = 3;
+ break;
+ }
+ break;
+ case 3:
+ if (strcmp(line, "-----END XORCOM LICENSE BLOCK-----") == 0) {
+ state = 4;
+ break;
+ }
+ if (str_to_bin(line, &table, sizeof(table)) < 0) {
+ ERR("Line %d: Error in data block\n", lineno);
+ return -1;
+ }
+ break;
+ case 4:
+ break;
+
+ }
+ }
+ if (state != 4) {
+ 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;
+}
+
+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:";
+ int do_write = 0;
+ 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 '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)) == 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) {
+ /* 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, 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, 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..6808927
--- /dev/null
+++ b/xpp/astribank_hexload.8
@@ -0,0 +1,66 @@
+.TH "ASTRIBANK_HEXLOAD" "8" "29 March 2009" "" ""
+
+.SH NAME
+astribank_tool \- Xorcom Astribank (xpp) firmware loader
+.SH SYNOPSIS
+.B astribank_tool \-D \fIdevice-path\fR <\fB\-F|\-p\fR> [\fIoptions\fR] \fIhexfile\fR
+
+.B astribank_tool [\-h]
+
+.SH DESCRIPTION
+.B astribank_hexload
+is a second-stage firmware loader for Xorcom Astribanks. Note that some
+older models use fpga_load(8) instead.
+
+It 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. On modern UDEV-based system
+this is usually /dev/bus/usb/\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).
+On older systems that use usbfs, it is usually
+/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
+.RE
+
+.B \-F
+.RS
+The firmware to load is a FPGA firmware.
+.RE
+
+.B \-p
+.RS
+The firmware to load is a PIC firmware.
+.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_tool(8), fpga_load(8)
+
+.SH AUTHOR
+This manual page was written by Tzafrir Cohen <tzafrir.cohen at xorcom.com> .
+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..b268e5d
--- /dev/null
+++ b/xpp/astribank_hexload.c
@@ -0,0 +1,229 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include "debug.h"
+#include "hexfile.h"
+#include "mpp_funcs.h"
+#include "pic_loader.h"
+#include "astribank_usb.h"
+
+#define DBG_MASK 0x80
+#define MAX_HEX_LINES 10000
+
+static char *progname;
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> hexfile...\n", progname);
+ fprintf(stderr, "\tOptions: {-F|-p}\n");
+ fprintf(stderr, "\t\t[-E] # Burn to EEPROM\n");
+ 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[-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;
+}
+
+static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest)
+{
+ struct hexdata *hexdata = NULL;
+ int finished = 0;
+ int ret;
+ int i;
+ char star[] = "+\\+|+/+-";
+
+ if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
+ perror(hexfile);
+ return -errno;
+ }
+ INFO("Loading hexfile to %s: %s (version %s)\n",
+ dev_dest2str(dest),
+ hexdata->fname, hexdata->version_info);
+#if 0
+ FILE *fp;
+ if((fp = fopen("fpga_dump_new.txt", "w")) == NULL) {
+ perror("dump");
+ exit(1);
+ }
+#endif
+ if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) {
+ ERR("Failed hexfile send start: %d\n", 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("Extra data after End Of Data Record (line %d)\n", 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("Failed hexfile sending in lineno %d (ret=%d)\n", i, ret);;
+ return ret;
+ }
+ }
+ if(verbose > LOG_INFO) {
+ putchar('\n');
+ fflush(stdout);
+ }
+ if((ret = mpp_send_end(astribank)) < 0) {
+ ERR("Failed hexfile send end: %d\n", 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;
+ struct astribank_device *astribank;
+ int opt_pic = 0;
+ int opt_dest = 0;
+ enum dev_dest dest = DEST_NONE;
+ const char options[] = "vd:D:EFp";
+ 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 = 1;
+ dest = DEST_EEPROM;
+ break;
+ case 'F':
+ if(dest != DEST_NONE) {
+ ERR("The -F and -E options are mutually exclusive.\n");
+ usage();
+ }
+ opt_dest = 1;
+ dest = DEST_FPGA;
+ break;
+ 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();
+ }
+ }
+ if((opt_dest ^ opt_pic) == 0) {
+ ERR("The -F, -E and -p options are mutually exclusive.\n");
+ usage();
+ }
+ iface_num = (opt_dest) ? 1 : 0;
+ if(!opt_pic) {
+ 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();
+ }
+ if((astribank = astribank_open(devpath, iface_num)) == NULL) {
+ ERR("Opening astribank failed\n");
+ return 1;
+ }
+ show_astribank_info(astribank);
+ if(opt_dest) {
+ if(load_hexfile(astribank, argv[optind], dest) < 0) {
+ ERR("Loading firmware to %s failed\n", dev_dest2str(dest));
+ return 1;
+ }
+ } else if(opt_pic) {
+ if((ret = load_pic(astribank, argc - optind, argv + optind)) < 0) {
+ ERR("Loading PIC's failed\n");
+ return 1;
+ }
+ }
+ astribank_close(astribank, 0);
+ return 0;
+}
diff --git a/xpp/astribank_hook b/xpp/astribank_hook
new file mode 100755
index 0000000..ae38635
--- /dev/null
+++ b/xpp/astribank_hook
@@ -0,0 +1,114 @@
+#! /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
+
+[ -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
+
+export XPPORDER_CONF="$dahdi_conf/xpp_order"
+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
+export DAHDI_CFG_CMD="dahdi_cfg -c $dahdi_conf/system.conf"
+export CALLED_FROM_ATRIBANK_HOOK=yes
+
+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
+}
+
+NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l`
+NUM_GOOD=`matched_devices | wc -l`
+
+start_dahdi() {
+ script=/etc/init.d/dahdi
+ if [ "$XPP_HOTPLUG_DAHDI" = yes ]; then
+ echo "Starting $script."
+ "$script" start | logger -i -t "$script"
+ status=$?
+ echo "Status($script): $status"
+ else
+ echo "$0: Skip($script): No XPP_HOTPLUG_DAHDI=yes in /etc/dahdi/init.conf"
+ exit 0
+ fi
+ if [ -x "$dir/twinstar_hook" ]; then
+ "$dir/twinstar_hook"
+ fi
+ # Finished astribanks
+ echo "Removing semaphore"
+ astribank_is_starting -v -r
+}
+
+case "$ACTION" in
+add)
+ ;;
+remove)
+ ;;
+online)
+ echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER
+ if [ "$NUM_GOOD" -eq "$NUM_WANTED" ]; then
+ echo "START-DAHDI: Total $NUM_GOOD online." | $LOGGER
+ # Fork services
+ start_dahdi < /dev/null 2>&1 | $LOGGER &
+ fi
+ ;;
+offline)
+ 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
+ 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 <tzafrir.cohen at xorcom.com> .
+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..2ae1f73
--- /dev/null
+++ b/xpp/astribank_is_starting.c
@@ -0,0 +1,190 @@
+#include "../autoconfig.h"
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static char *progname;
+static const key_t key_astribanks = 0xAB11A0;
+static int debug;
+static int verbose;
+static int timeout_seconds = 60;
+
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: %s [-d] [-t <seconds>] [-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);
+ 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_tool.8 b/xpp/astribank_tool.8
new file mode 100644
index 0000000..d685470
--- /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. On modern UDEV-based system
+this is usually /dev/bus/usb/\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).
+On older systems that use usbfs, it is usually
+/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 <tzafrir.cohen at xorcom.com> .
+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..59ae94c
--- /dev/null
+++ b/xpp/astribank_tool.c
@@ -0,0 +1,274 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include "mpp_funcs.h"
+#include "debug.h"
+
+#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}/<bus>/<dev> [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)
+{
+ uint8_t unit;
+ uint8_t card_status;
+ uint8_t card_type;
+ 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)) {
+ for(unit = 0; unit < 4; 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 = 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 = send_usb(astribank, 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)) == 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 <oron at actcom.co.il>
+# 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 <firmware_directory>"
+ 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..dce3d47
--- /dev/null
+++ b/xpp/astribank_usb.c
@@ -0,0 +1,555 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <arpa/inet.h>
+#include "astribank_usb.h"
+#include "debug.h"
+
+static const char rcsid[] = "$Id$";
+
+#define DBG_MASK 0x01
+#define TIMEOUT 500
+
+#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \
+ [t] = { \
+ .type_code = (t), \
+ .num_interfaces = (ni), \
+ .my_interface_num = (n), \
+ .num_endpoints = (ne), \
+ .my_ep_in = (in), \
+ .my_ep_out = (out), \
+ .name = #t, \
+ .endpoints = { __VA_ARGS__ }, \
+ }
+
+static const struct interface_type interface_types[] = {
+ TYPE_ENTRY(USB_11xx, 1, 0, 4, MP_EP_OUT, MP_EP_IN,
+ XPP_EP_OUT,
+ MP_EP_OUT,
+ XPP_EP_IN,
+ MP_EP_IN),
+ TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MP_EP_OUT, MP_EP_IN,
+ MP_EP_OUT,
+ MP_EP_IN),
+ TYPE_ENTRY(USB_PIC, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN,
+ XPP_EP_OUT,
+ XPP_EP_IN),
+
+};
+#undef TYPE_ENTRY
+
+//static int verbose = LOG_DEBUG;
+
+/*
+ * USB handling
+ */
+
+/* return 1 if:
+ * - str has a number
+ * - It is larger than 0
+ * - It equals num
+ */
+static int num_matches(int num, const char* str) {
+ int str_val = atoi(str);
+ if (str_val <= 0)
+ return 0;
+ return (str_val == num);
+}
+
+struct usb_device *dev_of_path(const char *path)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ char dirname[PATH_MAX];
+ char filename[PATH_MAX];
+ const char *p;
+ int bnum;
+ int dnum;
+ int ret;
+
+ assert(path != NULL);
+ if(access(path, F_OK) < 0) {
+ perror(path);
+ return NULL;
+ }
+ /* Find last '/' */
+ if((p = memrchr(path, '/', strlen(path))) == NULL) {
+ ERR("Missing a '/' in %s\n", path);
+ return NULL;
+ }
+ /* Get the device number */
+ ret = sscanf(p + 1, "%d", &dnum);
+ if(ret != 1) {
+ ERR("Path tail is not a device number: '%s'\n", p);
+ return NULL;
+ }
+ /* Search for a '/' before that */
+ p = memrchr(path, '/', p - path);
+ if(p == NULL)
+ p = path; /* Relative path */
+ else
+ p++; /* skip '/' */
+ /* Get the bus number */
+ ret = sscanf(p, "%d", &bnum);
+ if(ret != 1) {
+ ERR("Path tail is not a bus number: '%s'\n", p);
+ return NULL;
+ }
+ sprintf(dirname, "%03d", bnum);
+ sprintf(filename, "%03d", dnum);
+ for (bus = usb_busses; bus; bus = bus->next) {
+ if (! num_matches(bnum, bus->dirname))
+ //if(strcmp(bus->dirname, dirname) != 0)
+ continue;
+ for (dev = bus->devices; dev; dev = dev->next) {
+ //if(strcmp(dev->filename, filename) == 0)
+ if (num_matches(dnum, dev->filename))
+ return dev;
+ }
+ }
+ ERR("no usb device match '%s'\n", path);
+ return NULL;
+}
+
+int get_usb_string(struct astribank_device *astribank, uint8_t item, char *buf, unsigned int len)
+{
+ char tmp[BUFSIZ];
+ int ret;
+
+ assert(astribank->handle);
+ if (!item)
+ return 0;
+ ret = usb_get_string_simple(astribank->handle, item, tmp, BUFSIZ);
+ if (ret <= 0)
+ return ret;
+ return snprintf(buf, len, "%s", tmp);
+}
+
+static int match_interface(const struct astribank_device *astribank,
+ const struct interface_type *itype)
+{
+ struct usb_interface *interface;
+ struct usb_interface_descriptor *iface_desc;
+ struct usb_config_descriptor *config_desc;
+ int i = itype - interface_types;
+ int inum;
+ int num_altsetting;
+
+ DBG("Checking[%d]: interfaces=%d interface num=%d endpoints=%d: \"%s\"\n",
+ i,
+ itype->num_interfaces,
+ itype->my_interface_num,
+ itype->num_endpoints,
+ itype->name);
+ config_desc = astribank->dev->config;
+ if (!config_desc) {
+ ERR("No configuration descriptor: strange USB1 controller?\n");
+ return 0;
+ }
+ if(config_desc->bNumInterfaces <= itype->my_interface_num) {
+ DBG("Too little interfaces: have %d need %d\n",
+ config_desc->bNumInterfaces, itype->my_interface_num + 1);
+ return 0;
+ }
+ if(astribank->my_interface_num != itype->my_interface_num) {
+ DBG("Wrong match -- not my interface num (wanted %d)\n", astribank->my_interface_num);
+ return 0;
+ }
+ inum = itype->my_interface_num;
+ interface = &config_desc->interface[inum];
+ assert(interface != NULL);
+ iface_desc = interface->altsetting;
+ num_altsetting = interface->num_altsetting;
+ assert(num_altsetting != 0);
+ assert(iface_desc != NULL);
+ if(iface_desc->bInterfaceClass != 0xFF) {
+ DBG("Bad interface class 0x%X\n", iface_desc->bInterfaceClass);
+ return 0;
+ }
+ if(iface_desc->bInterfaceNumber != itype->my_interface_num) {
+ DBG("Bad interface number %d\n", iface_desc->bInterfaceNumber);
+ return 0;
+ }
+ if(iface_desc->bNumEndpoints != itype->num_endpoints) {
+ DBG("Different number of endpoints %d\n", iface_desc->bNumEndpoints);
+ return 0;
+ }
+ return 1;
+}
+
+static int astribank_init(struct astribank_device *astribank)
+{
+ 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;
+ const struct interface_type *fwtype;
+ int i;
+
+ assert(astribank);
+ astribank->handle = usb_open(astribank->dev);
+ if(!astribank->handle) {
+ ERR("Failed to open usb device '%s/%s': %s\n",
+ astribank->dev->bus->dirname, astribank->dev->filename, usb_strerror());
+ return 0;
+ }
+ fwtype = astribank->fwtype;
+ if(usb_claim_interface(astribank->handle, fwtype->my_interface_num) != 0) {
+ ERR("usb_claim_interface: %s\n", usb_strerror());
+ return 0;
+ }
+ dev_desc = &astribank->dev->descriptor;
+ config_desc = astribank->dev->config;
+ if (!config_desc) {
+ ERR("usb interface without a configuration\n");
+ return 0;
+ }
+ DBG("Got config_desc. Looking for interface %d\n", fwtype->my_interface_num);
+ interface = &config_desc->interface[fwtype->my_interface_num];
+ iface_desc = interface->altsetting;
+ endpoint = iface_desc->endpoint;
+ astribank->is_usb2 = (endpoint->wMaxPacketSize == 512);
+ for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) {
+ DBG("Validating endpoint @ %d (interface %d)\n", i, fwtype->my_interface_num);
+ if(endpoint->bEndpointAddress != fwtype->endpoints[i]) {
+ ERR("Wrong endpoint 0x%X != 0x%X (at index %d)\n",
+ endpoint->bEndpointAddress,
+ fwtype->endpoints[i],
+ i);
+ return 0;
+ }
+ if(endpoint->bEndpointAddress == MP_EP_OUT || endpoint->bEndpointAddress == MP_EP_IN) {
+ if(endpoint->wMaxPacketSize > PACKET_SIZE) {
+ ERR("Endpoint #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize);
+ return 0;
+ }
+ }
+ }
+ astribank->my_ep_in = fwtype->my_ep_in;
+ astribank->my_ep_out = fwtype->my_ep_out;
+ if(get_usb_string(astribank, dev_desc->iManufacturer, astribank->iManufacturer, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, dev_desc->iProduct, astribank->iProduct, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, dev_desc->iSerialNumber, astribank->iSerialNumber, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, iface_desc->iInterface, astribank->iInterface, BUFSIZ) < 0)
+ return 0;
+ DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n",
+ dev_desc->idVendor,
+ dev_desc->idProduct,
+ astribank->iManufacturer,
+ astribank->iProduct,
+ astribank->iSerialNumber,
+ astribank->iInterface);
+ if(usb_clear_halt(astribank->handle, astribank->my_ep_out) != 0) {
+ ERR("Clearing output endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if(usb_clear_halt(astribank->handle, astribank->my_ep_in) != 0) {
+ ERR("Clearing input endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if((i = flush_read(astribank)) < 0) {
+ ERR("flush_read failed: %d\n", i);
+ return 0;
+ }
+ return 1;
+}
+
+struct astribank_device *astribank_open(const char devpath[], int iface_num)
+{
+ struct astribank_device *astribank;
+ int i;
+
+ DBG("devpath='%s' iface_num=%d\n", devpath, iface_num);
+ if((astribank = malloc(sizeof(*astribank))) == NULL) {
+ ERR("Out of memory");
+ return NULL;
+ }
+ memset(astribank, 0, sizeof(*astribank));
+ astribank->my_interface_num = iface_num;
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ astribank->dev = dev_of_path(devpath);
+ if(!astribank->dev) {
+ ERR("Bailing out\n");
+ goto fail;
+ }
+ DBG("Scan interface types (astribank has %d interfaces)\n", astribank->dev->config->bNumInterfaces);
+ for(i = 0; i < sizeof(interface_types)/sizeof(interface_types[0]); i++) {
+ if(match_interface(astribank, &interface_types[i])) {
+ DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n",
+ i,
+ interface_types[i].num_interfaces,
+ interface_types[i].num_endpoints,
+ interface_types[i].name);
+ astribank->fwtype = &interface_types[i];
+ goto found;
+ }
+ }
+ ERR("Didn't find suitable device\n");
+fail:
+ free(astribank);
+ return NULL;
+found:
+ if(!astribank_init(astribank))
+ goto fail;
+ astribank->tx_sequenceno = 1;
+ return astribank;
+}
+
+/*
+ * MP device handling
+ */
+void show_astribank_info(const struct astribank_device *astribank)
+{
+ struct usb_device_descriptor *dev_desc;
+ struct usb_device *dev;
+
+ assert(astribank != NULL);
+ dev = astribank->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,
+ astribank->iManufacturer,
+ astribank->iProduct,
+ astribank->iSerialNumber);
+ } else {
+ printf("USB Bus/Device: [%s/%s]\n", dev->bus->dirname, dev->filename);
+ printf("USB Firmware Type: [%s]\n", astribank->fwtype->name);
+ printf("USB iManufacturer: [%s]\n", astribank->iManufacturer);
+ printf("USB iProduct: [%s]\n", astribank->iProduct);
+ printf("USB iSerialNumber: [%s]\n", astribank->iSerialNumber);
+ }
+}
+
+void astribank_close(struct astribank_device *astribank, int disconnected)
+{
+ assert(astribank != NULL);
+ if(!astribank->handle)
+ return; /* Nothing to do */
+ if(!disconnected) {
+ if(usb_release_interface(astribank->handle, astribank->fwtype->my_interface_num) != 0) {
+ ERR("Releasing interface: usb: %s\n", usb_strerror());
+ }
+ }
+ if(usb_close(astribank->handle) != 0) {
+ ERR("Closing device: usb: %s\n", usb_strerror());
+ }
+ astribank->tx_sequenceno = 0;
+ astribank->handle = NULL;
+}
+
+int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout)
+{
+ int ret;
+
+ dump_packet(LOG_DEBUG, __FUNCTION__, buf, len);
+ if(astribank->my_ep_out & USB_ENDPOINT_IN) {
+ ERR("send_usb called with an input endpoint 0x%x\n", astribank->my_ep_out);
+ return -EINVAL;
+ }
+ ret = usb_bulk_write(astribank->handle, astribank->my_ep_out, 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",
+ astribank->my_ep_out, ret, usb_strerror());
+ dump_packet(LOG_ERR, "send_usb[ERR]", buf, len);
+ exit(2);
+ } else {
+ DBG("bulk_write to endpoint 0x%x got ENODEV\n", astribank->my_ep_out);
+ astribank_close(astribank, 1);
+ }
+ return ret;
+ } else if(ret != len) {
+ ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n",
+ astribank->my_ep_out, ret, usb_strerror());
+ dump_packet(LOG_ERR, "send_usb[ERR]", buf, len);
+ return -EFAULT;
+ }
+ return ret;
+}
+
+int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout)
+{
+ int ret;
+
+ if(astribank->my_ep_in & USB_ENDPOINT_OUT) {
+ ERR("recv_usb called with an output endpoint 0x%x\n", astribank->my_ep_in);
+ return -EINVAL;
+ }
+ ret = usb_bulk_read(astribank->handle, astribank->my_ep_in, buf, len, timeout);
+ if(ret < 0) {
+ DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n",
+ astribank->my_ep_in, ret, usb_strerror());
+ memset(buf, 0, len);
+ return ret;
+ }
+ dump_packet(LOG_DEBUG, __FUNCTION__, buf, ret);
+ return ret;
+}
+
+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, __FUNCTION__, tmpbuf, ret);
+ }
+ return 0;
+}
+
+
+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)
+{
+ struct usb_device_descriptor *dev_desc;
+ uint16_t product_series;
+
+ assert(astribank != NULL);
+ dev_desc = &astribank->dev->descriptor;
+ product_series = dev_desc->idProduct;
+ 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..b3b4d79
--- /dev/null
+++ b/xpp/astribank_usb.h
@@ -0,0 +1,103 @@
+#ifndef ASTRIBANK_USB_H
+#define ASTRIBANK_USB_H
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <stdio.h>
+#include <usb.h>
+#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 usb_device *dev;
+ usb_dev_handle *handle;
+ int my_interface_num;
+ int my_ep_out;
+ int my_ep_in;
+ char iManufacturer[BUFSIZ];
+ char iProduct[BUFSIZ];
+ char iSerialNumber[BUFSIZ];
+ 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;
+ const struct interface_type *fwtype;
+ 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);
+
+#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 <tzafrir.cohen at xorcom.com>
+# 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 = '<Default>';
+
+my $style=<<END;
+<!--
+body {
+ margin-left: 0em;
+ margin-right: 5em;
+ //color: navy;
+ background-color: #white;
+}
+
+dfn {
+ font-style: italic;
+ text-decoration: underline;
+}
+
+#content {
+ margin-left: 10em;
+}
+
+h1, h2, h3 {
+ color: #d03;
+ margin-top: 2ex;
+}
+
+h1 {
+ text-align: center;
+ color: #d03;
+ background-color: #ccc;
+ margin-left:5em;
+}
+/*
+li:hover {
+ background-color: #44c;
+}
+
+li li:hover {
+ background-color: #448;
+}
+*/
+/*li.status-ok */
+.status-noconf {background-color: red; }
+.status-notused {background-color: pink; }
+
+#toc {
+ position: fixed;
+ width: 9em;
+ top: 3ex;
+ bottom: 0pt;
+ height: 100%;
+ margins-left: 1em;
+ color: #448;
+
+}
+
+#toc p {
+ display: block;
+ //text-align: center;
+ height: 3ex;
+}
+
+#toc a {
+ text-decoration: none;
+ /*
+ background-color: #F0FFF0;
+ */
+ font-weight: bold;
+ display: block;
+ padding: 0.2em;
+ width: 80%;
+ margin-bottom: 0.2ex;
+ border-top: 1px solid #8bd;
+ color: #8bd;
+ text-align: right;
+}
+
+-->
+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..49b9325
--- /dev/null
+++ b/xpp/dahdi_genconf
@@ -0,0 +1,196 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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::Std;
+use Dahdi;
+use Dahdi::Xpp;
+use Dahdi::Config::Gen;
+use Dahdi::Config::Params;
+
+my $version = '1'; # Functionality version (integer)
+my $revision = '$Revision$';
+
+my %opts;
+
+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->pri_set_fromconfig($gconfig);
+ }
+ }
+}
+
+sub generator_list($) {
+ my $gconfig = shift || die;
+ my @genlist;
+
+ if (@ARGV) {
+ for my $gen (@ARGV) {
+ push @genlist, $gen;
+ }
+ } else {
+ # No files given. Use the defaults.
+ @genlist = ('system', 'chandahdi');
+ if($gconfig->{'pri_connection_type'} eq 'R2') {
+ push @genlist, 'unicall';
+ }
+ }
+ 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);
+ }
+}
+
+getopts('vVF', \%opts) || die "$0: Bad option\n";
+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<GENCONF_PARAMETERS> environment
+variable.
+
+=back
+
+The dahdi_genconf script can generate various kinds of configuration files
+as specificed by the generator arguments. Each generator is a perl classes
+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, chandahdi, unicall, users.
+For further documentation on each, please user perldoc on the relevant
+class. E.g: C<perldoc Dahdi::Config::Gen::Chandahdi>
+
+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 -- print version string and exit.
+
+=item -v
+
+Verbose -- sets the C<'verbose'> option for all generators.
+
+=item -F
+
+Freepbx -- sets the C<'freepbx'> option for all generators.
+Currently, chandahdi is affected.
+
+
+=back
+
+=head2 Implementation notes:
+
+=over 4
+
+=item *
+
+F<genconf_parameters> parsing is done via C<Dahdi::Config::Params>.
+An object representing the parsed data is instanciated by:
+C<Dahdi::Config::Params-E<gt>new()>.
+The C<item()> method of this object contains all the hard coded
+defaults of the configuration directives.
+
+=item *
+
+A configuration object is instanciated by C<Dahdi::Config::Gen-E<gt>new($params)>.
+The mapping of configuration directives into semantic configuration is
+done in the constructor.
+
+=item *
+
+A single generator is run via the the C<run_generator()> method of the
+configuration object.
+
+=back
diff --git a/xpp/dahdi_hardware b/xpp/dahdi_hardware
new file mode 100755
index 0000000..867e897
--- /dev/null
+++ b/xpp/dahdi_hardware
@@ -0,0 +1,196 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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;
+ at 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
+# methood for making it happe:
+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 ouput - 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..87b89f1
--- /dev/null
+++ b/xpp/dahdi_registration
@@ -0,0 +1,166 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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 Getopt::Std;
+
+sub usage {
+ die "Usage: $0 [-s sort_order] [on|off|1|0]\n";
+}
+
+my %opts;
+getopts('s:', \%opts) || usage;
+
+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;
+ }
+}
+
+ at ARGV == 0 or @ARGV == 1 or usage;
+my $on = shift;
+my $verbose = 0;
+my $should_output = 1;
+
+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;
+}
+
+my @spans = Dahdi::spans;
+
+foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) {
+ myprintf "%-10s\t%3s-%s\t%s\n",
+ $xbus->name, $xbus->xpporder, $xbus->label, $xbus->connector;
+ next unless $xbus->status eq 'CONNECTED';
+ foreach my $xpd ($xbus->xpds()) {
+ my $prev = $xpd->dahdi_registration($on);
+ if(!defined($prev)) { # Failure
+ printf "%s: Failed %s\n", $xpd->fqn, $!;
+ next;
+ }
+ myprintf "\t%-10s: ", $xpd->fqn;
+ if(!defined($on)) { # Query only
+ my ($span) = grep { $_->name eq $xpd->fqn } @spans;
+ my $spanstr = ($span) ? ("Span " . $span->num) : "";
+ myprintf "%s %s\n", state2str($prev), $spanstr ;
+ next;
+ }
+ myprintf "%3s ==> %3s\n", state2str($prev), state2str($on);
+ }
+}
+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 [-s sortorder] [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).
+
+=head2 Parameters
+
+off -- deregisters all XPD's from dahdi.
+
+on -- registers all XPD's to dahdi.
+
+=head2 Options
+
+=over
+
+=item -s I<sort_order>
+
+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
diff --git a/xpp/debug.c b/xpp/debug.c
new file mode 100644
index 0000000..b8d3a70
--- /dev/null
+++ b/xpp/debug.c
@@ -0,0 +1,53 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include "debug.h"
+
+int verbose = LOG_INFO;
+int debug_mask = 0;
+
+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, const char *msg, const char *buf, int len)
+{
+ int i;
+
+ 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");
+}
+
diff --git a/xpp/debug.h b/xpp/debug.h
new file mode 100644
index 0000000..185848a
--- /dev/null
+++ b/xpp/debug.h
@@ -0,0 +1,46 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <syslog.h>
+
+/*
+ * 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__, __FUNCTION__, ## 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__, __FUNCTION__, ## arg)
+
+void dump_packet(int loglevel, const char *msg, const char *buf, int len);
+
+#endif /* DEBUG_H */
diff --git a/xpp/fpga_load.8 b/xpp/fpga_load.8
new file mode 100644
index 0000000..dd21db0
--- /dev/null
+++ b/xpp/fpga_load.8
@@ -0,0 +1,86 @@
+.TH "FPGA_LOAD" "8" "16 April 2006" "" ""
+
+.SH NAME
+fpga_load \- Xorcom Astribank (xpp) firmware tool
+.SH SYNOPSIS
+
+.B fpga_load
+[\fB-g\fR] [\fB-r\fR] [\fB-v\fR] \fB-D \fR{/proc/bus/usb|/dev/bus/usb}/\fIBUS/DEV\fR
+
+.B fpga_load
+[\fB-g\fR] [\fB-v\fR] \fB-D \fR{/proc/bus/usb|/dev/bus/usb}/\fIBUS/DEV\fR \fB-I \fIfirmware.hex\fR [\fB-b \fIdump.bin\fR] [\fB-i\fR]
+
+.B fpga_load -h
+
+.SH DESCRIPTION
+.B fpga_load
+loads the FPGA firmware to the Xorcom Astribank device.
+The syntax resembles that of fxload(8).
+
+.SH OPTIONS
+.B -b
+.I dump.bin
+.RS
+Before writing firmware, bump the processed binary file to
+.I dump.bin\fR.
+.RE
+
+.B -D
+.I DEVICE
+.RS
+Required. The device to read from/write to. On modern UDEV-based system
+this is usually /dev/bus/usb/\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).
+On older systems that use usbfs, it is usually
+/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
+.RE
+
+.B -r
+.RS
+Reset the Astribank and renumerate its USB connection to power on product ID.
+.RE
+
+.B -g
+.RS
+Dump all eeprom data to standard output.
+.RE
+
+.B -I
+.I fireware_file
+.RS
+The firmware file to write to the device.
+.RE
+
+.B -i
+.RS
+Show information about the firmware file (valid only with \fB-I\fR option).
+Example:
+.PP
+ ./FPGA_1151.hex: Version=3297 Checksum=58270
+
+In particular, the calculated checksum should match the output of \fIsum(1)\fR
+on the binary firmware file generated by the \fB-b\fR option.
+.RE
+
+.B -v
+.RS
+Increase verbosity. May be used multiple times.
+.RE
+
+.B -h
+.RS
+Displays usage message.
+.RE
+
+.SH SEE ALSO
+fxload(8), lsusb(8)
+
+.SH AUTHOR
+This manual page was written by Tzafrir Cohen <tzafrir.cohen at xorcom.com> .
+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/fpga_load.c b/xpp/fpga_load.c
new file mode 100644
index 0000000..e120b26
--- /dev/null
+++ b/xpp/fpga_load.c
@@ -0,0 +1,1052 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2006-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 <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <usb.h>
+#include "hexfile.h"
+
+static const char rcsid[] = "$Id$";
+
+#define ERR(fmt, arg...) do { \
+ if(verbose >= LOG_ERR) \
+ fprintf(stderr, "%s: ERROR (%d): " fmt, \
+ progname, __LINE__, ## arg); \
+ } while(0);
+#define INFO(fmt, arg...) do { \
+ if(verbose >= LOG_INFO) \
+ fprintf(stderr, "%s: " fmt, \
+ progname, ## arg); \
+ } while(0);
+#define DBG(fmt, arg...) do { \
+ if(verbose >= LOG_DEBUG) \
+ fprintf(stderr, "%s: DBG: " fmt, \
+ progname, ## arg); \
+ } while(0);
+
+static int verbose = LOG_WARNING;
+static char *progname;
+static int disconnected = 0;
+
+#define MAX_HEX_LINES 10000
+#define PACKET_SIZE 512
+#define EEPROM_SIZE 16
+#define LABEL_SIZE 8
+#define TIMEOUT 5000
+
+
+/* My device parameters */
+#define MY_EP_OUT 0x04
+#define MY_EP_IN 0x88
+
+#define FPGA_EP_OUT 0x02
+#define FPGA_EP_IN 0x86
+
+/* USB firmware types */
+#define USB_11xx 0
+#define USB_FIRMWARE_II 1
+
+#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \
+ [t] = { \
+ .type_code = (t), \
+ .num_interfaces = (ni), \
+ .my_interface_num = (n), \
+ .num_endpoints = (ne), \
+ .my_ep_in = (in), \
+ .my_ep_out = (out), \
+ .name = #t, \
+ .endpoints = { __VA_ARGS__ }, \
+ }
+
+static const struct astribank_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 */
+} astribank_types[] = {
+ TYPE_ENTRY(USB_11xx, 1, 0, 4, MY_EP_OUT, MY_EP_IN,
+ FPGA_EP_OUT,
+ MY_EP_OUT,
+ FPGA_EP_IN,
+ MY_EP_IN),
+ TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MY_EP_OUT, MY_EP_IN,
+ MY_EP_OUT,
+ MY_EP_IN),
+};
+#undef TYPE_ENTRY
+
+enum fpga_load_packet_types {
+ PT_STATUS_REPLY = 0x01,
+ PT_DATA_PACKET = 0x01,
+#ifdef XORCOM_INTERNAL
+ PT_EEPROM_SET = 0x04,
+#endif
+ PT_EEPROM_GET = 0x08,
+ PT_RENUMERATE = 0x10,
+ PT_RESET = 0x20,
+ PT_BAD_COMMAND = 0xAA
+};
+
+struct myeeprom {
+ uint8_t source;
+ uint16_t vendor;
+ uint16_t product;
+ uint8_t release_major;
+ uint8_t release_minor;
+ uint8_t reserved;
+ uint8_t label[LABEL_SIZE];
+} PACKED;
+
+struct fpga_packet_header {
+ struct {
+ uint8_t op;
+ } PACKED header;
+ union {
+ struct {
+ uint16_t seq;
+ uint8_t status;
+ } PACKED status_reply;
+ struct {
+ uint16_t seq;
+ uint8_t reserved;
+ uint8_t data[ZERO_SIZE];
+ } PACKED data_packet;
+ struct {
+ struct myeeprom data;
+ } PACKED eeprom_set;
+ struct {
+ struct myeeprom data;
+ } PACKED eeprom_get;
+ } d;
+} PACKED;
+
+enum fpga_load_status {
+ FW_FAIL_RESET = 1,
+ FW_FAIL_TRANS = 2,
+ FW_TRANS_OK = 4,
+ FW_CONFIG_DONE = 8
+};
+
+struct my_usb_device {
+ struct usb_device *dev;
+ usb_dev_handle *handle;
+ int my_interface_num;
+ int my_ep_out;
+ int my_ep_in;
+ char iManufacturer[BUFSIZ];
+ char iProduct[BUFSIZ];
+ char iSerialNumber[BUFSIZ];
+ char iInterface[BUFSIZ];
+ int is_usb2;
+ struct myeeprom eeprom;
+ const struct astribank_type *abtype;
+};
+
+const char *load_status2str(enum fpga_load_status s)
+{
+ switch(s) {
+ case FW_FAIL_RESET: return "FW_FAIL_RESET";
+ case FW_FAIL_TRANS: return "FW_FAIL_TRANS";
+ case FW_TRANS_OK: return "FW_TRANS_OK";
+ case FW_CONFIG_DONE: return "FW_CONFIG_DONE";
+ default: return "UNKNOWN";
+ }
+}
+
+/* return 1 if:
+ * - str has a number
+ * - It is larger than 0
+ * - It equals num
+ */
+int num_matches(int num, const char* str) {
+ int str_val = atoi(str);
+ if (str_val <= 0)
+ return 0;
+ return (str_val == num);
+}
+
+struct usb_device *dev_of_path(const char *path)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ char dirname[PATH_MAX];
+ char filename[PATH_MAX];
+ const char *p;
+ int bnum;
+ int dnum;
+ int ret;
+
+ assert(path != NULL);
+ if(access(path, F_OK) < 0) {
+ perror(path);
+ return NULL;
+ }
+ /* Find last '/' */
+ if((p = (const char *)memrchr(path, '/', strlen(path))) == NULL) {
+ ERR("Missing a '/' in %s\n", path);
+ return NULL;
+ }
+ /* Get the device number */
+ ret = sscanf(p + 1, "%d", &dnum);
+ if(ret != 1) {
+ ERR("Path tail is not a device number: '%s'\n", p);
+ return NULL;
+ }
+ /* Search for a '/' before that */
+ p = (const char *)memrchr(path, '/', p - path);
+ if(p == NULL)
+ p = path; /* Relative path */
+ else
+ p++; /* skip '/' */
+ /* Get the bus number */
+ ret = sscanf(p, "%d", &bnum);
+ if(ret != 1) {
+ ERR("Path tail is not a bus number: '%s'\n", p);
+ return NULL;
+ }
+ sprintf(dirname, "%03d", bnum);
+ sprintf(filename, "%03d", dnum);
+ for (bus = usb_busses; bus; bus = bus->next) {
+ if (! num_matches(bnum, bus->dirname))
+ //if(strcmp(bus->dirname, dirname) != 0)
+ continue;
+ for (dev = bus->devices; dev; dev = dev->next) {
+ //if(strcmp(dev->filename, filename) == 0)
+ if (num_matches(dnum, dev->filename))
+ return dev;
+ }
+ }
+ ERR("no usb device match '%s'\n", path);
+ return NULL;
+}
+
+int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *handle)
+{
+ char tmp[BUFSIZ];
+ int ret;
+
+ if (!item)
+ return 0;
+ ret = usb_get_string_simple(handle, item, tmp, BUFSIZ);
+ if (ret <= 0)
+ return ret;
+ return snprintf(buf, len, "%s", tmp);
+}
+
+void my_usb_device_cleanup(struct my_usb_device *mydev)
+{
+ assert(mydev != NULL);
+ if(!mydev->handle) {
+ return; /* Nothing to do */
+ }
+ if(!disconnected) {
+ if(usb_release_interface(mydev->handle, mydev->abtype->my_interface_num) != 0) {
+ ERR("Releasing interface: usb: %s\n", usb_strerror());
+ }
+ }
+ if(usb_close(mydev->handle) != 0) {
+ ERR("Closing device: usb: %s\n", usb_strerror());
+ }
+ disconnected = 1;
+ mydev->handle = NULL;
+}
+
+static void show_device_info(const struct my_usb_device *mydev)
+{
+ const struct myeeprom *eeprom;
+ uint8_t data[LABEL_SIZE + 1];
+
+ assert(mydev != NULL);
+ eeprom = &mydev->eeprom;
+ memset(data, 0, LABEL_SIZE + 1);
+ memcpy(data, eeprom->label, LABEL_SIZE);
+ printf("USB Firmware Type: [%s]\n", mydev->abtype->name);
+ printf("USB iManufacturer: [%s]\n", mydev->iManufacturer);
+ printf("USB iProduct: [%s]\n", mydev->iProduct);
+ printf("USB iSerialNumber: [%s]\n", mydev->iSerialNumber);
+ printf("EEPROM Source: 0x%02X\n", eeprom->source);
+ printf("EEPROM Vendor: 0x%04X\n", eeprom->vendor);
+ printf("EEPROM Product: 0x%04X\n", eeprom->product);
+ printf("EEPROM Release: %d.%03d\n", eeprom->release_major, eeprom->release_minor);
+ printf("EEPROM Label: HEX(%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X) [%s]\n",
+ data[0], data[1], data[2], data[3],
+ data[4], data[5], data[6], data[7], data);
+}
+
+void dump_packet(const char *msg, const char *buf, int len)
+{
+ int i;
+
+ for(i = 0; i < len; i++)
+ INFO("%s: %2d> 0x%02X\n", msg, i, (uint8_t)buf[i]);
+}
+
+int send_usb(const char *msg, struct my_usb_device *mydev, struct fpga_packet_header *phead, int len, int timeout)
+{
+ char *p = (char *)phead;
+ int ret;
+
+ if(verbose >= LOG_DEBUG)
+ dump_packet(msg, p, len);
+ if(mydev->my_ep_out & USB_ENDPOINT_IN) {
+ ERR("send_usb called with an input endpoint 0x%x\n", mydev->my_ep_out);
+ return -EINVAL;
+ }
+ ret = usb_bulk_write(mydev->handle, mydev->my_ep_out, p, 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: %s\n", mydev->my_ep_out, usb_strerror());
+ dump_packet("send_usb[ERR]", p, len);
+ } else {
+ disconnected = 1;
+ my_usb_device_cleanup(mydev);
+ }
+ return ret;
+ } else if(ret != len) {
+ ERR("bulk_write to endpoint 0x%x short write: %s\n", mydev->my_ep_out, usb_strerror());
+ dump_packet("send_usb[ERR]", p, len);
+ return -EFAULT;
+ }
+ return ret;
+}
+
+int recv_usb(const char *msg, struct my_usb_device *mydev, char *buf, size_t len, int timeout)
+{
+ int ret;
+
+ if(mydev->my_ep_in & USB_ENDPOINT_OUT) {
+ ERR("recv_usb called with an output endpoint 0x%x\n", mydev->my_ep_in);
+ return -EINVAL;
+ }
+ ret = usb_bulk_read(mydev->handle, mydev->my_ep_in, buf, len, timeout);
+ if(ret < 0) {
+ ERR("bulk_read from endpoint 0x%x failed: %s\n", mydev->my_ep_in, usb_strerror());
+ return ret;
+ }
+ if(verbose >= LOG_DEBUG)
+ dump_packet(msg, buf, ret);
+ return ret;
+}
+
+int flush_read(struct my_usb_device *mydev)
+{
+ char tmpbuf[BUFSIZ];
+ int ret;
+
+ memset(tmpbuf, 0, BUFSIZ);
+ ret = recv_usb("flush_read", mydev, tmpbuf, sizeof(tmpbuf), TIMEOUT);
+ if(ret < 0 && ret != -ETIMEDOUT) {
+ ERR("ret=%d\n", ret);
+ return ret;
+ } else if(ret > 0) {
+ DBG("Got %d bytes:\n", ret);
+ dump_packet(__FUNCTION__, tmpbuf, ret);
+ }
+ return 0;
+}
+
+#ifdef XORCOM_INTERNAL
+int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom)
+{
+ int ret;
+ int len;
+ char buf[PACKET_SIZE];
+ struct fpga_packet_header *phead = (struct fpga_packet_header *)buf;
+
+ DBG("%s Start...\n", __FUNCTION__);
+ assert(mydev != NULL);
+ phead->header.op = PT_EEPROM_SET;
+ memcpy(&phead->d.eeprom_set.data, eeprom, EEPROM_SIZE);
+ len = sizeof(phead->d.eeprom_set) + sizeof(phead->header.op);
+ ret = send_usb("eeprom_set[W]", mydev, phead, len, TIMEOUT);
+ if(ret < 0)
+ return ret;
+ ret = recv_usb("eeprom_set[R]", mydev, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
+ return ret;
+ phead = (struct fpga_packet_header *)buf;
+ if(phead->header.op == PT_BAD_COMMAND) {
+ ERR("Firmware rejected PT_EEPROM_SET command\n");
+ return -EINVAL;
+ } else if(phead->header.op != PT_EEPROM_SET) {
+ ERR("Got unexpected reply op=%d\n", phead->header.op);
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
+int eeprom_get(struct my_usb_device *mydev)
+{
+ int ret;
+ int len;
+ char buf[PACKET_SIZE];
+ struct fpga_packet_header *phead = (struct fpga_packet_header *)buf;
+ struct myeeprom *eeprom;
+
+ assert(mydev != NULL);
+ eeprom = &mydev->eeprom;
+ DBG("%s Start...\n", __FUNCTION__);
+ phead->header.op = PT_EEPROM_GET;
+ len = sizeof(phead->header.op); /* warning: sending small packet */
+ ret = send_usb("eeprom_get[W]", mydev, phead, len, TIMEOUT);
+ if(ret < 0)
+ return ret;
+ ret = recv_usb("eeprom_get[R]", mydev, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
+ return ret;
+ phead = (struct fpga_packet_header *)buf;
+ if(phead->header.op == PT_BAD_COMMAND) {
+ ERR("PT_BAD_COMMAND\n");
+ return -EINVAL;
+ } else if(phead->header.op != PT_EEPROM_GET) {
+ ERR("Got unexpected reply op=%d\n", phead->header.op);
+ return -EINVAL;
+ }
+ memcpy(eeprom, &phead->d.eeprom_get.data, EEPROM_SIZE);
+ return 0;
+}
+
+int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq)
+{
+ int ret;
+ int len;
+ uint8_t *data;
+ char buf[PACKET_SIZE];
+ struct fpga_packet_header *phead = (struct fpga_packet_header *)buf;
+ enum fpga_load_status status;
+
+ assert(mydev != NULL);
+ assert(hexline != NULL);
+ if(hexline->d.content.header.tt != TT_DATA) {
+ DBG("Non data record %d type = %d\n", seq, hexline->d.content.header.tt);
+ return 0;
+ }
+ len = hexline->d.content.header.ll; /* don't send checksum */
+ data = hexline->d.content.tt_data.data;
+ phead->header.op = PT_DATA_PACKET;
+ phead->d.data_packet.seq = seq;
+ phead->d.data_packet.reserved = 0x00;
+ memcpy(phead->d.data_packet.data, data, len);
+ len += sizeof(hexline->d.content.header);
+ DBG("%04d+\r", seq);
+ ret = send_usb("hexline[W]", mydev, phead, len, TIMEOUT);
+ if(ret < 0)
+ return ret;
+ ret = recv_usb("hexline[R]", mydev, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
+ return ret;
+ DBG("%04d-\r", seq);
+ phead = (struct fpga_packet_header *)buf;
+ if(phead->header.op != PT_STATUS_REPLY) {
+ ERR("Got unexpected reply op=%d\n", phead->header.op);
+ dump_packet("hexline[ERR]", buf, ret);
+ return -EINVAL;
+ }
+ status = (enum fpga_load_status)phead->d.status_reply.status;
+ switch(status) {
+ case FW_TRANS_OK:
+ case FW_CONFIG_DONE:
+ break;
+ case FW_FAIL_RESET:
+ case FW_FAIL_TRANS:
+ ERR("status reply %s (%d)\n", load_status2str(status), status);
+ dump_packet("hexline[ERR]", buf, ret);
+ return -EPROTO;
+ default:
+ ERR("Unknown status reply %d\n", status);
+ dump_packet("hexline[ERR]", buf, ret);
+ return -EPROTO;
+ }
+ return 0;
+}
+
+//. returns > 0 - ok, the number of lines sent
+//. returns < 0 - error number
+int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq, uint8_t maxwidth)
+{
+ struct hexline *extraline;
+ int linessent = 0;
+ int allocsize;
+ int extra_offset = 0;
+ unsigned int this_line = 0;
+ uint8_t bytesleft = 0;
+
+ assert(mydev != NULL);
+ if(!hexline) {
+ ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt);
+ return -EINVAL;
+ }
+ bytesleft = hexline->d.content.header.ll;
+ // split the line into several lines
+ while (bytesleft > 0) {
+ int status;
+ this_line = (bytesleft >= maxwidth) ? maxwidth : bytesleft;
+ allocsize = sizeof(struct hexline) + this_line + 1;
+ // generate the new line
+ if((extraline = (struct hexline *)malloc(allocsize)) == NULL) {
+ ERR("Not enough memory for spliting the lines\n" );
+ return -EINVAL;
+ }
+ memset(extraline, 0, allocsize);
+ extraline->d.content.header.ll = this_line;
+ extraline->d.content.header.offset = hexline->d.content.header.offset + extra_offset;
+ extraline->d.content.header.tt = hexline->d.content.header.tt;
+ memcpy( extraline->d.content.tt_data.data, hexline->d.content.tt_data.data+extra_offset, this_line);
+ status = send_hexline(mydev, extraline, seq+linessent );
+ // cleanups
+ free(extraline);
+ extra_offset += this_line;
+ bytesleft -= this_line;
+ if (status)
+ return status;
+ linessent++;
+ }
+ return linessent;
+}
+
+int match_usb_device_identity(const struct usb_config_descriptor *config_desc,
+ const struct astribank_type *ab)
+{
+ struct usb_interface *interface;
+ struct usb_interface_descriptor *iface_desc;
+
+ if(config_desc->bNumInterfaces <= ab->my_interface_num)
+ return 0;
+ interface = &config_desc->interface[ab->my_interface_num];
+ iface_desc = interface->altsetting;
+
+ return iface_desc->bInterfaceClass == 0xFF &&
+ iface_desc->bInterfaceNumber == ab->my_interface_num &&
+ iface_desc->bNumEndpoints == ab->num_endpoints;
+}
+
+const struct astribank_type *my_usb_device_identify(const char devpath[], struct my_usb_device *mydev)
+{
+ struct usb_device_descriptor *dev_desc;
+ struct usb_config_descriptor *config_desc;
+ int i;
+
+ assert(mydev != NULL);
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ mydev->dev = dev_of_path(devpath);
+ if(!mydev->dev) {
+ ERR("Bailing out\n");
+ return 0;
+ }
+ dev_desc = &mydev->dev->descriptor;
+ config_desc = mydev->dev->config;
+ for(i = 0; i < sizeof(astribank_types)/sizeof(astribank_types[0]); i++) {
+ if(match_usb_device_identity(config_desc, &astribank_types[i])) {
+ DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n",
+ i,
+ astribank_types[i].num_interfaces,
+ astribank_types[i].num_endpoints,
+ astribank_types[i].name);
+ return &astribank_types[i];
+ }
+ }
+ return NULL;
+}
+
+int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const struct astribank_type *abtype)
+{
+ 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;
+ int ret;
+ int i;
+
+ assert(mydev != NULL);
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ mydev->dev = dev_of_path(devpath);
+ if(!mydev->dev) {
+ ERR("Bailing out\n");
+ return 0;
+ }
+ mydev->handle = usb_open(mydev->dev);
+ if(!mydev->handle) {
+ ERR("Failed to open usb device '%s/%s': %s\n", mydev->dev->bus->dirname, mydev->dev->filename, usb_strerror());
+ return 0;
+ }
+ if(usb_claim_interface(mydev->handle, abtype->my_interface_num) != 0) {
+ ERR("usb_claim_interface: %s\n", usb_strerror());
+ return 0;
+ }
+ dev_desc = &mydev->dev->descriptor;
+ config_desc = mydev->dev->config;
+ if (!config_desc) {
+ ERR("usb interface without a configuration\n");
+ return 0;
+ }
+ interface = &config_desc->interface[abtype->my_interface_num];
+ iface_desc = interface->altsetting;
+ endpoint = iface_desc->endpoint;
+ mydev->is_usb2 = (endpoint->wMaxPacketSize == 512);
+ for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) {
+ if(endpoint->bEndpointAddress != abtype->endpoints[i]) {
+ ERR("Wrong endpoint 0x%X (at index %d)\n", endpoint->bEndpointAddress, i);
+ return 0;
+ }
+ if(endpoint->bEndpointAddress == MY_EP_OUT || endpoint->bEndpointAddress == MY_EP_IN) {
+ if(endpoint->wMaxPacketSize > PACKET_SIZE) {
+ ERR("Endpoint #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize);
+ return 0;
+ }
+ }
+ }
+ mydev->abtype = abtype;
+ mydev->my_ep_in = abtype->my_ep_in;
+ mydev->my_ep_out = abtype->my_ep_out;
+ ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle);
+ ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle);
+ ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle);
+ ret = get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle);
+ INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n",
+ dev_desc->idVendor,
+ dev_desc->idProduct,
+ mydev->iManufacturer,
+ mydev->iProduct,
+ mydev->iSerialNumber,
+ mydev->iInterface);
+ if(usb_clear_halt(mydev->handle, mydev->my_ep_out) != 0) {
+ ERR("Clearing output endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if(usb_clear_halt(mydev->handle, mydev->my_ep_in) != 0) {
+ ERR("Clearing input endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if(flush_read(mydev) < 0) {
+ ERR("flush_read failed\n");
+ return 0;
+ }
+ return 1;
+}
+
+int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types pt)
+{
+ char buf[PACKET_SIZE];
+ struct fpga_packet_header *phead = (struct fpga_packet_header *)buf;
+ int ret;
+
+ assert(mydev != NULL);
+ DBG("Renumerating with 0x%X\n", pt);
+ phead->header.op = pt;
+ ret = send_usb("renumerate[W]", mydev, phead, 1, TIMEOUT);
+ if(ret < 0 && ret != -ENODEV)
+ return ret;
+#if 0
+ /*
+ * FIXME: we count on our USB firmware to reset the device... should we?
+ */
+ ret = usb_reset(mydev->handle);
+ if(ret < 0) {
+ ERR("usb_reset: %s\n", usb_strerror());
+ return -ENODEV;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Returns: true on success, false on failure
+ */
+int fpga_load(struct my_usb_device *mydev, const struct hexdata *hexdata)
+{
+ unsigned int i;
+ unsigned int j = 0;
+ int ret;
+ int finished = 0;
+ const char *v = hexdata->version_info;
+
+ v = (v[0]) ? v : "Unknown";
+ assert(mydev != NULL);
+ INFO("FPGA_LOAD (version %s)\n", v);
+ /*
+ * i - is the line number
+ * j - is the sequence number, on USB 2, i=j, but on
+ * USB 1 send_splited_hexline may increase the sequence
+ * number, as it needs
+ */
+ for(i = 0; i < hexdata->maxlines; i++) {
+ struct hexline *hexline = hexdata->lines[i];
+
+ if(!hexline)
+ break;
+ if(finished) {
+ ERR("Extra data after End Of Data Record (line %d)\n", i);
+ return 0;
+ }
+ if(hexline->d.content.header.tt == TT_EOF) {
+ DBG("End of data\n");
+ finished = 1;
+ continue;
+ }
+ if(mydev->is_usb2) {
+ if((ret = send_hexline(mydev, hexline, i)) != 0) {
+ perror("Failed sending hexline");
+ return 0;
+ }
+ } else {
+ if((ret = send_splited_hexline(mydev, hexline, j, 60)) < 0) {
+ perror("Failed sending hexline (splitting did not help)");
+ return 0;
+ }
+ j += ret;
+ }
+ }
+ DBG("Finished...\n");
+ return 1;
+}
+
+#include <getopt.h>
+
+void usage()
+{
+ fprintf(stderr, "Usage: %s -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> [options...]\n", progname);
+ fprintf(stderr, "\tOptions:\n");
+ fprintf(stderr, "\t\t[-r] # Reset the device\n");
+ fprintf(stderr, "\t\t[-b <binfile>] # Output to <binfile>\n");
+ fprintf(stderr, "\t\t[-I <hexfile>] # Input from <hexfile>\n");
+ fprintf(stderr, "\t\t[-H <hexfile>] # Output to <hexfile> ('-' is stdout)\n");
+ fprintf(stderr, "\t\t[-i] # Show hexfile information\n");
+ fprintf(stderr, "\t\t[-g] # Get eeprom from device\n");
+ fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
+#ifdef XORCOM_INTERNAL
+ fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n");
+ fprintf(stderr, "\t\t[-V vendorid] # Set Vendor id on device\n");
+ fprintf(stderr, "\t\t[-P productid] # Set Product id on device\n");
+ fprintf(stderr, "\t\t[-R release] # Set Release. 2 dot separated decimals\n");
+ fprintf(stderr, "\t\t[-L label] # Set label.\n");
+#endif
+ exit(1);
+}
+
+static void parse_report_func(int level, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ if(level <= verbose)
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+}
+
+#ifdef XORCOM_INTERNAL
+static void eeprom_fill(struct myeeprom *myeeprom,
+ const char vendor[],
+ const char product[],
+ const char release[],
+ const char label[],
+ const char source[])
+{
+ // FF: address source is from device. C0: from eeprom
+ if (source)
+ myeeprom->source = strtoul(source, NULL, 0);
+ else
+ myeeprom->source = 0xC0;
+ if(vendor)
+ myeeprom->vendor = strtoul(vendor, NULL, 0);
+ if(product)
+ myeeprom->product = strtoul(product, NULL, 0);
+ if(release) {
+ int release_major = 0;
+ int release_minor = 0;
+
+ sscanf(release, "%d.%d", &release_major, &release_minor);
+ myeeprom->release_major = release_major;
+ myeeprom->release_minor = release_minor;
+ }
+ if(label) {
+ /* padding */
+ memset(myeeprom->label, 0, LABEL_SIZE);
+ memcpy(myeeprom->label, label, strlen(label));
+ }
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ const struct astribank_type *abtype;
+ struct my_usb_device mydev;
+ const char *devpath = NULL;
+ const char *binfile = NULL;
+ const char *inhexfile = NULL;
+ const char *outhexfile = NULL;
+ struct hexdata *hexdata = NULL;
+ int opt_reset = 0;
+ int opt_info = 0;
+ int opt_read_eeprom = 0;
+ int opt_output_width = 0;
+ int output_is_set = 0;
+#ifdef XORCOM_INTERNAL
+ int opt_write_eeprom = 0;
+ char *vendor = NULL;
+ char *source = NULL;
+ char *product = NULL;
+ char *release = NULL;
+ char *label = NULL;
+ const char options[] = "rib:D:ghH:I:vw:C:V:P:R:S:";
+#else
+ const char options[] = "rib:D:ghH:I:vw:";
+#endif
+ int ret = 0;
+
+ progname = argv[0];
+ assert(sizeof(struct fpga_packet_header) <= PACKET_SIZE);
+ assert(sizeof(struct myeeprom) == EEPROM_SIZE);
+ while (1) {
+ int c;
+
+ c = getopt (argc, argv, options);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'D':
+ devpath = optarg;
+ if(output_is_set++) {
+ ERR("Cannot set -D. Another output option is already selected\n");
+ return 1;
+ }
+ break;
+ case 'r':
+ opt_reset = 1;
+ break;
+ case 'i':
+ opt_info = 1;
+ break;
+ case 'b':
+ binfile = optarg;
+ if(output_is_set++) {
+ ERR("Cannot set -b. Another output option is already selected\n");
+ return 1;
+ }
+ break;
+ case 'g':
+ opt_read_eeprom = 1;
+ break;
+ case 'H':
+ outhexfile = optarg;
+ if(output_is_set++) {
+ ERR("Cannot set -H. Another output option is already selected\n");
+ return 1;
+ }
+ break;
+ case 'I':
+ inhexfile = optarg;
+ break;
+#ifdef XORCOM_INTERNAL
+ case 'V':
+ vendor = optarg;
+ break;
+ case 'C':
+ source = optarg;
+ break;
+ case 'P':
+ product = optarg;
+ break;
+ case 'R':
+ release = optarg;
+ break;
+ case 'S':
+ label = optarg;
+ {
+ const char GOOD_CHARS[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "-_.";
+ int len = strlen(label);
+ int goodlen = strspn(label, GOOD_CHARS);
+
+ if(len > LABEL_SIZE) {
+ ERR("Label too long (%d > %d)\n", len, LABEL_SIZE);
+ usage();
+ }
+ if(goodlen != len) {
+ ERR("Bad character in label number (pos=%d)\n", goodlen);
+ usage();
+ }
+ }
+ break;
+#endif
+ case 'w':
+ opt_output_width = strtoul(optarg, NULL, 0);
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'h':
+ default:
+ ERR("Unknown option '%c'\n", c);
+ usage();
+ }
+ }
+
+ if (optind != argc) {
+ usage();
+ }
+ if(inhexfile) {
+#ifdef XORCOM_INTERNAL
+ if(vendor || product || release || label || source ) {
+ ERR("The -I option is exclusive of -[VPRSC]\n");
+ return 1;
+ }
+#endif
+ parse_hexfile_set_reporting(parse_report_func);
+ hexdata = parse_hexfile(inhexfile, MAX_HEX_LINES);
+ if(!hexdata) {
+ ERR("Bailing out\n");
+ exit(1);
+ }
+ if(opt_info) {
+ printf("%s: Version=%s Checksum=%d\n",
+ inhexfile, hexdata->version_info,
+ bsd_checksum(hexdata));
+ }
+ if(binfile) {
+ dump_binary(hexdata, binfile);
+ return 0;
+ }
+ if(outhexfile) {
+ if(opt_output_width)
+ dump_hexfile2(hexdata, outhexfile, opt_output_width);
+ else
+ dump_hexfile(hexdata, outhexfile);
+ return 0;
+ }
+ }
+#ifdef XORCOM_INTERNAL
+ else if(vendor || product || release || label || source ) {
+ if(outhexfile) {
+ FILE *fp;
+
+ if(strcmp(outhexfile, "-") == 0)
+ fp = stdout;
+ else if((fp = fopen(outhexfile, "w")) == NULL) {
+ perror(outhexfile);
+ return 1;
+ }
+ memset(&mydev.eeprom, 0, sizeof(struct myeeprom));
+ eeprom_fill(&mydev.eeprom, vendor, product, release, label, source);
+ gen_hexline((uint8_t *)&mydev.eeprom, 0, sizeof(mydev.eeprom), fp);
+ gen_hexline(NULL, 0, 0, fp); /* EOF */
+ return 0;
+ }
+ }
+#endif
+ if(!devpath) {
+ ERR("Missing device path\n");
+ usage();
+ }
+ DBG("Startup %s\n", devpath);
+ if((abtype = my_usb_device_identify(devpath, &mydev)) == NULL) {
+ ERR("Bad device. Does not match our types.\n");
+ usage();
+ }
+ INFO("FIRMWARE: %s (type=%d)\n", abtype->name, abtype->type_code);
+ if(!my_usb_device_init(devpath, &mydev, abtype)) {
+ ERR("Failed to initialize USB device '%s'\n", devpath);
+ ret = -ENODEV;
+ goto dev_err;
+ }
+ ret = eeprom_get(&mydev);
+ if(ret < 0) {
+ ERR("Failed reading eeprom\n");
+ goto dev_err;
+ }
+#ifdef XORCOM_INTERNAL
+ if(vendor || product || release || label || source ) {
+ eeprom_fill(&mydev.eeprom, vendor, product, release, label, source);
+ opt_write_eeprom = 1;
+ opt_read_eeprom = 1;
+ }
+#endif
+ if(opt_read_eeprom) {
+ show_device_info(&mydev);
+ }
+ if(hexdata) {
+ if (!mydev.is_usb2)
+ INFO("Warning: working on a low end USB1 backend\n");
+ if(!fpga_load(&mydev, hexdata)) {
+ ERR("FPGA loading failed\n");
+ ret = -ENODEV;
+ goto dev_err;
+ }
+ ret = renumerate_device(&mydev, PT_RENUMERATE);
+ if(ret < 0) {
+ ERR("Renumeration failed: errno=%d\n", ret);
+ goto dev_err;
+ }
+ }
+#ifdef XORCOM_INTERNAL
+ else if(opt_write_eeprom) {
+ if(abtype->type_code == USB_FIRMWARE_II) {
+ ERR("No EEPROM burning command in %s. Use fxload for that\n",
+ abtype->name);
+ goto dev_err;
+ }
+ ret = eeprom_set(&mydev, &mydev.eeprom);
+ if(ret < 0) {
+ ERR("Failed writing eeprom: %s\n", strerror(-ret));
+ goto dev_err;
+ }
+ printf("------- RESULTS -------\n");
+ show_device_info(&mydev);
+ }
+#endif
+ if(opt_reset) {
+ DBG("Reseting to default\n");
+ ret = renumerate_device(&mydev, PT_RESET);
+ if(ret < 0) {
+ ERR("Renumeration to default failed: errno=%d\n", ret);
+ goto dev_err;
+ }
+ }
+ DBG("Exiting\n");
+dev_err:
+ my_usb_device_cleanup(&mydev);
+ return ret;
+}
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 <whitespace...> value
+# * List valued items:
+# key
+# <whitespace...>value1
+# <whitespace...>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 <oron at actcom.co.il>
+ * 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 <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#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 <oron at actcom.co.il>
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/param.h>
+#include <syslog.h>
+#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..e4d473c
--- /dev/null
+++ b/xpp/lsdahdi
@@ -0,0 +1,110 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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..45654b7
--- /dev/null
+++ b/xpp/mpp.h
@@ -0,0 +1,344 @@
+#ifndef MPP_H
+#define MPP_H
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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
+ */
+
+#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 reserved[3];
+ 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[24];
+} PACKED;
+
+enum mpp_command_ops {
+ /* MSB of op signifies a reply from device */
+ MPP_ACK = 0x80,
+
+ MPP_PROTO_QUERY = 0x01,
+ MPP_PROTO_REPLY = 0x81,
+
+ MPP_RENUM = 0x0B, /* Trigger USB renumeration */
+
+ MPP_EEPROM_SET = 0x0D,
+
+ MPP_CAPS_GET = 0x0E,
+ MPP_CAPS_GET_REPLY = 0x8E,
+ MPP_CAPS_SET = 0x0F, /* Set AB capabilities */
+
+ MPP_DEV_SEND_START = 0x05,
+ MPP_DEV_SEND_SEG = 0x07,
+ MPP_DEV_SEND_END = 0x09,
+
+ MPP_STATUS_GET = 0x11, /* Get Astribank Status */
+ MPP_STATUS_GET_REPLY = 0x91,
+ MPP_STATUS_GET_REPLY_V13 = 0x91, /* backward compat */
+
+ MPP_EXTRAINFO_GET = 0x13, /* Get extra vendor information */
+ MPP_EXTRAINFO_GET_REPLY = 0x93,
+ MPP_EXTRAINFO_SET = 0x15, /* Set extra vendor information */
+
+ MPP_EEPROM_BLK_RD = 0x27,
+ MPP_EEPROM_BLK_RD_REPLY = 0xA7,
+
+ MPP_SER_SEND = 0x37,
+ MPP_SER_RECV = 0xB7,
+
+ MPP_RESET = 0x45, /* Reset both FPGA and USB firmwares */
+ MPP_HALF_RESET = 0x47, /* Reset only FPGA firmware */
+
+ /* Twinstar */
+ MPP_TWS_WD_MODE_SET = 0x31, /* Set watchdog off/on guard */
+ MPP_TWS_WD_MODE_GET = 0x32, /* Current watchdog mode */
+ MPP_TWS_WD_MODE_GET_REPLY = 0xB2, /* Current watchdog mode */
+ MPP_TWS_PORT_SET = 0x34, /* USB-[0/1] */
+ MPP_TWS_PORT_GET = 0x35, /* USB-[0/1] */
+ MPP_TWS_PORT_GET_REPLY = 0xB5, /* USB-[0/1] */
+ MPP_TWS_PWR_GET = 0x36, /* Power: bits -> USB ports */
+ MPP_TWS_PWR_GET_REPLY = 0xB6, /* Power: bits -> USB ports */
+};
+
+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,
+};
+
+/* Individual commands structure */
+
+#define CMD_DEF(name, ...) struct d_ ## name { __VA_ARGS__ } PACKED d_ ## name
+
+CMD_DEF(ACK,
+ uint8_t stat;
+ );
+
+CMD_DEF(PROTO_QUERY,
+ uint8_t proto_version;
+ uint8_t reserved;
+ );
+
+CMD_DEF(PROTO_REPLY,
+ uint8_t proto_version;
+ uint8_t reserved;
+ );
+
+CMD_DEF(STATUS_GET);
+
+CMD_DEF(STATUS_GET_REPLY_V13,
+ uint8_t i2cs_data;
+
+#define STATUS_FPGA_LOADED(x) ((x) & 0x01)
+ uint8_t status; /* BIT(0) - FPGA is loaded */
+ );
+
+
+CMD_DEF(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(EEPROM_SET,
+ struct eeprom_table data;
+ );
+
+CMD_DEF(CAPS_GET);
+
+CMD_DEF(CAPS_GET_REPLY,
+ struct eeprom_table data;
+ struct capabilities capabilities;
+ struct capkey key;
+ );
+
+CMD_DEF(CAPS_SET,
+ struct eeprom_table data;
+ struct capabilities capabilities;
+ struct capkey key;
+ );
+
+CMD_DEF(EXTRAINFO_GET);
+
+CMD_DEF(EXTRAINFO_GET_REPLY,
+ struct extrainfo info;
+ );
+
+CMD_DEF(EXTRAINFO_SET,
+ struct extrainfo info;
+ );
+
+CMD_DEF(RENUM);
+
+CMD_DEF(EEPROM_BLK_RD,
+ uint16_t offset;
+ uint16_t len;
+ );
+
+CMD_DEF(EEPROM_BLK_RD_REPLY,
+ uint16_t offset;
+ uint8_t data[0];
+ );
+
+CMD_DEF(DEV_SEND_START,
+ uint8_t dest;
+ char ihex_version[VERSION_LEN];
+ );
+
+CMD_DEF(DEV_SEND_END);
+
+CMD_DEF(DEV_SEND_SEG,
+ uint16_t offset;
+ uint8_t data[0];
+ );
+
+CMD_DEF(RESET);
+CMD_DEF(HALF_RESET);
+
+CMD_DEF(SER_SEND,
+ uint8_t data[0];
+ );
+
+CMD_DEF(SER_RECV,
+ uint8_t data[0];
+ );
+
+CMD_DEF(TWS_WD_MODE_SET,
+ uint8_t wd_active;
+ );
+
+CMD_DEF(TWS_WD_MODE_GET);
+CMD_DEF(TWS_WD_MODE_GET_REPLY,
+ uint8_t wd_active;
+ );
+
+CMD_DEF(TWS_PORT_SET,
+ uint8_t portnum;
+ );
+
+CMD_DEF(TWS_PORT_GET);
+CMD_DEF(TWS_PORT_GET_REPLY,
+ uint8_t portnum;
+ );
+
+CMD_DEF(TWS_PWR_GET);
+CMD_DEF(TWS_PWR_GET_REPLY,
+ uint8_t power;
+ );
+
+#undef CMD_DEF
+
+#define MEMBER(n) struct d_ ## n d_ ## n
+
+struct mpp_command {
+ struct mpp_header header;
+ union {
+ MEMBER(ACK);
+ MEMBER(PROTO_QUERY);
+ MEMBER(PROTO_REPLY);
+ MEMBER(STATUS_GET);
+ MEMBER(STATUS_GET_REPLY_V13);
+ MEMBER(STATUS_GET_REPLY);
+ MEMBER(EEPROM_SET);
+ MEMBER(CAPS_GET);
+ MEMBER(CAPS_GET_REPLY);
+ MEMBER(CAPS_SET);
+ MEMBER(EXTRAINFO_GET);
+ MEMBER(EXTRAINFO_GET_REPLY);
+ MEMBER(EXTRAINFO_SET);
+ MEMBER(RENUM);
+ MEMBER(EEPROM_BLK_RD);
+ MEMBER(EEPROM_BLK_RD_REPLY);
+ MEMBER(DEV_SEND_START);
+ MEMBER(DEV_SEND_SEG);
+ MEMBER(DEV_SEND_END);
+ MEMBER(RESET);
+ MEMBER(HALF_RESET);
+ MEMBER(SER_SEND);
+ MEMBER(SER_RECV);
+ /* Twinstar */
+ MEMBER(TWS_WD_MODE_SET);
+ MEMBER(TWS_WD_MODE_GET);
+ MEMBER(TWS_WD_MODE_GET_REPLY);
+ MEMBER(TWS_PORT_SET);
+ MEMBER(TWS_PORT_GET);
+ MEMBER(TWS_PORT_GET_REPLY);
+ MEMBER(TWS_PWR_GET);
+ MEMBER(TWS_PWR_GET_REPLY);
+ uint8_t raw_data[0];
+ } PACKED alt;
+} PACKED;
+#undef MEMBER
+
+#define CMD_FIELD(cmd, name, field) ((cmd)->alt.d_ ## name.field)
+
+enum mpp_ack_stat {
+ STAT_OK = 0x00, /* acknowledges previous command */
+ STAT_FAIL = 0x01, /* Last command failed */
+ STAT_RESET_FAIL = 0x02, /* reset failed */
+ STAT_NODEST = 0x03, /* No destination is selected */
+ STAT_MISMATCH = 0x04, /* Data mismatch */
+ STAT_NOACCESS = 0x05, /* No access */
+ STAT_BAD_CMD = 0x06, /* Bad command */
+ STAT_TOO_SHORT = 0x07, /* Packet is too short */
+ STAT_ERROFFS = 0x08, /* Offset error */
+ STAT_NOCODE = 0x09, /* Source was not burned before */
+ STAT_NO_LEEPROM = 0x0A, /* Large EEPROM was not found */
+ STAT_NO_EEPROM = 0x0B, /* No EEPROM was found */
+ STAT_WRITE_FAIL = 0x0C, /* Writing to device failed */
+ STAT_FPGA_ERR = 0x0D, /* FPGA error */
+ STAT_KEY_ERR = 0x0E, /* Bad Capabilities Key */
+ STAT_NOCAPS_ERR = 0x0F, /* No matching capability */
+ STAT_NOPWR_ERR = 0x10, /* No power on USB connector */
+ STAT_CAPS_FPGA_ERR = 0x11, /* Setting of the capabilities while FPGA is loaded */
+};
+
+enum eeprom_type { /* EEPROM_QUERY: i2cs(ID1, ID0) */
+ 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,
+};
+
+#endif /* MPP_H */
diff --git a/xpp/mpp_funcs.c b/xpp/mpp_funcs.c
new file mode 100644
index 0000000..457455a
--- /dev/null
+++ b/xpp/mpp_funcs.c
@@ -0,0 +1,1109 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include "hexfile.h"
+#include "astribank_usb.h"
+#include "mpp_funcs.h"
+#include "debug.h"
+
+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(enum eeprom_type 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(enum dev_dest 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];
+};
+
+struct command_desc {
+ uint8_t op;
+ const char *name;
+ uint16_t len;
+};
+
+#define CMD_RECV(o) [MPP_ ## o] { \
+ .op = MPP_ ## o, \
+ .name = #o, \
+ .len = sizeof(struct mpp_header) + sizeof(struct d_ ## o), \
+ }
+
+#define CMD_SEND(o) [MPP_ ## o] { \
+ .op = MPP_ ## o, \
+ .name = #o, \
+ .len = sizeof(struct mpp_header) + sizeof(struct d_ ## o), \
+ }
+
+static const struct command_desc command_table[] = {
+ CMD_RECV(ACK),
+ CMD_SEND(PROTO_QUERY),
+ CMD_SEND(STATUS_GET),
+ CMD_RECV(STATUS_GET_REPLY),
+ CMD_SEND(EEPROM_SET),
+ CMD_SEND(CAPS_GET),
+ CMD_RECV(CAPS_GET_REPLY),
+ CMD_SEND(CAPS_SET),
+ CMD_SEND(EXTRAINFO_GET),
+ CMD_RECV(EXTRAINFO_GET_REPLY),
+ CMD_SEND(EXTRAINFO_SET),
+ CMD_RECV(PROTO_REPLY),
+ CMD_SEND(RENUM),
+ CMD_SEND(EEPROM_BLK_RD),
+ CMD_RECV(EEPROM_BLK_RD_REPLY),
+ CMD_SEND(DEV_SEND_SEG),
+ CMD_SEND(DEV_SEND_START),
+ CMD_SEND(DEV_SEND_END),
+ CMD_SEND(RESET),
+ CMD_SEND(HALF_RESET),
+ CMD_SEND(SER_SEND),
+ CMD_SEND(SER_RECV),
+ /* Twinstar */
+ CMD_SEND(TWS_WD_MODE_SET),
+ CMD_SEND(TWS_WD_MODE_GET),
+ CMD_RECV(TWS_WD_MODE_GET_REPLY),
+ CMD_SEND(TWS_PORT_SET),
+ CMD_SEND(TWS_PORT_GET),
+ CMD_RECV(TWS_PORT_GET_REPLY),
+ CMD_SEND(TWS_PWR_GET),
+ CMD_RECV(TWS_PWR_GET_REPLY),
+};
+
+static const struct command_desc command_table_V13[] = {
+ CMD_RECV(ACK),
+ CMD_SEND(PROTO_QUERY),
+ CMD_SEND(STATUS_GET),
+ CMD_RECV(STATUS_GET_REPLY_V13),
+ CMD_SEND(EEPROM_SET),
+ CMD_SEND(CAPS_GET),
+ CMD_RECV(CAPS_GET_REPLY),
+ CMD_SEND(CAPS_SET),
+ CMD_SEND(EXTRAINFO_GET),
+ CMD_RECV(EXTRAINFO_GET_REPLY),
+ CMD_SEND(EXTRAINFO_SET),
+ CMD_RECV(PROTO_REPLY),
+ CMD_SEND(RENUM),
+ CMD_SEND(EEPROM_BLK_RD),
+ CMD_RECV(EEPROM_BLK_RD_REPLY),
+ CMD_SEND(DEV_SEND_SEG),
+ CMD_SEND(DEV_SEND_START),
+ CMD_SEND(DEV_SEND_END),
+ CMD_SEND(RESET),
+ CMD_SEND(HALF_RESET),
+ CMD_SEND(SER_SEND),
+ CMD_SEND(SER_RECV),
+ /* Twinstar */
+ CMD_SEND(TWS_WD_MODE_SET),
+ CMD_SEND(TWS_WD_MODE_GET),
+ CMD_RECV(TWS_WD_MODE_GET_REPLY),
+ CMD_SEND(TWS_PORT_SET),
+ CMD_SEND(TWS_PORT_GET),
+ CMD_RECV(TWS_PORT_GET_REPLY),
+ CMD_SEND(TWS_PWR_GET),
+ CMD_RECV(TWS_PWR_GET_REPLY),
+};
+
+#undef CMD_SEND
+#undef CMD_RECV
+
+struct cmd_queue {
+ struct cmd_queue *next;
+ struct cmd_queue *prev;
+ struct mpp_command *cmd;
+};
+
+static struct cmd_queue output_queue = {
+ .next = &output_queue,
+ .prev = &output_queue,
+ .cmd = NULL
+ };
+
+void free_command(struct mpp_command *cmd)
+{
+ memset(cmd, 0, cmd->header.len);
+ free(cmd);
+}
+
+const struct command_desc *get_command_desc(uint8_t protocol_version, uint8_t op)
+{
+ const struct command_desc *desc;
+
+ switch(protocol_version) {
+ case MK_PROTO_VERSION(1,3):
+ if(op > sizeof(command_table_V13)/sizeof(command_table_V13[0])) {
+ //ERR("Invalid op=0x%X. Bigger than max valid op\n", op);
+ return NULL;
+ }
+ desc = &command_table_V13[op];
+ if(!desc->name)
+ return NULL;
+ break;
+ default:
+ if(op > sizeof(command_table)/sizeof(command_table[0])) {
+ //ERR("Invalid op=0x%X. Bigger than max valid op\n", op);
+ return NULL;
+ }
+ desc = &command_table[op];
+ if(!desc->name)
+ return NULL;
+ break;
+ }
+ return desc;
+}
+
+struct mpp_command *new_command(uint8_t protocol_version, uint8_t op, uint16_t extra_data)
+{
+ struct mpp_command *cmd;
+ const struct command_desc *desc;
+ uint16_t len;
+
+ desc = get_command_desc(protocol_version, 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;
+ if((cmd = malloc(len)) == NULL) {
+ ERR("Out of memory\n");
+ return NULL;
+ }
+ cmd->header.op = op;
+ cmd->header.len = len;
+ cmd->header.seq = 0; /* Overwritten in send_usb() */
+ return cmd;
+}
+
+void dump_command(struct mpp_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]);
+ }
+}
+
+int send_command(struct astribank_device *astribank, struct mpp_command *cmd, int timeout)
+{
+ int ret;
+ int len;
+ char *buf;
+
+ len = cmd->header.len;
+ cmd->header.seq = astribank->tx_sequenceno;
+
+ buf = (char *)cmd;
+ //printf("%s: len=%d\n", __FUNCTION__, len);
+#if 0
+ extern FILE *fp;
+ if(fp) {
+ int i;
+
+ fprintf(fp, "%05d:", cmd->header.seq);
+ for(i = 0; i < len; i++)
+ fprintf(fp, " %02X", (uint8_t)buf[i]);
+ fprintf(fp, "\n");
+ }
+#endif
+ ret = send_usb(astribank, (char *)cmd, len, timeout);
+ if(ret < 0) {
+ DBG("send_usb failed ret=%d\n", ret);
+ }
+ astribank->tx_sequenceno++;
+ return ret;
+}
+
+struct mpp_command *recv_command(struct astribank_device *astribank, int timeout)
+{
+ struct mpp_command *reply;
+ int ret;
+
+ if((reply = malloc(PACKET_SIZE)) == NULL) {
+ ERR("Out of memory\n");
+ goto err;
+ }
+ reply->header.len = 0;
+ ret = recv_usb(astribank, (char *)reply, PACKET_SIZE, 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, __FUNCTION__, (char *)reply, ret);
+ return reply;
+err:
+ if(reply) {
+ memset(reply, 0, PACKET_SIZE);
+ free_command(reply);
+ }
+ return NULL;
+}
+
+
+__attribute__((warn_unused_result))
+int process_command(struct astribank_device *astribank, struct mpp_command *cmd, struct mpp_command **reply_ref)
+{
+ struct mpp_command *reply = NULL;
+ const struct command_desc *reply_desc;
+ const struct command_desc *expected;
+ const struct command_desc *cmd_desc;
+ uint8_t reply_op;
+ int ret;
+
+ if(reply_ref)
+ *reply_ref = NULL; /* So the caller knows if a reply was received */
+ reply_op = cmd->header.op | 0x80;
+ if(cmd->header.op == MPP_PROTO_QUERY)
+ astribank->mpp_proto_version = MPP_PROTOCOL_VERSION; /* bootstrap */
+ cmd_desc = get_command_desc(astribank->mpp_proto_version, cmd->header.op);
+ expected = get_command_desc(astribank->mpp_proto_version, reply_op);
+ //printf("%s: len=%d\n", __FUNCTION__, cmd->header.len);
+ ret = send_command(astribank, 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(astribank, 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(astribank->mpp_proto_version, reply->header.op);
+ if(!reply_desc) {
+ ERR("Unknown reply op=0x%02X\n", reply->header.op);
+ ret = -EPROTO;
+ goto out;
+ }
+ DBG("REPLY NAME: %s\n", reply_desc->name);
+ if(reply->header.op == MPP_ACK) {
+ int status = CMD_FIELD(reply, ACK, stat);
+
+ if(expected) {
+ ERR("Expected OP=0x%02X: Got ACK(%d): %s\n",
+ reply_op, status, ack_status_msg(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(status));
+#if 0
+ extern FILE *fp;
+ if(fp) {
+ fprintf(fp, "Got ACK(%d)\n", status);
+ }
+#endif
+ 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->op != MPP_SER_RECV && 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;
+}
+
+static int set_ihex_version(char *dst, const char *src)
+{
+ memcpy(dst, src, VERSION_LEN);
+ return 0;
+}
+
+/*
+ * Protocol Commands
+ */
+
+int mpp_proto_query(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_PROTO_QUERY, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, PROTO_QUERY, proto_version) = MPP_PROTOCOL_VERSION; /* Protocol Version */
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ astribank->mpp_proto_version = CMD_FIELD(reply, PROTO_REPLY, proto_version);
+ if(! MPP_SUPPORTED_VERSION(astribank->mpp_proto_version)) {
+ ERR("Got mpp protocol version: %02x (expected %02x)\n",
+ astribank->mpp_proto_version,
+ MPP_PROTOCOL_VERSION);
+ ret = -EPROTO;
+ goto out;
+ }
+ if(astribank->mpp_proto_version != MPP_PROTOCOL_VERSION) {
+ ERR("Deprecated (but working) MPP protocol version [%X]. Please upgrade to [%X] ASAP\n",
+ astribank->mpp_proto_version, MPP_PROTOCOL_VERSION);
+ }
+ DBG("Protocol version: %02x\n", astribank->mpp_proto_version);
+ ret = astribank->mpp_proto_version;
+ free_command(reply);
+out:
+ return ret;
+}
+
+int mpp_status_query(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_STATUS_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ astribank->eeprom_type = 0x3 & (CMD_FIELD(reply, STATUS_GET_REPLY, i2cs_data) >> 3);
+ astribank->status = CMD_FIELD(reply, STATUS_GET_REPLY, status);
+ astribank->fw_versions = CMD_FIELD(reply, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_EEPROM_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, EEPROM_SET, data), et, sizeof(*et));
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_RENUM, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_CAPS_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, 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, CAPS_GET_REPLY, data), sizeof(*eeprom_table));
+ }
+ if(capabilities) {
+ const struct capabilities *cap = &CMD_FIELD(reply, CAPS_GET_REPLY, capabilities);
+
+ memcpy(capabilities, cap, sizeof(*capabilities));
+ }
+ if(key) {
+ const struct capkey *k = &CMD_FIELD(reply, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_CAPS_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, data), eeprom_table, sizeof(*eeprom_table));
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, capabilities), capabilities, sizeof(*capabilities));
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, key), key, sizeof(*key));
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_EXTRAINFO_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY);
+ if(info) {
+ memcpy(info, (void *)&CMD_FIELD(reply, EXTRAINFO_GET_REPLY, info), sizeof(*info));
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_EXTRAINFO_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, EXTRAINFO_SET, info), info, sizeof(*info));
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+ int size;
+
+ DBG("len = %d, offset = %d\n", len, offset);
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_EEPROM_BLK_RD, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, EEPROM_BLK_RD, len) = len;
+ CMD_FIELD(cmd, EEPROM_BLK_RD, offset) = offset;
+ ret = process_command(astribank, 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(struct d_EEPROM_BLK_RD_REPLY);
+ INFO("size=%d offset=0x%X\n", size, CMD_FIELD(reply, EEPROM_BLK_RD_REPLY, offset));
+ dump_packet(LOG_DEBUG, "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, EEPROM_BLK_RD_REPLY, data), size);
+out:
+ free_command(reply);
+ return size;
+}
+
+int mpp_send_start(struct astribank_device *astribank, enum dev_dest dest, const char *ihex_version)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply = NULL;
+ int ret = 0;
+
+ DBG("dest = %s ihex_version = '%s'\n", dev_dest2str(dest), ihex_version);
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_DEV_SEND_START, 0)) == NULL) {
+ ERR("new_command failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+ CMD_FIELD(cmd, DEV_SEND_START, dest) = dest;
+ set_ihex_version(CMD_FIELD(cmd, DEV_SEND_START, ihex_version), ihex_version);
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply = NULL;
+ int ret = 0;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_DEV_SEND_END, 0)) == NULL) {
+ ERR("new_command failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ 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));
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_DEV_SEND_SEG, len)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, DEV_SEND_SEG, offset) = offset;
+ memcpy(CMD_FIELD(cmd, 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, DEV_SEND_SEG, data), len, 1, fp) != 1) {
+ perror("fwrite");
+ exit(1);
+ }
+ fclose(fp);
+ }
+#endif
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ int ret;
+ int op = (full_reset) ? MPP_RESET: MPP_HALF_RESET;
+
+ DBG("full = %s\n", (full_reset) ? "YES" : "NO");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, op, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+ uint8_t *data;
+
+ DBG("len=%d\n", len);
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_SER_SEND, len)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ data = CMD_FIELD(cmd, SER_SEND, data);
+ memcpy(data, in, len);
+ ret = process_command(astribank, 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, 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)
+{
+ struct card_info_send {
+ uint8_t ser_op;
+ uint8_t addr;
+ } *card_info_send;
+ struct card_info_recv {
+ uint8_t ser_op_undef; /* invalid data */
+ uint8_t addr;
+ uint8_t card_full_type; /* (type << 4 | subtype) */
+ uint8_t card_status; /* BIT(0) - PIC burned */
+ } *card_info_recv;
+ uint8_t in[sizeof(struct card_info_recv)];
+ uint8_t out[sizeof(struct card_info_recv)];
+ int len;
+ int ret;
+
+ len = sizeof(struct card_info_recv);
+ memset(in, 0, len);
+ memset(out, 0, len);
+ card_info_send = (struct card_info_send *)∈
+ card_info_recv = (struct card_info_recv *)&out;
+ card_info_send->ser_op = SER_CARD_INFO_GET;
+ card_info_send->addr = (unit << 4); /* low nibble is subunit */
+ ret = mpp_serial_cmd(astribank, in, out, len);
+ if(ret < 0)
+ return ret;
+ *card_type = card_info_recv->card_full_type;
+ *card_status = card_info_recv->card_status;
+ return 0;
+}
+
+int mpp_tws_watchdog(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_TWS_WD_MODE_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("%s\n", (yes) ? "YES" : "NO");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_TWS_WD_MODE_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, TWS_WD_MODE_SET, wd_active) = (yes) ? 1 : 0;
+ ret = process_command(astribank, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_TWS_PWR_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, 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 mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_TWS_PORT_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, 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 mpp_command *cmd;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if(portnum >= 2) {
+ ERR("Invalid portnum (%d)\n", portnum);
+ return -EINVAL;
+ }
+ if((cmd = new_command(astribank->mpp_proto_version, MPP_TWS_PORT_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, TWS_PORT_SET, portnum) = portnum;
+ ret = process_command(astribank, cmd, NULL);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ * Wrappers
+ */
+
+struct astribank_device *mpp_init(const char devpath[])
+{
+ struct astribank_device *astribank;
+ int ret;
+
+ DBG("devpath='%s'\n", devpath);
+ if((astribank = astribank_open(devpath, 1)) == NULL) {
+ ERR("Opening astribank failed\n");
+ return NULL;
+ }
+ ret = mpp_proto_query(astribank);
+ 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);
+ 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: 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)
+{
+ fprintf(fp, "Extrainfo: : %s\n", (const char *)(extrainfo->text));
+}
+
+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/mpp_funcs.h b/xpp/mpp_funcs.h
new file mode 100644
index 0000000..59bbc7d
--- /dev/null
+++ b/xpp/mpp_funcs.h
@@ -0,0 +1,80 @@
+#ifndef MPP_FUNCS_H
+#define MPP_FUNCS_H
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 "mpp.h"
+#include "astribank_usb.h"
+
+#define TIMEOUT 2000
+
+/* high-level */
+struct astribank_device *mpp_init(const char devpath[]);
+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, enum dev_dest 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);
+
+/*
+ * 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);
+
+/* low-level */
+int process_command(struct astribank_device *astribank, struct mpp_command *cmd, struct mpp_command **reply_ref);
+struct mpp_command *new_command(uint8_t protocol_version, uint8_t op, uint16_t extra_data);
+void free_command(struct mpp_command *cmd);
+
+const char *dev_dest2str(enum dev_dest dest);
+
+#endif /* MPP_FUNCS_H */
diff --git a/xpp/perl_modules/Dahdi.pm b/xpp/perl_modules/Dahdi.pm
new file mode 100644
index 0000000..e17b939
--- /dev/null
+++ b/xpp/perl_modules/Dahdi.pm
@@ -0,0 +1,79 @@
+package Dahdi;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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_xpp_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<DAHDI_VIRT_TOP> 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<build_tools/dump_sys_state> .
+
+=head1 SEE ALSO
+
+Span objects: L<Dahdi::Span>.
+
+Dahdi channels objects: L<Dahdi::Chan>.
+
+Dahdi hardware devices information: L<Dahdi::Hardware>.
+
+Xorcom Astribank -specific information: L<Dahdi::Xpp>.
+
+=cut
+
+1;
diff --git a/xpp/perl_modules/Dahdi/Chans.pm b/xpp/perl_modules/Dahdi/Chans.pm
new file mode 100644
index 0000000..a869ae4
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Chans.pm
@@ -0,0 +1,264 @@
+package Dahdi::Chans;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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<undef>
+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(TE[24]|WCT1|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 = $span->xpd;
+ 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 = $span->xpd;
+ 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 <oron at actcom.co.il>
+# 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<Dahdi::Config::Params> object.
+The returned object contains all data required for generation in the
+form of a hash.
+
+The constructor maps the C<item()>s from the parameter object into semantic
+configuration keys. E.g: the C<lc_country> item is mapped to C<loadzone> and
+C<defaultzone> keys.
+
+The actual generation is done by delegation to one of the generators.
+This is done via the C<run_generator()> method which receive the
+generator name, a generator specific options hash and a list of
+span objects (from C<Dahdi::Span>) for which to generate configuration.
+
+This module contains few helper functions. E.g: C<is_true()>, C<bchan_range()>.
+
+=cut
+
+require Exporter;
+ at ISA = qw(Exporter);
+
+ at 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/Chandahdi.pm b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
new file mode 100644
index 0000000..7ade82a
--- /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\" <%04d>", $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=%04d\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</etc/asterisk/dahdi-channels.conf>
+This is used as a configuration for asterisk(1).
+It should be included in the main F</etc/asterisk/chan_dahdi.conf>.
+
+Its location may be overriden via the environment variable
+C<CHAN_DAHDI_CHANNELS_FILE>.
+
+=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<freepbx> database anyway.
+
+=back
+
+The I<freepbx> option may be activated also by adding a C<freepbx yes> line
+to the C<genconf_parameters> file.
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</etc/dahdi/modules>. This is a list of modules, one per
+line. This list is normally used by F</etc/init.d/dahdi>.
+
+Its location may be overriden via the environment variable
+F<DAHDI_MODULES_FILE>.
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..d7c2523
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Config/Gen/System.pm
@@ -0,0 +1,278 @@
+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;
+ printf "dchan=%d\n", $span->dchan()->num();
+ } 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 = $span->xpd();
+ 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</etc/dahdi/system.conf>.
+This is the configuration for dahdi_cfg(1).
+
+Its location may be overriden via the environment variable F<DAHDI_CONF_FILE>.
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</etc/asterisk/unicall-channels.conf> to be included in
+F</etc/asterisk/unicall.conf>
+
+Its location may be overriden via the environment variable
+C<UNICALL_CHANNELS_FILE>.
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</etc/asterisk/users.conf> 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<USERS_FILE>.
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..e7bfb72
--- /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 ($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</etc/dahdi/xpp_order>.
+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<XPPORDER_CONF>.
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 <oron at actcom.co.il>
+# 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<genconf_parameters> 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<not> an error.
+
+=item * Other opening errors cause a C<die> to be thrown.
+
+=item * The file name is saved as the value of C<GENCONF_FILE> key.
+
+=back
+
+The access to config keys should only be done via the C<item()> 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<NODEFAULTS =E<gt> 1> option, returns C<undef> 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(<F>) {
+ 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 <oron at actcom.co.il>
+# 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..1a4e36d
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Hardware/PCI.pm
@@ -0,0 +1,245 @@
+package Dahdi::Hardware::PCI;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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 ' },
+
+ # 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 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: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 => 'r1t1', DESCRIPTION => 'Rhino R1T1' },
+ '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 = <F>;
+ 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(</sys/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..edc0f4c
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Hardware/USB.pm
@@ -0,0 +1,206 @@
+package Dahdi::Hardware::USB;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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' },
+
+ # 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 = <F>;
+ 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 = <ATTR>;
+ 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 = $1 || next;
+ 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);
+ 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},
+ );
+ 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(<F>) {
+ my @lines = split(/\n/);
+ my ($tline) = grep(/^T/, @lines);
+ my ($pline) = grep(/^P/, @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 $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},
+ );
+ 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..9dd3347
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Span.pm
@@ -0,0 +1,364 @@
+package Dahdi::Span;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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<Dahdi> for usage example. Specifically
+C<Dahdi::spans()> 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<Dahdi::Chan> 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', # Does not expose NT/TE type
+ '(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
+ 'T[24]XXP \(PCI\) Card ', # wct4xxp
+ '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
+ );
+
+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 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 = <F>;
+ chomp $head;
+ $self->{IS_DIGITAL} = 0;
+ $self->{IS_BRI} = 0;
+ $self->{IS_PRI} = 0;
+ foreach my $cardtype (@bri_strings) {
+ if($head =~ m/$cardtype/) {
+ my $termtype = $1;
+ $termtype = 'TE' if ( $1 eq 'B4XXP' or $1 eq 'WCBRI' );
+ $self->{IS_DIGITAL} = 1;
+ $self->{IS_BRI} = 1;
+ $self->{TERMTYPE} = $termtype;
+ $self->{TYPE} = "BRI_$termtype";
+ $self->{DCHAN_IDX} = 2;
+ $self->{BCHAN_LIST} = [ 0, 1 ];
+ 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->{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;
+ while(<F>) {
+ 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;
+ $span->{SIGNALLING} = ($termtype eq 'NT') ? $DAHDI_PRI_NET : $DAHDI_PRI_CPE ;
+ $span->{TYPE} = $span->proto . "_$termtype";
+}
+
+sub pri_set_fromconfig($$) {
+ my $span = shift || die;
+ my $genconf = shift || die;
+ my $name = $span->name;
+# 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 = $span->{XPD};
+ 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..4ca468b
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Utils.pm
@@ -0,0 +1,66 @@
+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_xpp_base = "$Dahdi::virt_base/proc/xpp";
+ $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..d4b315b
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Xpp.pm
@@ -0,0 +1,343 @@
+package Dahdi::Xpp;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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 unless $entry =~ /xbus-(\d+)/;
+ my $xbus = Dahdi::Xpp::Xbus->new($1);
+ 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(',', at a_types);
+ #printf STDERR "DEBUG-b: %s %s %s\n", $b->name, $b_score, join(',', at 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 cmp $b->xpporder;
+ return $cmp if $cmp != 0;
+ return $a->connector cmp $b->connector;
+}
+
+=head1 xbuses([sort_order])
+
+Scans system (/proc and /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</etc/dahdi/xpp_order> file.
+Astribanks can be listed in this file by their label or by
+their connector string (prefixed with <@>).
+
+Astribanks not listed in the F<xpp_order> 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(<F>) {
+ 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 /proc/xpp/sync .
+For more information read that file and see README.Astribank .
+
+=cut
+
+sub sync_via_proc {
+ my $newsync = shift;
+ my $result;
+ my $newapi = 0;
+
+ my $proc_base = $Dahdi::proc_xpp_base;
+ my $file = "$proc_base/sync";
+ return '' unless -f $file;
+ # First query
+ open(F, "$file") or die "Failed to open $file for reading: $!";
+ while(<F>) {
+ chomp;
+ /SYNC=/ and $newapi = 1;
+ s/#.*//;
+ if(/\S/) { # First non-comment line
+ s/^SYNC=\D*// if $newapi;
+ $result = $_;
+ last;
+ }
+ }
+ close F;
+ if(defined($newsync)) { # Now change
+ $newsync =~ s/.*/\U$&/;
+ if($newsync =~ /^(\d+)$/) {
+ $newsync = ($newapi)? "SYNC=$1" : "$1 0";
+ } 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;
+}
+
+sub sync {
+ my ($newsync) = @_;
+ my $result;
+ my $file = "$sysfs_ab_driver/sync";
+ if(! -f $file) { # Old /proc interface
+ return sync_via_proc(@_);
+ }
+ open(F, "$file") or die "Failed to open $file for reading: $!";
+ $result = <F>;
+ 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<Dahdi::Xpp::Xbus>
+
+Xbus (Astribank) object.
+
+=item L<Dahdi::Xpp::Xpd>
+
+XPD (the rough equivalent of a Dahdi span) object.
+
+=item L<Dahdi::Xpp::Line>
+
+Object for a line: an analog port or a time-slot in a adapter.
+Equivalent of a channel in Dahdi.
+
+=item L<Dahdi>
+
+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..1302a9e
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Xpp/Line.pm
@@ -0,0 +1,89 @@
+package Dahdi::Xpp::Line;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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;
+ my $procdir = 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");
+ if(defined $battery) {
+ my @batt = split(/\s+/, $battery);
+ foreach my $l (@lines) {
+ die unless @batt;
+ my $state = shift @batt;
+ $l->{BATTERY} = ($state eq '+') ? 1 : 0;
+ }
+ } else {
+ # Fallback to old interface
+ my ($infofile) = glob "$procdir/*_info";
+ die "Failed globbing '$procdir/*_info'" unless defined $infofile;
+ open(F, "$infofile") || die "Failed opening '$infofile': $!";
+ my $battery_info = 0;
+ while (<F>) {
+ chomp;
+ $battery_info = 1 if /^Battery:/;
+ if($battery_info && s/^\s*on\s*:\s*//) {
+ my @batt = split;
+ foreach my $l (@lines) {
+ die unless @batt;
+ my $state = shift @batt;
+ $l->{BATTERY} = ($state eq '+') ? 1 : 0;
+ }
+ $battery_info = 0;
+ die if @batt;
+ }
+ }
+ close F;
+ }
+ }
+ close F;
+}
+
+
+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 <oron at actcom.co.il>
+# 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<astribank_tool(8)>
+
+=head1 DESCRIPTION
+
+This package uses C<astribank_tool(8)> to collect information
+about Astribanks via MPP (Management Processor Protocol).
+
+The binary default location is F</usr/sbin/astribank_tool>. It may be
+overridden via module parameter C<astribank_tool=> and the
+C<ASTRIBANK_TOOL> 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<Dahdi::Hardware> objects and augment their
+data with C<Dahdi::Xpp::Mpp> objects.
+
+This method is the normal external interface of this class.
+
+=head2 new()
+
+Constructor. Receive as parameter an instance of C<Dahdi::Hardware> class
+and return a C<Dahdi::Xpp:Mpp> 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<undef>.
+
+=head2 showinfo()
+
+Dump an C<Dahdi::Xpp::Mpp> 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(<F>) {
+ 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..b68d7cc
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Xpp/Xbus.pm
@@ -0,0 +1,213 @@
+package Dahdi::Xpp::Xbus;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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;
+}
+
+my %file_warned; # Prevent duplicate warnings about same file.
+
+sub xbus_attr_path($$) {
+ my ($busnum, @attr) = @_;
+ foreach my $attr (@attr) {
+ my $file = sprintf "$Dahdi::Xpp::sysfs_astribanks/xbus-%02d/$attr", $busnum;
+ unless(-f $file) {
+ my $procfile = sprintf "$Dahdi::proc_xpp_base/XBUS-%02d/$attr", $busnum;
+ warn "$0: warning - OLD DRIVER: missing '$file'. Fall back to '$procfile'\n"
+ unless $file_warned{$attr}++;
+ $file = $procfile;
+ }
+ next unless -f $file;
+ return $file;
+ }
+ return undef;
+}
+
+sub xbus_getattr($$) {
+ my $xbus = shift || die;
+ my $attr = shift || die;
+ $attr = lc($attr);
+ my $file = xbus_attr_path($xbus->num, lc($attr));
+
+ open(F, $file) || die "Failed opening '$file': $!";
+ my $val = <F>;
+ 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_old($) {
+ my $xbus_num = shift || die;
+ my $pat = sprintf "$Dahdi::proc_xpp_base/XBUS-%02d/XPD-[0-9][0-9]", $xbus_num;
+ my @xpdnames;
+
+ #print STDERR "read_xpdnames_old($xbus_num): $pat\n";
+ foreach (glob $pat) {
+ die "Bad /proc entry: '$_'" unless /^.*XPD-([0-9])([0-9])$/;
+ my $name = sprintf("%02d:%1d:%1d", $xbus_num, $1, $2);
+ #print STDERR "\t> $_ ($name)\n";
+ push(@xpdnames, $name);
+ }
+ return @xpdnames;
+}
+
+sub read_xpdnames($) {
+ my $xbus_num = shift || die;
+ my $xbus_dir = "$Dahdi::Xpp::sysfs_astribanks/xbus-$xbus_num";
+ my $pat = sprintf "%s/xbus-%02d/[0-9][0-9]:[0-9]:[0-9]", $Dahdi::Xpp::sysfs_astribanks, $xbus_num;
+ my @xpdnames;
+
+ #print STDERR "read_xpdnames($xbus_num): $pat\n";
+ 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;
+}
+
+my $warned_notransport = 0;
+
+sub new($$) {
+ my $pack = shift or die "Wasn't called as a class method\n";
+ my $num = shift;
+ my $xbus_dir = "$Dahdi::Xpp::sysfs_astribanks/xbus-$num";
+ my $self = {
+ NUM => $num,
+ NAME => "XBUS-$num",
+ SYSFS_DIR => $xbus_dir,
+ };
+ bless $self, $pack;
+ $self->read_attrs;
+ # Get transport related info
+ my $transport = "$xbus_dir/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;
+ if(-e $transport) {
+ @xpdnames = read_xpdnames($num);
+ } else {
+ @xpdnames = read_xpdnames_old($num);
+ warn "$0: warning - OLD DRIVER: missing '$transport'. Fall back to /proc\n"
+ unless $warned_notransport++;
+ }
+ foreach my $xpdstr (@xpdnames) {
+ my ($busnum, $unit, $subunit) = split(/:/, $xpdstr);
+ my $procdir = "$Dahdi::proc_xpp_base/XBUS-$busnum/XPD-$unit$subunit";
+ my $xpd = Dahdi::Xpp::Xpd->new($self, $unit, $subunit, $procdir, "$xbus_dir/$xpdstr");
+ push(@xpds, $xpd);
+ }
+ @{$self->{XPDS}} = sort { $a->id <=> $b->id } @xpds;
+ return $self;
+}
+
+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..6cd49a7
--- /dev/null
+++ b/xpp/perl_modules/Dahdi/Xpp/Xpd.pm
@@ -0,0 +1,387 @@
+package Dahdi::Xpp::Xpd;
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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<Dahdi::Xpp::Xbus>
+
+=head1 id
+
+The two-digit ID in the Xbus. Normally 0I<x> for digital spans and
+I<x>0 for analog ones (for some digit, I<x>).
+
+=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<XPD-10>.
+
+=head1 dir
+
+The ProcFS directory with information about the XPD. e.g.
+C</proc/xpp/XBUS-00/XPD-10>.
+
+=head1 sysfs_dir
+
+The SysFS directory with information about the module. E.g.
+C</sys/bus/astribanks/devices/xbus-00/00:1:0>.
+
+=head1 channels
+
+A list of L<Dahdi::Xpp:Chan> 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<FXS>, C<FXO>, C<BRI_TE>, C<BRI_NT>,
+C<E1>, C<T1>.
+
+=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<TE> or C<NT>.
+
+=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 ($busnum, $unitnum, $subunitnum, @attr) = (
+ $self->xbus->num,
+ $self->unit,
+ $self->subunit,
+ @_);
+ foreach my $attr (@attr) {
+ my $file = sprintf "$Dahdi::Xpp::sysfs_xpds/%02d:%1d:%1d/$attr",
+ $busnum, $unitnum, $subunitnum;
+ unless(-f $file) {
+ my $procfile = sprintf "/proc/xpp/XBUS-%02d/XPD-%1d%1d/$attr",
+ $busnum, $unitnum, $subunitnum;
+ warn "$0: warning - OLD DRIVER: missing '$file'. Fall back to /proc\n"
+ unless $file_warned{$attr}++;
+ $file = $procfile;
+ }
+ next unless -f $file;
+ return $file;
+ }
+ return undef;
+}
+
+# Backward compat plug for old /proc interface...
+sub xpd_old_gettype($) {
+ my $xpd = shift || die;
+ my $summary = "/proc/xpp/" . $xpd->fqn . "/summary";
+ open(F, $summary) or die "Failed to open '$summary': $!";
+ my $head = <F>;
+ close F;
+ chomp $head;
+ $head =~ s/^XPD-\d+\s+\(//;
+ $head =~ s/,.*//;
+ return $head;
+}
+
+sub xpd_old_getspan($) {
+ my $xpd = shift || die;
+ my $dahdi_registration = "/proc/xpp/" . $xpd->fqn . "/dahdi_registration";
+ open(F, $dahdi_registration) or die "Failed to open '$dahdi_registration': $!";
+ my $head = <F>;
+ close F;
+ chomp $head;
+ return $head;
+}
+
+sub xpd_old_getoffhook($) {
+ my $xpd = shift || die;
+ my $summary = "/proc/xpp/" . $xpd->fqn . "/summary";
+ my $channels;
+
+ local $/ = "\n";
+ open(F, "$summary") || die "Failed opening $summary: $!\n";
+ my $head = <F>;
+ chomp $head; # "XPD-00 (BRI_TE ,card present, span 3)"
+ my $offhook;
+ while(<F>) {
+ chomp;
+ if(s/^\s*offhook\s*:\s*//) {
+ s/\s*$//;
+ $offhook = $_;
+ $offhook || die "No channels in '$summary'";
+ last;
+ }
+ }
+ close F;
+ return $offhook;
+}
+
+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 = <F>;
+ 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));
+
+ # Handle special cases for backward compat
+ return xpd_old_gettype($xpd) if $attr eq 'type' and !defined $file;
+ return xpd_old_getspan($xpd) if $attr eq 'span' and !defined $file;
+ return xpd_old_getoffhook($xpd) if $attr eq 'offhook' and !defined $file;
+ 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 = <F>;
+ 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 = <F>;
+ 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 || die;
+ my $unit = shift; # May be zero
+ my $subunit = shift; # May be zero
+ my $procdir = shift || die;
+ my $sysfsdir = shift || die;
+ my $self = {
+ XBUS => $xbus,
+ ID => sprintf("%1d%1d", $unit, $subunit),
+ FQN => $xbus->name . "/" . "XPD-$unit$subunit",
+ UNIT => $unit,
+ SUBUNIT => $subunit,
+ DIR => $procdir,
+ 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, $procdir);
+ return $self;
+}
+
+#------------------------------------
+# static xpd related helper functions
+#------------------------------------
+
+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..ed80f22
--- /dev/null
+++ b/xpp/pic_loader.c
@@ -0,0 +1,276 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * 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 <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <regex.h>
+#include "hexfile.h"
+#include "pic_loader.h"
+#include "debug.h"
+
+#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, "dump:picline[W]", (char *)phead, pack_len);
+
+ ret = send_usb(astribank, buf, pack_len, TIMEOUT);
+ if(ret < 0) {
+ ERR("send_usb failed: %d\n", ret);
+ return ret;
+ }
+ DBG("send_usb: Written %d bytes\n", ret);
+ if (recv_answer) {
+ ret = recv_usb(astribank, 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, "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;
+
+ v = (v[0]) ? v : "Unknown";
+ assert(astribank != NULL);
+ assert(hexdata != NULL);
+ if(!astribank->is_usb2) {
+ ERR("Skip PIC burning (not USB2)\n");
+ return 0;
+ }
+ INFO("Load PIC: %s (version %s)\n", hexdata->fname, hexdata->version_info);
+ basename = pic_basename(hexdata->fname, &card_type);
+ if(!basename) {
+ ERR("Bad PIC filename '%s'. Abort.\n", 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(usb_bulk_read(astribank->handle, astribank->my_ep_in, 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("hexdata finished early (line %d)", 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("Bad line len %d\n", 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("Unexpected TT = %d in line %d\n",
+ 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;
+
+ DBG("Loading %d PIC files...\n", 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("PIC %s burning failed\n", curr);
+ return -ENODEV;
+ }
+ free_hexdata(picdata);
+ }
+ if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) {
+ ERR("PIC end burning failed\n");
+ 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 <oron at actcom.co.il>
+ * 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 <stdint.h>
+#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 <oron at actcom.co.il>
+ * 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 <stdio.h>
+#include <stdarg.h>
+#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 <oron at actcom.co.il>
+# 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;
+ at 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<twinstar> 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<watchdog mode>, 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<on> if the watchdog is triggered in the Atribank or I<off> 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<status> 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<twinstar> 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 <oron at actcom.co.il>
+# 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 <oron at actcom.co.il>
+# 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</etc/dahdi/xpp_order> file that describes the current configuration.
+This is done by running C<dahdi_genconf xpporder>
+
+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..30b3ac5
--- /dev/null
+++ b/xpp/waitfor_xpds
@@ -0,0 +1,93 @@
+#! /bin/sh
+
+# waitfor_xpds: wait until all Astribanks were initialized
+# $Id$
+
+# Written by Oron Peled <oron at actcom.co.il>
+# 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}"
+
+[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf
+
+ab_list() {
+ # Only check /sys info (don't use /proc anymore).
+ ab=`find /sys/bus/astribanks/devices/xbus-*/ -name waitfor_xpds 2> /dev/null || :`
+ echo $ab
+}
+
+# Any hardware?
+if ! dahdi_hardware="`which dahdi_hardware 2>/dev/null`"; then
+ echo >&2 "$0: Missing dahdi_hardware"
+ exit 0
+fi
+if ! astribank_is_starting="`which astribank_is_starting 2>/dev/null`"; then
+ echo >&2 "$0: Missing astribank_is_starting"
+ exit 0
+fi
+if [ "`$dahdi_hardware | grep xpp_usb`" != "" ]; then
+ astribank_is_starting -v -a
+fi
+if ! astribank_is_starting; then
+ exit 0
+fi
+
+# Wait for driver and first device
+echo -n 1>&2 "Astribanks detection "
+tries=10
+while [ ! -e "/sys/bus/astribanks/devices/xbus-00" ]
+do
+ if [ "$tries" -le 0 ]; then
+ echo 1>&2 "TIMEOUT"
+ exit 1
+ fi
+ echo -n 1>&2 "."
+ sleep 1
+ : $((tries-=1))
+done
+echo ""
+
+# Wait for device to stabilize and XPD's to finish initalizations
+echo 1>&2 "Astribanks initializing spans"
+while
+ if ! ab=`ab_list`; then
+ exit 1
+ fi
+ test "$oldab" != "$ab"
+do
+ oldab="$ab"
+ cat $ab
+done
+
+if [ "$XPP_HOTPLUG_DAHDI" = yes ]; then
+ if [ "$CALLED_FROM_ATRIBANK_HOOK" = '' ]; 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
+ fi
+else
+ # Non-hotplug -- Sequential initialization, remove semaphore
+ astribank_is_starting -v -r 1>&2
+fi
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 <oron at actcom.co.il>
+# 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 <number> | chan <number> | xpd <bus num> [<xpd num>] | label <label>}\n";
+}
+
+my $state = shift;
+my $selector = shift;
+usage unless defined($state) and $state =~ /^(on|off|bzzt)$/;
+usage unless defined($selector) and $selector =~ /^(span|chan|xpd|label)$/i;
+
+my $xpd;
+my @blinklist;
+my @channels;
+
+if($selector =~ /^span$/i) {
+ my $number = shift;
+ usage unless defined($number) and $number =~ /^\d+/;
+ my $span = Dahdi::Span::by_number($number);
+ die "Unkown Span $number\n" unless $span;
+ $xpd = Dahdi::Xpp::xpd_of_span($span);
+ die "Span $number is not an XPD\n" unless defined $xpd;
+ my $xpdname = $xpd->fqn;
+ my $connector = $xpd->xbus->connector;
+ die "$xpdname is not connected\n" unless defined $connector;
+ push(@blinklist, $xpd);
+ my @chans = $span->chans();
+ @channels = join(' ', map { $_->num } @chans);
+ printf "Using %s (connected via $connector): channels @channels\n", $xpd->fqn;
+} elsif($selector =~ /^chan$/i) {
+ my $channo = shift;
+ usage unless defined($channo) and $channo =~ /^\d+/;
+ my @spans = Dahdi::spans();
+ my @chans = map { $_->chans() } @spans;
+ my ($chan) = grep { $_->num eq $channo } @chans;
+ die "Channel $channo was not found\n" unless defined $chan;
+ die "Cannot blink Input ports\n" if $chan->type eq 'IN';
+ die "Cannot blink Output ports\n" if $chan->type eq 'OUT';
+ push(@blinklist, $chan);
+} elsif($selector =~ /^xpd$/i) {
+ my $busnum = shift;
+ my $xpdnum = shift;
+ my $linenum = shift;
+ usage unless defined($busnum) and $busnum =~ /^\d+/;
+ my $xbus = Dahdi::Xpp::Xbus::by_number($busnum);
+ die "Unkown XBUS number $busnum\n" unless defined $xbus;
+ if(defined $xpdnum) {
+ usage unless $xpdnum =~ /^\d+/;
+ $xpd = $xbus->get_xpd_by_number($xpdnum);
+ die "Unkown XPD number $xpdnum on XBUS number $busnum\n" unless defined $xpd;
+ if(defined $linenum) {
+ usage unless $linenum =~ /^\d+/;
+ my $lines = $xpd->lines;
+ my $l = @{$lines}[$linenum];
+ die "Bad line number $linenum on XPD $xpd->fqn\n" unless defined $l;
+ push(@blinklist, $l);
+ } else {
+ push(@blinklist, $xpd);
+ }
+ } else {
+ @blinklist = $xbus->xpds;
+ die "XBUS number $busnum has no XPDS!\n" unless @blinklist;
+ }
+} elsif($selector =~ /^label$/i) {
+ my $label = shift;
+ usage unless defined($label);
+ my $xbus = Dahdi::Xpp::Xbus::by_label($label);
+ die "Unkown XBUS label $label\n" unless defined $xbus;
+ @blinklist = $xbus->xpds;
+ die "XBUS label '$label' has no XPDS!\n" unless @blinklist;
+}
+
+if($state eq 'on') {
+ $_->blink(1) foreach (@blinklist);
+} elsif($state eq 'off') {
+ $_->blink(0) foreach (@blinklist);
+} elsif($state eq 'bzzt') {
+ $_->blink(1) foreach (@blinklist);
+ sleep 1;
+ $_->blink(0) foreach (@blinklist);
+}
+
+__END__
+
+=head1 NAME
+
+xpp_blink - Blink the leds of a specified XPD
+
+=head1 SYNOPSIS
+
+xpp_blink {on|off|bzzt} {span <number> | chan <number> | xpd <bus num> [<xpd num> [<lineno>]]}
+
+=head1 DESCRIPTION
+
+Blink all the leds of an XPD.
+
+=head2 Blink mode:
+
+=over
+
+=item on
+
+Turn on constant blink
+
+=item off
+
+Turn off blink
+
+=item bzzt
+
+Blink briefly for 1 second.
+
+=back
+
+=head2 Selector:
+
+=over
+
+=item span
+
+Select by span number. This only work for XPD registered to dahdi.
+
+will also print the dahdi channels of the span and the xbus/xpd this
+span represents.
+
+=item chan
+
+Select by channel number. This only work for XPD registered to dahdi.
+
+=item xpd
+
+Select by xbus + xpd numbers. If only xbus number is given, all the
+XPDs of the selected xbus (Astribank) are blinked.
+
+=item label
+
+Select by xbus label. Affect the whole Astribank.
+
+=back
+
+=head1 EXAMPLES
+
+ $ xpp_blink bzzt span 2
+ Using XBUS-04/XPD-10 (connected via usb-0000:00:1d.7-1): channels 15 16 17 18 19 20 21 22
+
+ $ xpp_blink bzzt chan 18
+
+ $ xpp_blink on xpd 0 1 5
+
+ $ xpp_blink off xpd 0
+
+ $ xpp_blink bzzt label 'usb:00000238'
diff --git a/xpp/xpp_fxloader b/xpp/xpp_fxloader
new file mode 100644
index 0000000..284c5ab
--- /dev/null
+++ b/xpp/xpp_fxloader
@@ -0,0 +1,364 @@
+#!/bin/bash
+
+# xpp_fxloader: load Xorcom Astribank (XPP) firmware
+# $Id$
+#
+# Written by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+# Copyright (C) 2006-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 script can be run manually or from hotplug/udev.
+#
+# Firmware files should be located in $FIRMWARE_DIR which defaults:
+# 1. /usr/share/dahdi
+# 2. Can be overidden by setting $FIRMWARE_DIR in the environment
+# 3. Can be overidden by setting $FIRMWARE_DIR in /etc/dahdi/init.conf
+#
+# Manual Run
+# ##########
+#
+# path/to/xpp_fxloader load
+#
+# Make sure the firmware files are in $FIRMWARE_DIR
+#
+
+set -e
+
+# Make sure fxload is in the path:
+PATH="$PATH:/usr/local/sbin:/sbin:/usr/sbin"
+export PATH
+
+me=`basename $0`
+dir=`dirname $0`
+PATH="$dir:$PATH"
+DEFAULTS="/etc/dahdi/init.conf"
+
+if [ -t 2 ]; then
+ LOGGER="logger -i -t '$me' -s"
+else
+ LOGGER="logger -i -t '$me'"
+fi
+
+debug() {
+ [ "$DEBUG" != "" ] && $LOGGER "$@"
+ return 0
+}
+
+USBFS_PREFIX=/proc/bus/usb
+DEVUSB_PREFIX=/dev/bus/usb
+USB_PREFIX=
+
+FIRMWARE_DIR="${FIRMWARE_DIR:-/usr/share/dahdi}"
+ASTRIBANK_HEXLOAD=${ASTRIBANK_HEXLOAD:-/usr/sbin/astribank_hexload}
+ASTRIBANK_TOOL=${ASTRIBANK_TOOL:-/usr/sbin/astribank_tool}
+XPP_UDEV_SLEEP_TIME="${XPP_UDEV_SLEEP_TIME:-15}"
+
+USB_FW="${USB_FW:-USB_FW.hex}"
+
+if [ -r "$DEFAULTS" ]; then
+ . "$DEFAULTS"
+fi
+
+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
+}
+
+run_astribank_hexload() {
+ debug "Running: $ASTRIBANK_HEXLOAD $*"
+ $ASTRIBANK_HEXLOAD "$@" | $LOGGER
+ status=$PIPESTATUS
+ if [ $status != 0 ]; then
+ $LOGGER "$ASTRIBANK_HEXLOAD failed with status $status"
+ exit 77
+ fi
+}
+
+run_astribank_tool() {
+ debug "Running: $ASTRIBANK_TOOL $*"
+ $ASTRIBANK_TOOL "$@" | $LOGGER
+ status=$PIPESTATUS
+ if [ $status != 0 ]; then
+ $LOGGER "$ASTRIBANK_TOOL failed with status $status"
+ exit 77
+ 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)
+ debug "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev"
+ run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
+ done
+}
+
+load_fw_device() {
+ dev=$1
+ fw=$2
+ debug "FPGA loading $fw into $dev"
+ run_astribank_hexload -D "$dev" -F "$FIRMWARE_DIR/$fw"
+ pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-4].hex`
+ debug "PIC burning into $dev: $pic_files"
+ run_astribank_hexload -D "$dev" -p $pic_files
+ run_astribank_tool -D "$dev" -n # Do renumeration!
+ debug "PIC burning finished $pic_files"
+}
+
+#
+# Use in manual loading. Parallelize loading
+# firmwares to all of our devices
+#
+firmware_by_id() {
+ v_id=$1
+ p_id=$2
+ fw=$3
+
+ devices=`find_dev $v_id $p_id`
+ childs=""
+ for dev in $devices
+ do
+ (
+ set -e
+
+ load_fw_device "$dev" "$fw"
+ sleep_if_race
+ ) &
+ childs="$childs $!"
+ sleep 0.4
+ done
+ # Wait for specific childs to get their exit status
+ wait $childs
+}
+
+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"
+}
+
+reset_fpga() {
+ totaldevs=`numdevs e4e4 '11[3456][0123]'`
+ devices=`find_dev e4e4 '11[3456][12]'`
+ debug "Reseting devices [$totaldevs devices]"
+ for dev in $devices
+ do
+ debug "Resetting FPGA Firmware on $dev"
+ sleep_if_race
+ run_astribank_tool -D "$dev" -r full 2>&1 >/dev/null
+ done
+ if [ "$1" = 'wait' ]; then
+ wait_renumeration $totaldevs e4e4 '11[3456][03]'
+ fi
+}
+
+usage() {
+ echo "$0: Astribank firmware loading script."
+ echo "Usage: "
+ echo "$0 load : manual firmware loading."
+ echo "$0 usb : manual firmware loading: USB firmware only."
+ echo "$0 help : this text."
+}
+
+# We have a potential astribank
+astribank_is_starting -a
+
+#########################
+##
+## Manual run
+##
+
+# to run manually, pass the parameter 'xppdetect'
+case "$1" in
+udev)
+ # Various kernel versions use different sets of variables.
+ # Here we want to make sure we have 'DEVICE' and 'PRODUCT' set
+ # up. DEVICE is now deprecated in favour of DEVNAME. It will
+ # likely to contain an invalid name if /proc/bus/usb is not
+ # mounted. So it needs further cooking.
+ DEVICE="${DEVNAME:-$DEVICE}"
+ case "$DEVICE" in /proc/*) DEVICE="/dev${DEVICE#/proc}" ;; esac
+ # PRODUCT contains 'vendor_id'/'product_id'/'version' . We
+ # currently pass it as a parameter, but might as well get it
+ # from the envirnment.
+ PRODUCT="${PRODUCT:-$2}"
+ # skip on to the rest of the script. Don't exit.
+ ;;
+reset-wait)
+ reset_fpga wait
+ ;;
+reset)
+ reset_fpga
+ ;;
+xppdetect|load|usb)
+ numdevs=`numdevs e4e4 '11[3456][013]'`
+ $LOGGER -- "--------- FIRMWARE LOADING: ($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 1163 $USB_FW
+ wait_renumeration $numdevs e4e4 '11[3456]1'
+ if [ "$1" != 'usb' ]
+ then
+ firmware_by_id e4e4 1131 FPGA_FXS.hex
+ firmware_by_id e4e4 1141 FPGA_1141.hex
+ firmware_by_id e4e4 1151 FPGA_1151.hex
+ firmware_by_id e4e4 1161 FPGA_1161.hex
+ wait_renumeration $numdevs e4e4 '11[3456]2'
+ fi
+
+ sleep 3 # Let it stabilize
+ $LOGGER -- "--------- FIRMWARE IS LOADED"
+ exit 0
+ ;;
+help)
+ usage
+ exit 0
+ ;;
+*)
+ if [ "$ACTION" = '' ]; then # not called from hotplug
+ echo "$0: Error: unknown command \"$1\""
+ echo ''
+ usage
+ exit 1
+ fi
+ ;;
+esac
+
+#########################
+##
+## Hotplug run
+##
+
+# allow disabling automatic hotplugging:
+if [ "$XPP_HOTPLUG_DISABLED" != '' ]; then
+ $LOGGER -p kern.info "Exiting... XPP_HOTPLUG_DISABLED"
+ exit 0
+fi
+
+if [ "$ACTION" != add ]; then
+ exit 0;
+fi
+
+# This procedure is run in the background to do the actual work of loading the
+# firmware. Running it in the background allows udev to continue doing other tasks
+# and thus provide a faster startup.
+#
+# On some systems (e.g. CentOS 5) we get the relevant udev event before the device
+# file is ready. Which is why we want the background process to wait a bit first.
+udev_delayed_load() {
+ sleep 0.2
+ # Make sure the new device is writable:
+ usb_dev_writable=0
+ for i in `seq $XPP_UDEV_SLEEP_TIME`; do
+ if [ -w "$DEVICE" ]; then
+ usb_dev_writable=1;
+ break;
+ fi
+ sleep 1
+ done
+ if [ $usb_dev_writable != 1 ]; then
+ $LOGGER "Device $DEVICE not writable. Can't load firmware."
+ return;
+ fi
+
+ $LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
+ prod_id=`echo "$PRODUCT" | cut -d/ -f2`
+ case "$PRODUCT" in
+ e4e4/11[3456]0/*|e4e4/1163/*)
+ FIRM_USB="$FIRMWARE_DIR/$USB_FW"
+ $LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
+ run_fxload -D "$DEVICE" -I "$FIRM_USB"
+ ;;
+ e4e4/11[3456]1/*)
+ if [ "$prod_id" = 1131 ]; then
+ FIRM_FPGA="FPGA_FXS.hex" # Legacy
+ else
+ FIRM_FPGA="FPGA_$prod_id.hex"
+ fi
+ sleep_if_race
+ load_fw_device "$DEVICE" "$FIRM_FPGA"
+ ;;
+ esac
+}
+
+udev_delayed_load &
+
diff --git a/xpp/xpp_fxloader.usermap b/xpp/xpp_fxloader.usermap
new file mode 100644
index 0000000..8c14b72
--- /dev/null
+++ b/xpp/xpp_fxloader.usermap
@@ -0,0 +1,10 @@
+# module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info
+xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1130 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1131 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1140 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1141 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1150 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1151 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1160 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1161 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
diff --git a/xpp/xpp_modprobe b/xpp/xpp_modprobe
new file mode 100644
index 0000000..e972bc3
--- /dev/null
+++ b/xpp/xpp_modprobe
@@ -0,0 +1,10 @@
+# Some debugging options for the brave of heart:
+#options dahdi debug=1
+#options wcfxo debug=1
+#options xpp debug=1
+#options xpp_usb debug=1
+#options xpd_fxs debug=1
+#options xpd_fxo debug=1
+
+# For pre-loading of card modules (e.g: xpp_fxs)
+#install xpp_usb /sbin/modprobe xpd_fxs && /sbin/modprobe --ignore-install xpp_usb
diff --git a/xpp/xpp_sync b/xpp/xpp_sync
new file mode 100755
index 0000000..41cfd61
--- /dev/null
+++ b/xpp/xpp_sync
@@ -0,0 +1,226 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# 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::Xpp;
+use Dahdi::Xpp::Xbus;
+
+my $sync;
+my $autoselect;
+
+sub usage() {
+ print
+ "$0: show / set Astribank sync source\n".
+ "\n".
+ "Usage: $0 [-v] Show sync source.\n".
+ " $0 [-v] <auto|NN|dahdi> Set sync source.\n".
+ "";
+ exit 1;
+}
+
+my %opts;
+getopts('hv', \%opts) || usage;
+
+$opts{h} && usage;
+if(@ARGV == 1) {
+ $sync = shift;
+ $autoselect = 1 if $sync =~ /^auto$/i;
+}
+
+
+sub get_sorted_xpds() {
+ my @good_xpds;
+
+ foreach my $xbus (Dahdi::Xpp::xbuses) {
+ next unless $xbus->status eq 'CONNECTED';
+ foreach my $xpd ($xbus->xpds()) {
+ my $isreg = $xpd->dahdi_registration();
+ if(!defined($isreg)) { # Failure
+ printf STDERR "%s: Failed %s\n", $xpd->fqn, $!;
+ next;
+ }
+ next unless $isreg; # Skip unregistered XPDs
+ push(@good_xpds, $xpd);
+ }
+ }
+ my @xpd_prio = Dahdi::Xpp::Xpd::xpds_by_rank(@good_xpds);
+ Dahdi::Xpp::Xpd::show_xpd_rank(@xpd_prio) if $opts{v};
+ return @xpd_prio;
+}
+
+sub do_select(@) {
+ my $found;
+
+ foreach my $xpd (@_) {
+ my $xbus = $xpd->xbus;
+ my $busnum = $xbus->name;
+ die "Uknown bus name" unless $busnum;
+ $busnum =~ s/XBUS-//;
+ die "bad bus name" unless $busnum =~ /^\d+$/;
+ #printf "Setting sync: %-10s (%s)\n", $xpd->fqn, $xpd->type;
+ if(Dahdi::Xpp::sync($busnum)) {
+ #print "SET $busnum\n";
+ $found = 1;
+ last;
+ } else {
+ print STDERR "Failed to set $busnum: $!\n";
+ }
+ }
+}
+
+sub do_set($) {
+ my $sync = shift;
+ die "Failed to set sync to '$sync'" unless Dahdi::Xpp::sync($sync);
+}
+
+sub unique_xbus(@) {
+ my %seen;
+
+ grep { !$seen{$_->xbus}++; } @_;
+}
+
+my $curr_sync = Dahdi::Xpp::sync;
+my @sync_xpds = unique_xbus(get_sorted_xpds());
+
+sub show_sync() {
+ foreach my $xpd (@sync_xpds) {
+ my $xbus = $xpd->xbus;
+ my $xpdstr = '[ ' . $xbus->pretty_xpds . ' ]';
+ my $label = '[' . $xbus->label() . ']';
+ my $connector = '(' . $xbus->connector . ')';
+ my $mark = ($curr_sync =~ /^\d+$/ and $xbus->num == $curr_sync)?"+":"";
+ my $padding = ' ' x (40 - length $xpdstr);
+ printf " %1s %s %-25s %-14s %s\n", $mark, $xbus->name, $connector, $label, $xpdstr;
+ }
+}
+
+sub check_fxo_host_sync() {
+ my @host_synced_xpds = grep { $_->xbus->num() ne $curr_sync } @sync_xpds;
+ my @host_synced_fxos = grep($_->type eq 'FXO', @host_synced_xpds);
+ if(@host_synced_fxos) {
+ my @bad_xbus = map { $_->xbus } unique_xbus(@host_synced_fxos);
+ our $lines = join("\n\t", map { $_->name } @bad_xbus);
+ print STDERR <<"END";
+==================================================
+WARNING: FXO which is not the syncer cause bad PCM
+ Affected Astribanks are:
+--------------------------------------------------
+ $lines
+==================================================
+END
+ }
+}
+
+if(defined $sync) {
+ if($autoselect) {
+ do_select(@sync_xpds);
+ } else {
+ $sync = uc($sync);
+ do_set($sync);
+ }
+ $curr_sync = Dahdi::Xpp::sync;
+ #print "New sync: ", Dahdi::Xpp::sync, "\n";
+} else {
+ print "Current sync: ", $curr_sync, "\n";
+ print "Best Available Syncers:\n";
+ show_sync;
+ check_fxo_host_sync;
+}
+
+__END__
+
+=head1 NAME
+
+xpp_sync - Handle sync selection of Xorcom Astribanks.
+
+=head1 SYNOPSIS
+
+xpp_sync <auto|dahdi|nn>
+
+xpp_sync [-v]
+
+=head1 DESCRIPTION
+
+On a normal operation one Astribank device provides timing for all the
+other Astribank devices.
+
+When run without parameters, xpp_sync will display a list of Astribanks
+(xbuses) that are connected and registered as Dahdi spans. The current
+xpp sync master will be marked.
+
+If you this an Astribank is connected and yet it does not appear on the
+output of xpp_sync, it may be unregistered. Try running dahdi_registration .
+
+=head2 Parameters
+
+=over
+
+=item auto
+
+Automatically selects the best Astribank for syncing.
+
+=item dahdi
+
+Gets synchronization from the Dahdi sync master.
+
+=item nn
+
+Sets XBUS-I<nn> as sync source.
+
+=item -v
+
+Also print the numeric xpp sync rank.
+
+=back
+
+(Parameter name is case-insensitive)
+
+=head2 Example output:
+
+ Setting SYNC
+ Current sync: 01
+ Best Available Syncers:
+ + XBUS-01 (usb-0000:00:10.4-3) [usb:12345678] [ PRI_TE PRI_NT PRI_TE PRI_NT ]
+ XBUS-00 (usb-0000:00:10.4-2) [usb:QA-01] [ FXS FXO ]
+ ==================================================
+ WARNING: FXO which is not the syncer cause bad PCM
+ Affected Astribanks are:
+ --------------------------------------------------
+ XBUS-00
+ ==================================================
+
+In this example we see that the recommended xpp sync master is XBUS-02 -
+it is the first on the list. It is also the actual syncer, as we can see
+from the '+' beside it.
+
+xpp_sync is normally called from the dahdi init.d script.
+The parameter it is called with defaults to
+I<auto>, but it is possible to override that parameter (e.g: set it to
+I<dahdi>) through the value of XPP_SYNC in /etc/dahdi/init.conf .
+
+=head1 FILES
+
+=over
+
+=item /proc/xpp/sync
+
+(Deprecated: no longer supported)
+xpp_sync is essentially a nicer interface to /proc/xpp/sync . That file
+shows the current xpp sync master (and in what format you need to write
+to it to set the 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/zonedata.c b/zonedata.c
new file mode 100644
index 0000000..d15f276
--- /dev/null
+++ b/zonedata.c
@@ -0,0 +1,983 @@
+/*
+ * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * Working with the "Tormenta ISA" Card
+ *
+ * Primary Author: Mark Spencer <markster at digium.com>
+ *
+ * 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, "413+438" },
+ { DAHDI_TONE_BUSY, "425/375,0/375" },
+ { DAHDI_TONE_RINGTONE, "413+438/400,0/200,413+438/400,0/2000" },
+ /* XXX Congestion: Should reduce by 10 db every other cadence XXX */
+ { DAHDI_TONE_CONGESTION, "425/375,0/375,420/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" },
+ },
+ .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" },
+ },
+ .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 = -1 }
+};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/dahdi-tools.git
More information about the Pkg-voip-commits
mailing list