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
This commit is contained in:
committed by
Shaun Ruffell
parent
a885b2c253
commit
466357f5c2
341
LICENSE
Normal file
341
LICENSE
Normal file
@@ -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.
|
||||
504
LICENSE.LGPL
Normal file
504
LICENSE.LGPL
Normal file
@@ -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!
|
||||
|
||||
|
||||
420
Makefile
Normal file
420
Makefile
Normal file
@@ -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
|
||||
-@menuselect/cmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
|
||||
|
||||
gmenuselect: menuselect/gmenuselect menuselect-tree
|
||||
-@menuselect/gmenuselect menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!"
|
||||
|
||||
nmenuselect: menuselect/nmenuselect menuselect-tree
|
||||
-@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
|
||||
233
README
Normal file
233
README
Normal file
@@ -0,0 +1,233 @@
|
||||
DAHDI Telephony Interface Driver
|
||||
=================================
|
||||
Asterisk Development Team <asteriskteam@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]
|
||||
103
UPGRADE.txt
Normal file
103
UPGRADE.txt
Normal file
@@ -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.
|
||||
1113
acinclude.m4
Normal file
1113
acinclude.m4
Normal file
File diff suppressed because it is too large
Load Diff
102
autoconfig.h.in
Normal file
102
autoconfig.h.in
Normal file
@@ -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
|
||||
17
bittest.h
Normal file
17
bittest.h
Normal file
@@ -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;
|
||||
}
|
||||
13
blacklist.sample
Normal file
13
blacklist.sample
Normal file
@@ -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
|
||||
48
bootstrap.sh
Executable file
48
bootstrap.sh
Executable file
@@ -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
|
||||
90
build_tools/dahdi_svn_tarball
Executable file
90
build_tools/dahdi_svn_tarball
Executable file
@@ -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
|
||||
|
||||
147
build_tools/dump_sys_state
Executable file
147
build_tools/dump_sys_state
Executable file
@@ -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@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`
|
||||
|
||||
11
build_tools/make_firmware_object.in
Executable file
11
build_tools/make_firmware_object.in
Executable file
@@ -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
|
||||
7
build_tools/make_tree
Executable file
7
build_tools/make_tree
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "<?xml version=\"1.0\"?>"
|
||||
echo
|
||||
echo "<menu name=\"DAHDI Tools Selection\">"
|
||||
cat dahdi.xml
|
||||
echo "</menu>"
|
||||
56
build_tools/make_version
Executable file
56
build_tools/make_version
Executable file
@@ -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
|
||||
10
build_tools/make_version_c
Executable file
10
build_tools/make_version_c
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
cat << END
|
||||
/*
|
||||
* version.c
|
||||
* Automatically generated
|
||||
*/
|
||||
|
||||
const char dahdi_tools_version[] = "DAHDI Tools Version - ${TOOLSVERSION}";
|
||||
|
||||
END
|
||||
2
build_tools/menuselect-deps.in
Normal file
2
build_tools/menuselect-deps.in
Normal file
@@ -0,0 +1,2 @@
|
||||
LIBNEWT=@PBX_NEWT@
|
||||
HDLC=@PBX_HDLC@
|
||||
80
build_tools/test_kernel_git
Executable file
80
build_tools/test_kernel_git
Executable file
@@ -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
|
||||
41
build_tools/uninstall-modules
Executable file
41
build_tools/uninstall-modules
Executable file
@@ -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
|
||||
1526
config.guess
vendored
Executable file
1526
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1658
config.sub
vendored
Executable file
1658
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
215
configure.ac
Normal file
215
configure.ac
Normal file
@@ -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 ***)
|
||||
333
dahdi.init
Executable file
333
dahdi.init
Executable file
@@ -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
|
||||
|
||||
26
dahdi.xml
Normal file
26
dahdi.xml
Normal file
@@ -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>
|
||||
1662
dahdi_cfg.c
Normal file
1662
dahdi_cfg.c
Normal file
File diff suppressed because it is too large
Load Diff
55
dahdi_diag.c
Normal file
55
dahdi_diag.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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);
|
||||
}
|
||||
236
dahdi_maint.c
Normal file
236
dahdi_maint.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Performance and Maintenance utility
|
||||
*
|
||||
* Written by Russ Meyerriecks <rmeyerriecks@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;
|
||||
}
|
||||
783
dahdi_monitor.c
Normal file
783
dahdi_monitor.c
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* Monitor a DAHDI Channel
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@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;
|
||||
}
|
||||
205
dahdi_scan.c
Normal file
205
dahdi_scan.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Scan and output information about DAHDI spans and ports.
|
||||
*
|
||||
* Written by Brandon Kruse <bkruse@digium.com>
|
||||
* and Kevin P. Fleming <kpfleming@digium.com>
|
||||
* Copyright (C) 2007 Digium, Inc.
|
||||
*
|
||||
* Based on zttool written by Mark Spencer <markster@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);
|
||||
}
|
||||
65
dahdi_speed.c
Normal file
65
dahdi_speed.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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++;
|
||||
}
|
||||
}
|
||||
164
dahdi_test.c
Normal file
164
dahdi_test.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
541
dahdi_tool.c
Normal file
541
dahdi_tool.c
Normal file
@@ -0,0 +1,541 @@
|
||||
/*
|
||||
* Configuration program for Zapata Telephony Interface
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@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;
|
||||
}
|
||||
21
dahdi_tools_version.h
Normal file
21
dahdi_tools_version.h
Normal file
@@ -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[];
|
||||
70
doc/dahdi_cfg.8
Normal file
70
doc/dahdi_cfg.8
Normal file
@@ -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@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.
|
||||
52
doc/dahdi_diag.8
Normal file
52
doc/dahdi_diag.8
Normal file
@@ -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@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.
|
||||
43
doc/dahdi_monitor.8
Normal file
43
doc/dahdi_monitor.8
Normal file
@@ -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@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.
|
||||
101
doc/dahdi_scan.8
Normal file
101
doc/dahdi_scan.8
Normal file
@@ -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@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.
|
||||
49
doc/dahdi_test.8
Normal file
49
doc/dahdi_test.8
Normal file
@@ -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@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.
|
||||
25
doc/dahdi_tool.8
Normal file
25
doc/dahdi_tool.8
Normal file
@@ -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@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.
|
||||
207
doc/fxotune.8
Normal file
207
doc/fxotune.8
Normal file
@@ -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@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.
|
||||
60
doc/fxstest.8
Normal file
60
doc/fxstest.8
Normal file
@@ -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@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
|
||||
44
doc/patgen.8
Normal file
44
doc/patgen.8
Normal file
@@ -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@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.
|
||||
49
doc/pattest.8
Normal file
49
doc/pattest.8
Normal file
@@ -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@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.
|
||||
119
fxotune.h
Normal file
119
fxotune.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* fxotune.h -- data structures and associated definitions for fxotune.c
|
||||
*
|
||||
* By Matthew Fredrickson <creslin@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},
|
||||
};
|
||||
|
||||
337
fxstest.c
Normal file
337
fxstest.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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;
|
||||
}
|
||||
135
hdlcgen.c
Normal file
135
hdlcgen.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
233
hdlcstress.c
Normal file
233
hdlcstress.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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
|
||||
}
|
||||
|
||||
}
|
||||
302
hdlctest.c
Normal file
302
hdlctest.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
136
hdlcverify.c
Normal file
136
hdlcverify.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
ifup-hdlc
Normal file
39
ifup-hdlc
Normal file
@@ -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
|
||||
19
init.conf.sample
Normal file
19
init.conf.sample
Normal file
@@ -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
|
||||
323
install-sh
Executable file
323
install-sh
Executable file
@@ -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:
|
||||
47
makeopts.in
Normal file
47
makeopts.in
Normal file
@@ -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@
|
||||
4
modprobe.conf.sample
Normal file
4
modprobe.conf.sample
Normal file
@@ -0,0 +1,4 @@
|
||||
# You should place any module parameters for your DAHDI modules here
|
||||
# Example:
|
||||
#
|
||||
# options wctdm24xxp latency=6
|
||||
48
modules.sample
Normal file
48
modules.sample
Normal file
@@ -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
|
||||
|
||||
164
patgen.c
Normal file
164
patgen.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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
|
||||
}
|
||||
|
||||
}
|
||||
295
patlooptest.c
Normal file
295
patlooptest.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
170
pattest.c
Normal file
170
pattest.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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
|
||||
}
|
||||
|
||||
}
|
||||
29
ppp/Makefile
Normal file
29
ppp/Makefile
Normal file
@@ -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
|
||||
293
ppp/dahdi.c
Normal file
293
ppp/dahdi.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/* dahdi.c - pppd plugin to implement PPP over DAHDI HDLC channel.
|
||||
*
|
||||
* Copyright 2002 Digium, Inc.
|
||||
* Mark Spencer <markster@digium.inc>
|
||||
*
|
||||
* Borrows from PPPoE by Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
|
||||
* Jamal Hadi Salim <hadi@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
|
||||
};
|
||||
|
||||
704
sethdlc.c
Normal file
704
sethdlc.c
Normal file
@@ -0,0 +1,704 @@
|
||||
/*
|
||||
* sethdlc.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2002 Krzysztof Halasa <khc@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@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);
|
||||
}
|
||||
330
system.conf.sample
Normal file
330
system.conf.sample
Normal file
@@ -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
|
||||
#
|
||||
78
timertest.c
Normal file
78
timertest.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
* Based on previous works, designs, and architectures conceived and
|
||||
* written by Jim Dixon <jim@lambdatel.com>.
|
||||
*
|
||||
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Primary Author: Mark Spencer <markster@digium.com>
|
||||
* Radio Support by Jim Dixon <jim@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);
|
||||
}
|
||||
518
tonezone.c
Normal file
518
tonezone.c
Normal file
@@ -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@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;
|
||||
}
|
||||
90
tonezone.h
Normal file
90
tonezone.h
Normal file
@@ -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@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
|
||||
48
wavformat.h
Normal file
48
wavformat.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* wavformat.h -- data structures and associated definitions for wav files
|
||||
*
|
||||
* By Michael Spiceland (mspiceland@digium.com)
|
||||
*
|
||||
* (C) 2009 Digium, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*/
|
||||
|
||||
#ifndef WAVFORMAT_H
|
||||
#define WAVFORMAT_H
|
||||
|
||||
#include <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
|
||||
140
xpp/Makefile
Normal file
140
xpp/Makefile
Normal file
@@ -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
|
||||
1656
xpp/README.Astribank
Normal file
1656
xpp/README.Astribank
Normal file
File diff suppressed because it is too large
Load Diff
70
xpp/astribank_allow.8
Normal file
70
xpp/astribank_allow.8
Normal file
@@ -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
|
||||
384
xpp/astribank_allow.c
Normal file
384
xpp/astribank_allow.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il> and
|
||||
* Alex Landau <alex.landau@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;
|
||||
}
|
||||
66
xpp/astribank_hexload.8
Normal file
66
xpp/astribank_hexload.8
Normal file
@@ -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@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.
|
||||
229
xpp/astribank_hexload.c
Normal file
229
xpp/astribank_hexload.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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;
|
||||
}
|
||||
114
xpp/astribank_hook
Executable file
114
xpp/astribank_hook
Executable file
@@ -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
|
||||
|
||||
100
xpp/astribank_is_starting.8
Normal file
100
xpp/astribank_is_starting.8
Normal file
@@ -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@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.
|
||||
190
xpp/astribank_is_starting.c
Normal file
190
xpp/astribank_is_starting.c
Normal file
@@ -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;
|
||||
}
|
||||
86
xpp/astribank_tool.8
Normal file
86
xpp/astribank_tool.8
Normal file
@@ -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@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.
|
||||
274
xpp/astribank_tool.c
Normal file
274
xpp/astribank_tool.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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;
|
||||
}
|
||||
150
xpp/astribank_upgrade
Executable file
150
xpp/astribank_upgrade
Executable file
@@ -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@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"
|
||||
555
xpp/astribank_usb.c
Normal file
555
xpp/astribank_usb.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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;
|
||||
}
|
||||
|
||||
103
xpp/astribank_usb.h
Normal file
103
xpp/astribank_usb.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef ASTRIBANK_USB_H
|
||||
#define ASTRIBANK_USB_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@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 */
|
||||
265
xpp/dahdi.cgi
Executable file
265
xpp/dahdi.cgi
Executable file
@@ -0,0 +1,265 @@
|
||||
#! /usr/bin/perl -wT
|
||||
|
||||
# Written by Tzafrir Cohen <tzafrir.cohen@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 ),
|
||||
);
|
||||
23
xpp/dahdi_drivers
Executable file
23
xpp/dahdi_drivers
Executable file
@@ -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.
|
||||
196
xpp/dahdi_genconf
Executable file
196
xpp/dahdi_genconf
Executable file
@@ -0,0 +1,196 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# Written by Oron Peled <oron@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
|
||||
196
xpp/dahdi_hardware
Executable file
196
xpp/dahdi_hardware
Executable file
@@ -0,0 +1,196 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# Written by Oron Peled <oron@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;
|
||||
@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
|
||||
|
||||
166
xpp/dahdi_registration
Executable file
166
xpp/dahdi_registration
Executable file
@@ -0,0 +1,166 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# Written by Oron Peled <oron@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;
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
53
xpp/debug.c
Normal file
53
xpp/debug.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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");
|
||||
}
|
||||
|
||||
46
xpp/debug.h
Normal file
46
xpp/debug.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@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 */
|
||||
86
xpp/fpga_load.8
Normal file
86
xpp/fpga_load.8
Normal file
@@ -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@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.
|
||||
1052
xpp/fpga_load.c
Normal file
1052
xpp/fpga_load.c
Normal file
File diff suppressed because it is too large
Load Diff
169
xpp/genconf_parameters
Normal file
169
xpp/genconf_parameters
Normal file
@@ -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
|
||||
568
xpp/hexfile.c
Normal file
568
xpp/hexfile.c
Normal file
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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;
|
||||
}
|
||||
87
xpp/hexfile.h
Normal file
87
xpp/hexfile.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Written by Oron Peled <oron@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
|
||||
110
xpp/lsdahdi
Executable file
110
xpp/lsdahdi
Executable file
@@ -0,0 +1,110 @@
|
||||
#! /usr/bin/perl -w
|
||||
#
|
||||
# Written by Oron Peled <oron@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.
|
||||
344
xpp/mpp.h
Normal file
344
xpp/mpp.h
Normal file
@@ -0,0 +1,344 @@
|
||||
#ifndef MPP_H
|
||||
#define MPP_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@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 */
|
||||
1109
xpp/mpp_funcs.c
Normal file
1109
xpp/mpp_funcs.c
Normal file
File diff suppressed because it is too large
Load Diff
80
xpp/mpp_funcs.h
Normal file
80
xpp/mpp_funcs.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef MPP_FUNCS_H
|
||||
#define MPP_FUNCS_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@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 */
|
||||
79
xpp/perl_modules/Dahdi.pm
Normal file
79
xpp/perl_modules/Dahdi.pm
Normal file
@@ -0,0 +1,79 @@
|
||||
package Dahdi;
|
||||
#
|
||||
# Written by Oron Peled <oron@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;
|
||||
264
xpp/perl_modules/Dahdi/Chans.pm
Normal file
264
xpp/perl_modules/Dahdi/Chans.pm
Normal file
@@ -0,0 +1,264 @@
|
||||
package Dahdi::Chans;
|
||||
#
|
||||
# Written by Oron Peled <oron@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;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user