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:
parent
a885b2c253
commit
466357f5c2
|
@ -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.
|
|
@ -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!
|
||||
|
||||
|
|
@ -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
|
|
@ -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]
|
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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`
|
||||
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "<?xml version=\"1.0\"?>"
|
||||
echo
|
||||
echo "<menu name=\"DAHDI Tools Selection\">"
|
||||
cat dahdi.xml
|
||||
echo "</menu>"
|
|
@ -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
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
cat << END
|
||||
/*
|
||||
* version.c
|
||||
* Automatically generated
|
||||
*/
|
||||
|
||||
const char dahdi_tools_version[] = "DAHDI Tools Version - ${TOOLSVERSION}";
|
||||
|
||||
END
|
|
@ -0,0 +1,2 @@
|
|||
LIBNEWT=@PBX_NEWT@
|
||||
HDLC=@PBX_HDLC@
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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 ***)
|
|
@ -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
|
||||
|
|
@ -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>
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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++;
|
||||
}
|
||||
}
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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[];
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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},
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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@
|
|
@ -0,0 +1,4 @@
|
|||
# You should place any module parameters for your DAHDI modules here
|
||||
# Example:
|
||||
#
|
||||
# options wctdm24xxp latency=6
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
#
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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 ),
|
||||
);
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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.
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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;
|
|
@ -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
Loading…
Reference in New Issue