diff options
author | Gerald Begumisa <ben_g@users.sourceforge.net> | 2007-02-06 06:56:19 +0000 |
---|---|---|
committer | Gerald Begumisa <ben_g@users.sourceforge.net> | 2007-02-06 06:56:19 +0000 |
commit | 6ea47988e23c732814f792cb9dde7a35f9b26885 (patch) | |
tree | 886a952c4570e6d62d44bac3bdd9999daaf1ecfc | |
parent | 94e3eb2d0cda7df2d876d1698db2e8e75cd0a0b1 (diff) |
IAX2 support added by Gerald Begumisa
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@399 09dcff7a-b715-0410-9601-b79a96267cd0
13 files changed, 2822 insertions, 685 deletions
diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/LICENSE.txt b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/LICENSE.txt index 7023fe1..a52b16e 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/LICENSE.txt +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/LICENSE.txt @@ -1,341 +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.
+ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/README.txt b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/README.txt index 7954b9d..36f55b2 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/README.txt +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/README.txt @@ -1,75 +1,75 @@ -
-Welcome to Oreka, an open media capture and retrieval platform
-
-Copyright (C) 2005, orecx LLC http://www.orecx.com
-
-This program is free software, distributed under the terms of
-the GNU General Public License.
-
-This package is a binary distribution of the oreka audio recording service. Source code and documentation can be found at http://sourceforge.net/projects/oreka/
-
---------
-Features
-
-* VoIP recording capability by sniffing on a network device (default configuration)
-* Works as well on a dedicated server for LAN-wide recording as on an individual PC for personal VoIP recording
-* Audio device recording (by default, records all devices in the system) using the Sound Device plugin
-* Generates calls details records with local party, remote party and call direction.
-
-The VoIP plugin supports the following protocols:
- - Bidirectional SIP sessions recording with SIP metadata extraction
- - Bidirectional Cisco skinny (aka SCCP) session recording with Skinny metadata extraction
- - Bidirectional Raw RTP session recording with limited metadata extraction (when SIP and Skinny both fail - e.g for H.323)
-
--------------
-Running orkaudio
-
-* run the daemon:
-
-root@myhost:/ # orkaudio
-
-* Or run attached to tty:
-
-root@myhost:/ # orkaudio debug
-
--------------
-Files location
-
-* Configuration files are in /etc/orkaudio
-* Logging output is in /var/log/orkaudio/orkaudio.log
-* Captured audio files are in /var/log/orkaudio/[year]/[month]/[day]/[hour]
-* Call details records can be found in /var/log/orkaudio/tapelist.log
-
---------------
-Capturing from the right network device
-
-If the software does not seem to produce any audio output, you might be monitoring from the wrong network device. edit /var/log/orkaudio/orkaudio.log and try to locate lines similar to the following:
-
-....
-2005-11-21 21:57:14,253 INFO packet:479 - Available pcap devices:
-2005-11-21 21:57:14,254 INFO packet:483 - * eth0
-2005-11-21 21:57:14,254 INFO packet:483 - * Pseudo-device that captures on all interfaces any
-2005-11-21 21:57:14,255 INFO packet:483 - * lo
-
-....
-
-Pick the device you want to monitor, e.g. eth0 and paste this into the orkaudio configuration file (/etc/orkaudio/config.xml) so that it looks like the following:
-
-....
-<Device>eth0</Device>
-....
-
---------------
-Where to tap ?
-
-* If you record from a single PC, no need to worry, just install the software
-* For VoIP recording on an entire LAN, you need to tap an ethernet link carrying all
-the voice traffic you want to monitor. There are three methods:
-1. Ehternet tap
-2. Ethernet Hub
-3. Switch SPAN port
-For more info on those options, see:
-http://www.snort.org/docs and more specifically:
-http://www.snort.org/docs/iss-placement.pdf
-
-
+ +Welcome to Oreka, an open media capture and retrieval platform + +Copyright (C) 2005, orecx LLC http://www.orecx.com + +This program is free software, distributed under the terms of +the GNU General Public License. + +This package is a binary distribution of the oreka audio recording service. Source code and documentation can be found at http://sourceforge.net/projects/oreka/ + +-------- +Features + +* VoIP recording capability by sniffing on a network device (default configuration) +* Works as well on a dedicated server for LAN-wide recording as on an individual PC for personal VoIP recording +* Audio device recording (by default, records all devices in the system) using the Sound Device plugin +* Generates calls details records with local party, remote party and call direction. + +The VoIP plugin supports the following protocols: + - Bidirectional SIP sessions recording with SIP metadata extraction + - Bidirectional Cisco skinny (aka SCCP) session recording with Skinny metadata extraction + - Bidirectional Raw RTP session recording with limited metadata extraction (when SIP and Skinny both fail - e.g for H.323) + +------------- +Running orkaudio + +* run the daemon: + +root@myhost:/ # orkaudio + +* Or run attached to tty: + +root@myhost:/ # orkaudio debug + +------------- +Files location + +* Configuration files are in /etc/orkaudio +* Logging output is in /var/log/orkaudio/orkaudio.log +* Captured audio files are in /var/log/orkaudio/[year]/[month]/[day]/[hour] +* Call details records can be found in /var/log/orkaudio/tapelist.log + +-------------- +Capturing from the right network device + +If the software does not seem to produce any audio output, you might be monitoring from the wrong network device. edit /var/log/orkaudio/orkaudio.log and try to locate lines similar to the following: + +.... +2005-11-21 21:57:14,253 INFO packet:479 - Available pcap devices: +2005-11-21 21:57:14,254 INFO packet:483 - * eth0 +2005-11-21 21:57:14,254 INFO packet:483 - * Pseudo-device that captures on all interfaces any +2005-11-21 21:57:14,255 INFO packet:483 - * lo + +.... + +Pick the device you want to monitor, e.g. eth0 and paste this into the orkaudio configuration file (/etc/orkaudio/config.xml) so that it looks like the following: + +.... +<Device>eth0</Device> +.... + +-------------- +Where to tap ? + +* If you record from a single PC, no need to worry, just install the software +* For VoIP recording on an entire LAN, you need to tap an ethernet link carrying all +the voice traffic you want to monitor. There are three methods: +1. Ehternet tap +2. Ethernet Hub +3. Switch SPAN port +For more info on those options, see: +http://www.snort.org/docs and more specifically: +http://www.snort.org/docs/iss-placement.pdf + + diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-AUTHORS b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-AUTHORS index 48d95e4..9895e17 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-AUTHORS +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-AUTHORS @@ -1,3 +1,3 @@ -Michael CATANZARITI <mcatan@users.sourceforge.net>
-Edmond NOLAN <log_debug@users.sourceforge.net>
-
+Michael CATANZARITI <mcatan@users.sourceforge.net> +Edmond NOLAN <log_debug@users.sourceforge.net> + diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-COPYING b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-COPYING index 6071c89..0f1bdb8 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-COPYING +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-COPYING @@ -1 +1 @@ -See license.apl
+See license.apl diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-ChangeLog b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-ChangeLog index a3673eb..d1bb8d8 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-ChangeLog +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-ChangeLog @@ -1,145 +1,145 @@ -Version 0.9.7 (2004-05-10)
-==========================
-
-* Fixed examples source code in the "Short introduction to log4cxx".
-* Fixed, in the renaming algorithm of RollingFileAppender and
- DailyRollingFileAppender, a problem specific to Unicode.
-* Fixed conflict with Windows macros "min" and "max", by renaming
- StrictMath::min and StrictMath::max to StrictMath::minimum and
- StrictMath::maximum.
-* Port to HPUX 11.0.
-* Fixed segmentation fault in PropertyConfigurator.
-* Port to Solaris.
-* Fixed MutexException thrown while destroying RollingFileAppender.
-* Logging macros can be used without explicity declaring the use of log4cxx
- namespace.
-* Fixed static library unresolved externals for msvc 6 and 7.1
-
-Version 0.9.6 (2004-04-11)
-==========================
-
-* Timezone management has been optimized through the class TimeZone
-* Inter-thread synchronization and reference counting has been optimized
-* Reference counting now uses gcc atomic functions (bug 929078)
-* Use of StringBuffer has been optimized.
-* Support of localisation throug resourceBundles
-* SyslogAppender now uses the system function 'syslog' to log on the local host.
- (only for POSIX systems)
-* Added TimeZone configuration to PatternLayout (bug 912563)
-* Support of the DailyRollingFileAppender (feature request 842765)
-
-Version 0.9.5 (2004-02-04)
-==========================
-
-* Port of log4j Jnuit tests with Cppunit and Boost Regex.
-* Added explicit exports for MSDEV 6 and MSDEV 7 (no further need of .def files)
-* Custom levels can be configured through the DOMConfigurator and
- PropertyConfigurator classes (Level inherites from Object)
-* Added a reference counter to LoggingEvent to avoid useless copies
- (LoggingEvent inherites from Object)
-* The file log4j.xml as well as the file log4j.properties are now search
- for, in log4cxx initialization.
-* The root logger can be assigned the "OFF" level.
-* Added MSVC6 project missing files mutext.cpp & condition.cpp (bug 847397)
-* condition.cpp now compiles with MSVC6 (bug 847417)
-* fixed pure virtual function call in PropertyConfigurator::configureAndWatch
- (bug 848521)
-* XMLAppender now displays correct timestamp with MSVC 6 (bug 852836)
-* SRLPORT 4.6 support.
-* Fixed an infinite loop in class Properties.
-* Fixed compilations problems with unicode.
-* Fixed SocketAppender bug concerning MDC ans NDC.
-
-Version 0.9.4 (2003-10-25)
-==========================
-
-* StringBuffer has been optimized.
-* Fixed miscellaneous threading problems.
-* Added TimeZone support in PatternLayout (bug 796894)
-* Fixed threading configuration problems (bug 809125)
-* Fixed miscellaneous MSVC and cygwin compilation problems.
-
-Version 0.9.3 (2003-09-19)
-==========================
-
-* Changed tstring to log4cxx::String and tostringstream to
- log4cxx::StringBuffer.
-* Fixed MSVC 2003 compilation erros and warnings.
-* Added helpers for NDC and MDC.
-* Added TimeZone support in TTCCLayout.
-* Fixed compilation problems with logger macros (LOG4CXX_...)
-* Fixed milliseconds formatting problem with MSVC 6.0 and 2003
-* Fixed AsyncAppender crash
-* Added new tests
-* Added benchmarks
-
-Version 0.9.2 (2003-08-10)
-==========================
-
-* Fixed FreeBSD compilation problem with pthread mutex (class CriticalSection).
-* Fixed milliseconds formatting problem (class DateFormat).
-* Long events (> 1024 chars) are now supported in the class XMLSocketAppender.
-* Carriage returns have been normalized in the class XMLLayout.
-
-Version 0.9.1 (2003-08-06)
-==========================
-
-* Fixed deadlock problems in classes Logger and AsyncAppender.
-* Fixed MSVC 6.0 compilation problems.
-* Added MSVC 6.0 static libraty project.
-* Default configuration for the SMTP options is "no".
-
-Version 0.9.0 (2003-08-06)
-==========================
-
-* Added ODBCAppender (matching log4j JDBCAppender)
-* Added SyslogAppender
-* Added SMTPAppender (only for Linux/FreeBSD)
-* Added BasicConfigurator
-* Added a FileWatchDog in PropertyConfigurator and DOMConfigurator
-* Possibility to load a custom LoggerFactory through the DOMConfigurator
-* Changed time precision from seconds to milliseconds
-* Added MSVC 6.0 'Unicode Debug' and 'Unicode Release' targets
-* Added Java like System class.
-
-Version 0.1.1 (2003-07-09)
-==========================
-
-* Fixed MSVC 6.0 compilation problems concerning the 'Release' target
-* Added MSVC 6.0 tests projects
-
-Version 0.1.0 (2003-07-08)
-==========================
-
-* FreeBSD Autotools/Compilation support
-* Fixed TelnetAppender crash when a socket bind exception occured.
-* Added log4j DTD support to XMLLayout and DOMConfigurator
-* Can now send events in XML format over TCP (class XMLSocketAppender) for the
- log4j Chainsaw UI
-* Now compiles with 'configure --enable-unicode' (UTF16 Unicode support)
-* Added Java like Properties class. It's a helper for the PropertyConfigurator
-* Added Java like objects with dynamic cast and instanciation. Custom objects
- can be configured through the DOMConfigurator and PropertyConfigurator classes
-* Port of the PropertyConfigurator class
-* Port of the "Map Diagnostic Context" (MDC) class
-* Added 13 tests (try make check)
-
-Version 0.0.1 (2003-05-31)
-==========================
-
-Loggers, Hierarchy, Filters, Appenders, Layouts, NDC
-
-* Appenders:
- AsyncAppender, ConsoleAppender, FileAppender, NTEventLogAppender,
- RollingFileAppender, SocketAppender, SocketHubAappender,
- TelnetAppender
-
-* Layouts:
- HTMLLayout, PatternLayout, SimpleLayout, TTCCLayout, XMLLayout
-
-
-* Filters:
- DenyAllFilter, LevelMatchFilter, LevelRangeFilter, StringMatchFilter
-
-* Configurators:
- DOMConfigurator
+Version 0.9.7 (2004-05-10) +========================== + +* Fixed examples source code in the "Short introduction to log4cxx". +* Fixed, in the renaming algorithm of RollingFileAppender and + DailyRollingFileAppender, a problem specific to Unicode. +* Fixed conflict with Windows macros "min" and "max", by renaming + StrictMath::min and StrictMath::max to StrictMath::minimum and + StrictMath::maximum. +* Port to HPUX 11.0. +* Fixed segmentation fault in PropertyConfigurator. +* Port to Solaris. +* Fixed MutexException thrown while destroying RollingFileAppender. +* Logging macros can be used without explicity declaring the use of log4cxx + namespace. +* Fixed static library unresolved externals for msvc 6 and 7.1 + +Version 0.9.6 (2004-04-11) +========================== + +* Timezone management has been optimized through the class TimeZone +* Inter-thread synchronization and reference counting has been optimized +* Reference counting now uses gcc atomic functions (bug 929078) +* Use of StringBuffer has been optimized. +* Support of localisation throug resourceBundles +* SyslogAppender now uses the system function 'syslog' to log on the local host. + (only for POSIX systems) +* Added TimeZone configuration to PatternLayout (bug 912563) +* Support of the DailyRollingFileAppender (feature request 842765) + +Version 0.9.5 (2004-02-04) +========================== + +* Port of log4j Jnuit tests with Cppunit and Boost Regex. +* Added explicit exports for MSDEV 6 and MSDEV 7 (no further need of .def files) +* Custom levels can be configured through the DOMConfigurator and + PropertyConfigurator classes (Level inherites from Object) +* Added a reference counter to LoggingEvent to avoid useless copies + (LoggingEvent inherites from Object) +* The file log4j.xml as well as the file log4j.properties are now search + for, in log4cxx initialization. +* The root logger can be assigned the "OFF" level. +* Added MSVC6 project missing files mutext.cpp & condition.cpp (bug 847397) +* condition.cpp now compiles with MSVC6 (bug 847417) +* fixed pure virtual function call in PropertyConfigurator::configureAndWatch + (bug 848521) +* XMLAppender now displays correct timestamp with MSVC 6 (bug 852836) +* SRLPORT 4.6 support. +* Fixed an infinite loop in class Properties. +* Fixed compilations problems with unicode. +* Fixed SocketAppender bug concerning MDC ans NDC. + +Version 0.9.4 (2003-10-25) +========================== + +* StringBuffer has been optimized. +* Fixed miscellaneous threading problems. +* Added TimeZone support in PatternLayout (bug 796894) +* Fixed threading configuration problems (bug 809125) +* Fixed miscellaneous MSVC and cygwin compilation problems. + +Version 0.9.3 (2003-09-19) +========================== + +* Changed tstring to log4cxx::String and tostringstream to + log4cxx::StringBuffer. +* Fixed MSVC 2003 compilation erros and warnings. +* Added helpers for NDC and MDC. +* Added TimeZone support in TTCCLayout. +* Fixed compilation problems with logger macros (LOG4CXX_...) +* Fixed milliseconds formatting problem with MSVC 6.0 and 2003 +* Fixed AsyncAppender crash +* Added new tests +* Added benchmarks + +Version 0.9.2 (2003-08-10) +========================== + +* Fixed FreeBSD compilation problem with pthread mutex (class CriticalSection). +* Fixed milliseconds formatting problem (class DateFormat). +* Long events (> 1024 chars) are now supported in the class XMLSocketAppender. +* Carriage returns have been normalized in the class XMLLayout. + +Version 0.9.1 (2003-08-06) +========================== + +* Fixed deadlock problems in classes Logger and AsyncAppender. +* Fixed MSVC 6.0 compilation problems. +* Added MSVC 6.0 static libraty project. +* Default configuration for the SMTP options is "no". + +Version 0.9.0 (2003-08-06) +========================== + +* Added ODBCAppender (matching log4j JDBCAppender) +* Added SyslogAppender +* Added SMTPAppender (only for Linux/FreeBSD) +* Added BasicConfigurator +* Added a FileWatchDog in PropertyConfigurator and DOMConfigurator +* Possibility to load a custom LoggerFactory through the DOMConfigurator +* Changed time precision from seconds to milliseconds +* Added MSVC 6.0 'Unicode Debug' and 'Unicode Release' targets +* Added Java like System class. + +Version 0.1.1 (2003-07-09) +========================== + +* Fixed MSVC 6.0 compilation problems concerning the 'Release' target +* Added MSVC 6.0 tests projects + +Version 0.1.0 (2003-07-08) +========================== + +* FreeBSD Autotools/Compilation support +* Fixed TelnetAppender crash when a socket bind exception occured. +* Added log4j DTD support to XMLLayout and DOMConfigurator +* Can now send events in XML format over TCP (class XMLSocketAppender) for the + log4j Chainsaw UI +* Now compiles with 'configure --enable-unicode' (UTF16 Unicode support) +* Added Java like Properties class. It's a helper for the PropertyConfigurator +* Added Java like objects with dynamic cast and instanciation. Custom objects + can be configured through the DOMConfigurator and PropertyConfigurator classes +* Port of the PropertyConfigurator class +* Port of the "Map Diagnostic Context" (MDC) class +* Added 13 tests (try make check) + +Version 0.0.1 (2003-05-31) +========================== + +Loggers, Hierarchy, Filters, Appenders, Layouts, NDC + +* Appenders: + AsyncAppender, ConsoleAppender, FileAppender, NTEventLogAppender, + RollingFileAppender, SocketAppender, SocketHubAappender, + TelnetAppender + +* Layouts: + HTMLLayout, PatternLayout, SimpleLayout, TTCCLayout, XMLLayout + + +* Filters: + DenyAllFilter, LevelMatchFilter, LevelRangeFilter, StringMatchFilter + +* Configurators: + DOMConfigurator diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-README b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-README index 187cee7..9f260af 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-README +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-README @@ -1,94 +1,94 @@ -Introduction
-============
-Log4cxx is a port to C++ of the log4j project.
-The goal is have the same functionnalities and interfaces of log4j.
-
-Features
-========
-It's a flexible and highly configurable logging framework
-Main features :
-- Configurable logging destinations (appenders)
-- Configurable logging format (layouts)
-- Categorized logging statements through a hierarchy (loggers)
-- Advanced filtering (filters)
-- Thread safe library
-- UTF-16 Unicode support
-
-* Appenders:
- AsyncAppender, ConsoleAppender, DailyRollingFileAppender, FileAppender,
- NTEventLogAppender, ODBCAppender, RollingFileAppender, SMTPAppender,
- SocketAppender, SocketHubAappender, SyslogAppender, TelnetAppender,
- XMLSocketAppender
-
-* Layouts:
- HTMLLayout, PatternLayout, SimpleLayout, TTCCLayout, XMLLayout
-
-* Filters:
- DenyAllFilter, LevelMatchFilter, LevelRangeFilter, StringMatchFilter
-
-* Configurators:
- BasicConfigurator, DOMConfigurator, PropertyConfigurator
-
-* Java like objects with dynamic cast and instanciation. Custom objects can
- be configured through the DOMConfigurator and PropertyConfigurator classes
-
-Supported OS
-============
-* Linux (tested on Linux Mandrake 10.0)
-* FreeBSD
-* Windows (MSVC 6.0, MSVC 7.1 or Cygwin)
-* Other POSIX OS should be supported but were not tested
-
-Installation
-============
-./autogen.sh
-./configure
-make
-make check
-make install
-
-See INSTALL file for further details.
-
-Visual Studio .Net 2003 and Visual Studio 6.0 considerations
-============================================================
-For projects linking with log4cxx static library, the macro LOG4CXX_STATIC must
-be defined (tab C++, textbox Preprocessor in the project properties) and
-"log4cxxs.lib" must be passed to the linker (tab Link,textbox Object/Library
-Modules in the project settings).
-
-For projects linking with log4cxx dynamic library (dll), "log4cxx.lib" must be
-passed to the linker (tab Link,textbox Object/Library Modules in the project
-settings).
-
-Unitary Tests
-=============
-You will need to install
-* cppunit (http://cppunit.sourceforge.net/)
-* boost regex (http://www.boost.org/)
-
-Unix : run "make check"
-Windows : run msvc/tests/runtests.bat
-
-Performance Tests
-=================
-Just run performance/logging.sh.
-The result are expressed in micro-seconds.
-
-Links
-=====
-http://logging.apache.org/log4cxx
- Log4cxx project page
-
-http://logging.apache.org/log4j
- Log4j project page
-
-Contacts
-========
-See AUTHORS file
-
-License
-=======
-This library is licensed under the Apache Public License. Please read the
-included license.apl for details.
-
-
+Introduction +============ +Log4cxx is a port to C++ of the log4j project. +The goal is have the same functionnalities and interfaces of log4j. + +Features +======== +It's a flexible and highly configurable logging framework +Main features : +- Configurable logging destinations (appenders) +- Configurable logging format (layouts) +- Categorized logging statements through a hierarchy (loggers) +- Advanced filtering (filters) +- Thread safe library +- UTF-16 Unicode support + +* Appenders: + AsyncAppender, ConsoleAppender, DailyRollingFileAppender, FileAppender, + NTEventLogAppender, ODBCAppender, RollingFileAppender, SMTPAppender, + SocketAppender, SocketHubAappender, SyslogAppender, TelnetAppender, + XMLSocketAppender + +* Layouts: + HTMLLayout, PatternLayout, SimpleLayout, TTCCLayout, XMLLayout + +* Filters: + DenyAllFilter, LevelMatchFilter, LevelRangeFilter, StringMatchFilter + +* Configurators: + BasicConfigurator, DOMConfigurator, PropertyConfigurator + +* Java like objects with dynamic cast and instanciation. Custom objects can + be configured through the DOMConfigurator and PropertyConfigurator classes + +Supported OS +============ +* Linux (tested on Linux Mandrake 10.0) +* FreeBSD +* Windows (MSVC 6.0, MSVC 7.1 or Cygwin) +* Other POSIX OS should be supported but were not tested + +Installation +============ +./autogen.sh +./configure +make +make check +make install + +See INSTALL file for further details. + +Visual Studio .Net 2003 and Visual Studio 6.0 considerations +============================================================ +For projects linking with log4cxx static library, the macro LOG4CXX_STATIC must +be defined (tab C++, textbox Preprocessor in the project properties) and +"log4cxxs.lib" must be passed to the linker (tab Link,textbox Object/Library +Modules in the project settings). + +For projects linking with log4cxx dynamic library (dll), "log4cxx.lib" must be +passed to the linker (tab Link,textbox Object/Library Modules in the project +settings). + +Unitary Tests +============= +You will need to install +* cppunit (http://cppunit.sourceforge.net/) +* boost regex (http://www.boost.org/) + +Unix : run "make check" +Windows : run msvc/tests/runtests.bat + +Performance Tests +================= +Just run performance/logging.sh. +The result are expressed in micro-seconds. + +Links +===== +http://logging.apache.org/log4cxx + Log4cxx project page + +http://logging.apache.org/log4j + Log4j project page + +Contacts +======== +See AUTHORS file + +License +======= +This library is licensed under the Apache Public License. Please read the +included license.apl for details. + + diff --git a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-license.apl b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-license.apl index 6994c62..1aa6614 100644 --- a/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-license.apl +++ b/distribution/orkaudio-linux-deb-binary/debian/usr/share/doc/orkaudio/log4cxx-license.apl @@ -1,15 +1,15 @@ -/*
- * Copyright 2003,2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/* + * Copyright 2003,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/orkaudio/audiocaptureplugins/voip/Iax2Session.cpp b/orkaudio/audiocaptureplugins/voip/Iax2Session.cpp new file mode 100644 index 0000000..6b072b5 --- /dev/null +++ b/orkaudio/audiocaptureplugins/voip/Iax2Session.cpp @@ -0,0 +1,990 @@ +/* + * Oreka -- A media capture and retrieval platform + * + * Copyright (C) 2005, orecx LLC + * + * http://www.orecx.com + * + * This program is free software, distributed under the terms of + * the GNU General Public License. + * Please refer to http://www.gnu.org/copyleft/gpl.html + * + */ +#pragma warning( disable: 4786 ) // disables truncated symbols in browse-info warning +#define _WINSOCKAPI_ // prevents the inclusion of winsock.h + +#include "Utils.h" +#include "AudioCapture.h" +#include "Iax2Session.h" +#include "AudioCapturePlugin.h" +#include "AudioCapturePluginCommon.h" +#include <list> +#include "ConfigManager.h" +#include "VoIpConfig.h" +#include "ace/OS_NS_arpa_inet.h" + +extern AudioChunkCallBackFunction g_audioChunkCallBack; +extern CaptureEventCallBackFunction g_captureEventCallBack; + +extern VoIpConfigTopObjectRef g_VoIpConfigTopObjectRef; +#define DLLCONFIG g_VoIpConfigTopObjectRef.get()->m_config + +Iax2Session::Iax2Session(CStdString& trackingId) +{ + m_trackingId = trackingId; + m_lastUpdated = time(NULL); + m_log = Logger::getLogger("Iax2session"); + m_invitorIp.s_addr = 0; + m_inviteeIp.s_addr = 0; + m_localIp.s_addr = 0; + m_remoteIp.s_addr = 0; + m_direction = CaptureEvent::DirUnkn; + m_numIax2Packets = 0; + m_started = false; + m_stopped = false; + m_beginDate = 0; + m_codec = 0; + m_hasDuplicateIax2 = false; + m_iax2_state = IAX2_STATE_WAITING; + m_invitor_scallno = 0; + m_invitee_scallno = 0; + + /* Not sure if IAX2 needs these... */ + m_highestIax2SeqNumDelta = 0; + m_minIax2SeqDelta = (double)DLLCONFIG.m_rtpDiscontinuityMinSeqDelta; + m_minIax2TimestampDelta = (double)DLLCONFIG.m_rtpDiscontinuityMinSeqDelta * 160; +} + +void Iax2Session::Stop() +{ + CStdString logMsg; + + logMsg.Format("[%s] %s Session stop, numIax2Pkts:%d dupl:%d seqDelta:%d " + "lastUpdated:%u", m_trackingId, m_capturePort, m_numIax2Packets, + m_hasDuplicateIax2, m_highestIax2SeqNumDelta, m_lastUpdated); + + LOG4CXX_INFO(m_log, logMsg); + + if(m_started && !m_stopped) { + CaptureEventRef stopEvent(new CaptureEvent); + stopEvent->m_type = CaptureEvent::EtStop; + stopEvent->m_timestamp = m_lastUpdated; + g_captureEventCallBack(stopEvent, m_capturePort); + m_stopped = true; + } +} + +void Iax2Session::Start() +{ + CaptureEventRef startEvent(new CaptureEvent); + + m_started = true; + time(&m_beginDate); + GenerateOrkUid(); + startEvent->m_type = CaptureEvent::EtStart; + startEvent->m_timestamp = m_beginDate; + startEvent->m_value = m_trackingId; + CStdString timestamp = IntToString(startEvent->m_timestamp); + + LOG4CXX_INFO(m_log, "[" + m_trackingId + "] " + m_capturePort + " " + + IAX2_PROTOCOL_STR + " Session start, timestamp:" + timestamp); + + g_captureEventCallBack(startEvent, m_capturePort); +} + +void Iax2Session::GenerateOrkUid() +{ + struct tm date = {0}; + int month, year; + + ACE_OS::localtime_r(&m_beginDate, &date); + + month = date.tm_mon + 1; + year = date.tm_year + 1900; + + m_orkUid.Format("%.4d%.2d%.2d_%.2d%.2d%.2d_%s", year, month, date.tm_mday, + date.tm_hour, date.tm_min, date.tm_sec, m_trackingId); +} + +/* We index with the invitor because the invitor is the first party + * that provides us with complete information i.e the IP address + * and the call number, which we need. Remember, though that + * call numbers are scarce by nature and may be reused. */ +void Iax2Session::ProcessMetadataIax2Incoming() +{ + char szNewSrcIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_invitorIp, szNewSrcIp, sizeof(szNewSrcIp)); + + m_remoteParty = m_new->m_caller; + m_localParty = m_new->m_callee; + m_direction = CaptureEvent::DirIn; + m_localIp = m_inviteeIp; + m_remoteIp = m_invitorIp; + m_capturePort.Format("%s,%d", szNewSrcIp, m_invitor_scallno); +} + +/* We index with the invitor because the invitor is the first party + * that provides us with complete information i.e the IP address + * and the call number, which we need. Remember, though that + * call numbers are scarce by nature and may be reused. */ +void Iax2Session::ProcessMetadataIax2Outgoing() +{ + char szNewSrcIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_invitorIp, szNewSrcIp, sizeof(szNewSrcIp)); + m_remoteParty = m_new->m_callee; + m_localParty = m_new->m_caller; + m_direction = CaptureEvent::DirOut; + m_capturePort.Format("%s,%d", szNewSrcIp, m_invitor_scallno); + m_localIp = m_invitorIp; + m_remoteIp = m_inviteeIp; +} + +/* Is this function ever necessary? */ +void Iax2Session::UpdateMetadataIax2(Iax2PacketInfoRef& iax2Packet, bool sourceIax2AddressIsNew) +{ + // Find out if the new IAX2 packet could match one of the IAX2 NEW messages associated with the session + Iax2NewInfoRef invite, tmpNew; + std::list<Iax2NewInfoRef>::iterator it; + + for(it = m_news.begin(); it != m_news.end(); it++) { + tmpNew = *it; + + if(tmpNew->m_validated) + break; + + if(sourceIax2AddressIsNew) { + if((unsigned int)(iax2Packet->m_sourceIp.s_addr) == + (unsigned int)(tmpNew->m_receiverIp.s_addr)) + invite = tmpNew; + } else { + if((unsigned int)(iax2Packet->m_destIp.s_addr) == + (unsigned int)(tmpNew->m_receiverIp.s_addr)) + invite = tmpNew; + } + } + + if(invite.get()) { + CStdString inviteString, iax2String, logMsg; + + // The NEW has generated an IAX2 voice stream + invite->m_validated = true; + + // Update session metadata with NEW info + m_remoteParty = invite->m_caller; + m_localParty = invite->m_callee; + m_localIp = invite->m_receiverIp; + + // Do some logging + invite->ToString(inviteString); + iax2Packet->ToString(iax2String); + + logMsg.Format("[%s] metadata update: local:%s remote:%s " + "IAX2 Pkt:%s NEW Info:%s", m_trackingId, m_localParty, + m_remoteParty, iax2String, inviteString); + LOG4CXX_INFO(m_log, logMsg); + + // Report Local party + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalParty; + event->m_value = m_localParty; + g_captureEventCallBack(event, m_capturePort); + + // Report remote party + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtRemoteParty; + event->m_value = m_remoteParty; + g_captureEventCallBack(event, m_capturePort); + + // Report Local IP + char szLocalIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&m_localIp, szLocalIp, sizeof(szLocalIp)); + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalIp; + event->m_value = szLocalIp; + g_captureEventCallBack(event, m_capturePort); + + // Trigger metadata update + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtUpdate; + g_captureEventCallBack(event, m_capturePort); + } +} + +void Iax2Session::ProcessMetadataIax2(Iax2PacketInfoRef& iax2Packet) +{ + /* This is the first full IAX2_FRAME_VOICE frame which will tell us + * the codec being used */ + if(((unsigned int)iax2Packet->m_sourceIp.s_addr != (unsigned int)m_invitorIp.s_addr) && + ((unsigned int)iax2Packet->m_destIp.s_addr != (unsigned int)m_invitorIp.s_addr)) + { + LOG4CXX_ERROR(m_log, "[" + m_trackingId + "] " + m_srcIpAndCallNo + " alien IAX2 packet"); + } + + /* Obtain the codec information */ + m_codec = iax2Packet->m_payloadType; + + // work out capture port and direction + if(DLLCONFIG.IsMediaGateway(m_invitorIp)) { + if(DLLCONFIG.IsMediaGateway(m_inviteeIp)) { + // Media gateway talking to media gateway, this is probably incoming + ProcessMetadataIax2Incoming(); + } else if(DLLCONFIG.IsPartOfLan(m_inviteeIp)) { + // Gateway to LAN, this is pobably incoming + ProcessMetadataIax2Incoming(); + } else { + // Gateway to outside address, probably outgoing but treat as incoming for now because + // It can be due to misconfigured LAN Mask, odds are it's still incoming. + ProcessMetadataIax2Incoming(); + } + } else if (DLLCONFIG.IsPartOfLan(m_invitorIp)) { + ProcessMetadataIax2Outgoing(); + } else { + // SIP invitor media IP address is an outside IP address + if(DLLCONFIG.IsMediaGateway(m_inviteeIp)) { + ProcessMetadataIax2Incoming(); + } else if(DLLCONFIG.IsPartOfLan(m_inviteeIp)) { + ProcessMetadataIax2Incoming(); + } else { + // SIP invitee media address is an outside IP address + ProcessMetadataIax2Outgoing(); + } + } +} + +void Iax2Session::ReportMetadata() +{ + char szLocalIp[16], szRemoteIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_localIp, szLocalIp, sizeof(szLocalIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_remoteIp, szRemoteIp, sizeof(szRemoteIp)); + + // Make sure Local Party is always reported + if(m_localParty.IsEmpty()) { + m_localParty = szLocalIp; + } + + // Report Local party + CaptureEventRef event(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalParty; + event->m_value = m_localParty; + g_captureEventCallBack(event, m_capturePort); + + // Report remote party + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtRemoteParty; + event->m_value = m_remoteParty; + g_captureEventCallBack(event, m_capturePort); + + // Report direction + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtDirection; + event->m_value = CaptureEvent::DirectionToString(m_direction); + g_captureEventCallBack(event, m_capturePort); + + // Report Local IP address + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtLocalIp; + event->m_value = szLocalIp; + g_captureEventCallBack(event, m_capturePort); + + // Report Remote IP address + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtRemoteIp; + event->m_value = szRemoteIp; + g_captureEventCallBack(event, m_capturePort); + + // Report OrkUid + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtOrkUid; + event->m_value = m_orkUid; + g_captureEventCallBack(event, m_capturePort); + + // Report native Call ID + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtCallId; + event->m_value = m_srcIpAndCallNo; + g_captureEventCallBack(event, m_capturePort); + + // Report end of metadata + event.reset(new CaptureEvent()); + event->m_type = CaptureEvent::EtEndMetadata; + g_captureEventCallBack(event, m_capturePort); +} + +static char *iax2_state_to_str(int iax2state) +{ + switch(iax2state) { + case IAX2_STATE_WAITING: + return "WAITING"; + case IAX2_STATE_LINKED: + return "LINKED"; + case IAX2_STATE_UP: + return "UP"; + default: + return "UNKNOWN"; + } + + /* NOT REACHED */ + return "UNKNOWN"; +} + +/* + * Returns false if packet is received out-of-sync (when we are in the wrong state) + */ +bool Iax2Session::AddIax2Packet(Iax2PacketInfoRef& iax2Packet) +{ + CStdString logMsg; + unsigned char channel = 0; + + /* What is our state? We need to be in the IAX2_STATE_LINKED state + * or the IAX2_STATE_UP state to receive any voice frames */ + if((m_iax2_state != IAX2_STATE_LINKED) && (m_iax2_state != IAX2_STATE_UP)) { + logMsg.Format("[%s] receiving voice packets while in %s state? " + "Destroying session...", m_trackingId, + iax2_state_to_str(m_iax2_state)); + return false; + } + + /* We do not have a voice packet yet */ + if(m_lastIax2Packet.get() == NULL) { + /* The first IAX2 voice frame is expected to be a full frame, + * complete with the payload type information. If this is not + * the case, we will continue dropping any mini frames */ + + if(iax2Packet->m_frame_type != IAX2_FRAME_FULL) { + logMsg.Format("[%s] 1st packet is not a full frame! Dropping...", m_trackingId); + LOG4CXX_ERROR(m_log, logMsg); + return true; + } + + ProcessMetadataIax2(iax2Packet); + m_iax2_state = IAX2_STATE_UP; + } + + /* If we get another full voice packet, we need to update our codec + * information */ + if(iax2Packet->m_frame_type == IAX2_FRAME_FULL) + m_codec = iax2Packet->m_payloadType; + + m_lastIax2Packet = iax2Packet; + if(m_lastIax2PacketSide1.get() == NULL) { + // First IAX2 packet for side 1 + m_lastIax2PacketSide1 = iax2Packet; + channel = 1; + if(m_log->isInfoEnabled()) + { + iax2Packet->ToString(logMsg); + logMsg = "[" + m_trackingId + "] 1st packet s1: " + logMsg; + LOG4CXX_INFO(m_log, logMsg); + } + } else { + // Comparing destination IP address to find out if side1, see (1) + if((unsigned int)iax2Packet->m_destIp.s_addr == (unsigned int)m_lastIax2PacketSide1->m_destIp.s_addr) + { + if(iax2Packet->m_timestamp == m_lastIax2PacketSide1->m_timestamp) + { + m_hasDuplicateIax2 = true; + return true; // dismiss duplicate IAX2 packet + } + /* XXX Detect discontinuity using timestamps? */ + /* + else + { + double seqNumDelta = (double)iax2Packet->m_seqNum - (double)m_lastIax2PacketSide1->m_seqNum; + if(DLLCONFIG.m_iax2DiscontinuityDetect) + { + double timestampDelta = (double)iax2Packet->m_timestamp - (double)m_lastIax2PacketSide1->m_timestamp; + if( abs(seqNumDelta) > m_minIax2SeqDelta && + abs(timestampDelta) > m_minIax2TimestampDelta) + { + logMsg.Format("[%s] IAX2 discontinuity s1: before: seq:%u ts:%u after: seq:%u ts:%u", + m_trackingId, m_lastIax2PacketSide1->m_seqNum, m_lastIax2PacketSide1->m_timestamp, + iax2Packet->m_seqNum, iax2Packet->m_timestamp); + LOG4CXX_INFO(m_log, logMsg); + return false; + } + } + if(seqNumDelta > (double)m_highestIax2SeqNumDelta) + { + m_highestIax2SeqNumDelta = (unsigned int)seqNumDelta; + } + } */ + m_lastIax2PacketSide1 = iax2Packet; + channel = 1; + } + else + { + if(m_lastIax2PacketSide2.get() == NULL) + { + // First IAX2 packet for side 2 + if(m_log->isInfoEnabled()) + { + iax2Packet->ToString(logMsg); + logMsg = "[" + m_trackingId + "] 1st packet s2: " + logMsg; + LOG4CXX_INFO(m_log, logMsg); + } + } + else + { + if(iax2Packet->m_timestamp == m_lastIax2PacketSide2->m_timestamp) + { + m_hasDuplicateIax2 = true; + return true; // dismiss duplicate IAX2 packet + } + /* XXX Detect discontinuity using timestamps? */ + /* + else + { + double seqNumDelta = (double)iax2Packet->m_seqNum - (double)m_lastIax2PacketSide2->m_seqNum; + if(DLLCONFIG.m_iax2DiscontinuityDetect) + { + double timestampDelta = (double)iax2Packet->m_timestamp - (double)m_lastIax2PacketSide2->m_timestamp; + if( abs(seqNumDelta) > m_minIax2SeqDelta && + abs(timestampDelta) > m_minIax2TimestampDelta) + { + logMsg.Format("[%s] IAX2 discontinuity s2: before: seq:%u ts:%u after: seq:%u ts:%u", + m_trackingId, m_lastIax2PacketSide2->m_seqNum, m_lastIax2PacketSide2->m_timestamp, + iax2Packet->m_seqNum, iax2Packet->m_timestamp); + LOG4CXX_INFO(m_log, logMsg); + return false; + } + } + if(seqNumDelta > (double)m_highestIax2SeqNumDelta) + { + m_highestIax2SeqNumDelta = (unsigned int)seqNumDelta; + } + }*/ + } + m_lastIax2PacketSide2 = iax2Packet; + channel = 2; + } + } + + m_numIax2Packets++; + + /* Can stream change happen with IAX2?? + bool hasSourceAddress = m_iax2AddressList.HasAddressOrAdd(iax2Packet->m_sourceIp, iax2Packet->m_sourcePort); + bool hasDestAddress = m_iax2AddressList.HasAddressOrAdd(iax2Packet->m_destIp, iax2Packet->m_destPort); + if( hasSourceAddress == false || hasDestAddress == false ) + { + iax2Packet->ToString(logMsg); + logMsg.Format("[%s] new IAX2 stream s%d: %s", + m_trackingId, channel, logMsg); + LOG4CXX_INFO(m_log, logMsg); + + if(m_protocol == ProtIax2 && m_started) // make sure this only happens if ReportMetadata() already been called for the session + { + UpdateMetadataIax2(iax2Packet, hasDestAddress); + } + } + */ + + if(m_numIax2Packets == 1) { + Start(); + ReportMetadata(); + } + + if(m_started) { + AudioChunkDetails details; + AudioChunkRef chunk(new AudioChunk()); + + details.m_arrivalTimestamp = iax2Packet->m_arrivalTimestamp; + details.m_numBytes = iax2Packet->m_payloadSize; + details.m_timestamp = iax2Packet->m_timestamp; + details.m_rtpPayloadType = m_codec; + details.m_channel = channel; + details.m_encoding = AlawAudio; + + chunk->SetBuffer(iax2Packet->m_payload, details); + g_audioChunkCallBack(chunk, m_capturePort); + + m_lastUpdated = iax2Packet->m_arrivalTimestamp; + } + + return true; +} + +/* Report AUTHREQ so as to get the invitee call number */ +void Iax2Session::ReportIax2Authreq(Iax2AuthreqInfoRef& authreq) +{ + m_invitee_scallno = StringToInt(authreq->m_sender_callno); +} + +/* Obtain the invitee call number from the ACCEPT, in case an AUTHREQ + * was not sent */ +void Iax2Session::ReportIax2Accept(Iax2AcceptInfoRef& acceptinfo) +{ + m_invitee_scallno = StringToInt(acceptinfo->m_sender_callno); +} + +/* Report NEW */ +void Iax2Session::ReportIax2New(Iax2NewInfoRef& invite) +{ + if(m_new.get() == NULL) { + char szFromIax2Ip[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&invite->m_senderIp, szFromIax2Ip, sizeof(szFromIax2Ip)); + + m_new = invite; + m_invitorIp = invite->m_senderIp; + m_inviteeIp = invite->m_receiverIp; + m_invitor_scallno = StringToInt(invite->m_callNo); + m_srcIpAndCallNo = CStdString(szFromIax2Ip) + "," + invite->m_callNo; + } else { + CStdString inviteString; + invite->ToString(inviteString); + CStdString logMsg; + logMsg.Format("[%s] associating NEW:%s", m_trackingId, inviteString); + LOG4CXX_INFO(m_log, logMsg); + } + + m_news.push_front(invite); +} + + +//===================================================================== +Iax2Sessions::Iax2Sessions() +{ + m_log = Logger::getLogger("iax2sessions"); + if(CONFIG.m_debug) { + m_alphaCounter.Reset(); + } +} + +/* In the cases where AUTHREQ was not sent, we need to still obtain the + * invitee call number and make a map for it */ +void Iax2Sessions::ReportIax2Accept(Iax2AcceptInfoRef& acceptinfo) +{ + CStdString srcIpAndCallNo, log_msg, destIpAndCallNo, numSessions, acceptString; + std::map<CStdString, Iax2SessionRef>::iterator pair; + char invitor_ip[16], invitee_ip[16]; + Iax2SessionRef session; + + /* Assumption is that the receiver is the invitor */ + ACE_OS::inet_ntop(AF_INET, (void*)&acceptinfo->m_receiverIp, invitor_ip, sizeof(invitor_ip)); + ACE_OS::inet_ntop(AF_INET, (void*)&acceptinfo->m_senderIp, invitee_ip, sizeof(invitee_ip)); + srcIpAndCallNo = CStdString(invitor_ip) + "," + acceptinfo->m_receiver_callno; + destIpAndCallNo = CStdString(invitee_ip) + "," + acceptinfo->m_sender_callno; + + pair = m_bySrcIpAndCallNo.find(srcIpAndCallNo); + if(pair != m_bySrcIpAndCallNo.end()) { + session = pair->second; + if(session.get() != NULL) { + /* Excellent! We have an existing session. Now check if we have + * already mapped the invitee call number and IP address */ + + pair = m_byDestIpAndCallNo.find(destIpAndCallNo); + if(pair != m_byDestIpAndCallNo.end()) { + /* We already have a mapping and all necessary information */ + + session = pair->second; + if(session.get() != NULL) { + session->m_iax2_state = IAX2_STATE_LINKED; + LOG4CXX_INFO(m_log, "[" + session->m_trackingId + "] " + "received ACCEPT. Session already " + "registered. Now LINKED."); + return; + } + } + + /* We need to enter the information */ + log_msg.Format("[%s] got ACCEPT for this session. Registering " + "sender call number", session->m_trackingId); + LOG4CXX_INFO(m_log, log_msg); + + session->m_destIpAndCallNo = destIpAndCallNo; + session->m_iax2_state = IAX2_STATE_LINKED; + + m_byDestIpAndCallNo.insert(std::make_pair(session->m_destIpAndCallNo, session)); + session->ReportIax2Accept(acceptinfo); + + acceptinfo->ToString(acceptString); + LOG4CXX_INFO(m_log, "[" + session->m_trackingId + "] supplemented " + "by IAX2 ACCEPT:" + acceptString + ". Status now LINKED"); + + return; + } + } + + /* We don't have an existing session? */ + acceptinfo->ToString(acceptString); + log_msg.Format("Got ACCEPT [%s] but couldn't find corresponding NEW", acceptString); + LOG4CXX_ERROR(m_log, log_msg); + + return; +} + +/* After a NEW has been sent, an AUTHREQ may be sent by the sender and this + * is the stage where we grab the callno of the sender */ +void Iax2Sessions::ReportIax2Authreq(Iax2AuthreqInfoRef& authreq) +{ + CStdString srcIpAndCallNo, log_msg, destIpAndCallNo, numSessions, authreqString; + std::map<CStdString, Iax2SessionRef>::iterator pair; + char invitor_ip[16], invitee_ip[16]; + Iax2SessionRef session; + + /* Assumption is that the receiver is the invitor */ + ACE_OS::inet_ntop(AF_INET, (void*)&authreq->m_receiverIp, invitor_ip, sizeof(invitor_ip)); + ACE_OS::inet_ntop(AF_INET, (void*)&authreq->m_senderIp, invitee_ip, sizeof(invitee_ip)); + srcIpAndCallNo = CStdString(invitor_ip) + "," + authreq->m_receiver_callno; + destIpAndCallNo = CStdString(invitee_ip) + "," + authreq->m_sender_callno; + + pair = m_bySrcIpAndCallNo.find(srcIpAndCallNo); + if(pair != m_bySrcIpAndCallNo.end()) { + /* Excellent! We have an existing session */ + session = pair->second; + + if(session.get() != NULL) { + session->m_destIpAndCallNo = destIpAndCallNo; + m_byDestIpAndCallNo.insert(std::make_pair(session->m_destIpAndCallNo, session)); + session->ReportIax2Authreq(authreq); + session->m_iax2_state = IAX2_STATE_WAITING; + + authreq->ToString(authreqString); + LOG4CXX_INFO(m_log, "[" + session->m_trackingId + "] " + "supplemented by IAX2 AUTHREQ:" + authreqString + + ". Status now WAITING"); + + return; + } + } + + /* We don't have an existing session? */ + authreq->ToString(authreqString); + log_msg.Format("Got AUTHREQ [%s] but couldn't find corresponding NEW", authreqString); + LOG4CXX_ERROR(m_log, log_msg); + + return; +} + +void Iax2Sessions::ReportIax2New(Iax2NewInfoRef& invite) +{ + char szFromIax2Ip[16]; + std::map<CStdString, Iax2SessionRef>::iterator pair; + + ACE_OS::inet_ntop(AF_INET, (void*)&invite->m_senderIp, szFromIax2Ip, sizeof(szFromIax2Ip)); + CStdString IpAndCallNo = CStdString(szFromIax2Ip) + "," + invite->m_callNo; + + pair = m_bySrcIpAndCallNo.find(IpAndCallNo); + if (pair != m_bySrcIpAndCallNo.end()) { + // The session already exists, check the state + CStdString logmsg; + + Iax2SessionRef session = pair->second; + + if(session.get() != NULL) { + if(session->m_iax2_state == IAX2_STATE_UP) { + CStdString log_msg; + + log_msg.Format("[%s] is in the UP state but we've " + "got another NEW from this same IP %s and same " + "source call number %s", session->m_trackingId, + szFromIax2Ip, invite->m_callNo); + + LOG4CXX_ERROR(m_log, log_msg); + return; + } + } + + /* Stop this session and proceed */ + Stop(session); + } + + /* Create a new session */ + CStdString trackingId = m_alphaCounter.GetNext(); + Iax2SessionRef session(new Iax2Session(trackingId)); + session->m_srcIpAndCallNo = IpAndCallNo; + session->ReportIax2New(invite); + m_bySrcIpAndCallNo.insert(std::make_pair(session->m_srcIpAndCallNo, session)); + + CStdString numSessions = IntToString(m_bySrcIpAndCallNo.size()); + LOG4CXX_DEBUG(m_log, CStdString("BySrcIpAndCallNo: ") + numSessions); + + CStdString inviteString; + invite->ToString(inviteString); + LOG4CXX_INFO(m_log, "[" + trackingId + "] created by IAX2 NEW:" + inviteString + " for " + session->m_srcIpAndCallNo); +} + +/* This function is called as a result of a) an IAX2 HANGUP; b) a + * CONTROL HANGUP; or c) an IAX2 REJECT */ +void Iax2Sessions::ReportIax2Hangup(Iax2HangupInfoRef& bye) +{ + CStdString senderIpAndCallNo, log_msg, receiverIpAndCallNo, numSessions, hangupString; + std::map<CStdString, Iax2SessionRef>::iterator pair; + char sender_ip[16], receiver_ip[16]; + Iax2SessionRef session; + + ACE_OS::inet_ntop(AF_INET, (void*)&bye->m_receiverIp, receiver_ip, sizeof(receiver_ip)); + ACE_OS::inet_ntop(AF_INET, (void*)&bye->m_senderIp, sender_ip, sizeof(sender_ip)); + receiverIpAndCallNo = CStdString(receiver_ip) + "," + bye->m_receiver_callno; + senderIpAndCallNo = CStdString(sender_ip) + "," + bye->m_sender_callno; + + /* The recipient of the HANGUP is the Invitor */ + pair = m_bySrcIpAndCallNo.find(receiverIpAndCallNo); + if (pair != m_bySrcIpAndCallNo.end()) { + Iax2SessionRef session = pair->second; + if(session.get() != NULL) { + log_msg.Format("[%s] %s: Hanging up session", session->m_trackingId, session->m_srcIpAndCallNo); + LOG4CXX_INFO(m_log, log_msg); + Stop(session); + } + } + + /* The sender of the HANGUP is the Invitor */ + pair = m_bySrcIpAndCallNo.find(senderIpAndCallNo); + if (pair != m_bySrcIpAndCallNo.end()) { + Iax2SessionRef session = pair->second; + if(session.get() != NULL) { + log_msg.Format("[%s] %s: Hanging up session", session->m_trackingId, session->m_srcIpAndCallNo); + LOG4CXX_INFO(m_log, log_msg); + Stop(session); + } + } + + /* The recipient of the HANGUP is the Invitee */ + pair = m_byDestIpAndCallNo.find(receiverIpAndCallNo); + if (pair != m_byDestIpAndCallNo.end()) { + Iax2SessionRef session = pair->second; + if(session.get() != NULL) { + log_msg.Format("[%s] %s: Hanging up session", session->m_trackingId, session->m_srcIpAndCallNo); + LOG4CXX_INFO(m_log, log_msg); + Stop(session); + } + } + + /* The sender of the HANGUP is the Invitee */ + pair = m_byDestIpAndCallNo.find(senderIpAndCallNo); + if (pair != m_byDestIpAndCallNo.end()) { + Iax2SessionRef session = pair->second; + if(session.get() != NULL) { + log_msg.Format("[%s] %s: Hanging up session", session->m_trackingId, session->m_srcIpAndCallNo); + LOG4CXX_INFO(m_log, log_msg); + Stop(session); + } + } +} + +void Iax2Sessions::Stop(Iax2SessionRef& session) +{ + CStdString numSessions; + + session->Stop(); + + if(session->m_srcIpAndCallNo.size() > 0) { + m_bySrcIpAndCallNo.erase(session->m_srcIpAndCallNo); + + numSessions = IntToString(m_bySrcIpAndCallNo.size()); + LOG4CXX_DEBUG(m_log, CStdString("BySrcIpAndPort: ") + numSessions); + } + + if(session->m_destIpAndCallNo.size() > 0) { + m_byDestIpAndCallNo.erase(session->m_destIpAndCallNo); + + numSessions = IntToString(m_byDestIpAndCallNo.size()); + LOG4CXX_DEBUG(m_log, CStdString("ByDestIpAndPort: ") + numSessions); + } +} + + +void Iax2Sessions::ReportIax2Packet(Iax2PacketInfoRef& iax2Packet) +{ + Iax2SessionRef session; + CStdString logMsg, sourcecallno, IpAndCallNo; + std::map<CStdString, Iax2SessionRef>::iterator pair; + char szSourceIp[16]; + + /* Add this IAX2 voice frame to a session which matches either the source + * IP address and call number or the destination IP address and call number. + * In this context "source IP" refers to the IP address of the machine which + * initiated the session i.e sent the "NEW". Likewise "destination IP" + * refers to the machine to whom the "NEW" was sent. There is no chance + * that there could be a duplicate */ + + ACE_OS::inet_ntop(AF_INET, (void*)&iax2Packet->m_sourceIp, szSourceIp, + sizeof(szSourceIp)); + sourcecallno = IntToString(iax2Packet->m_sourcecallno); + + IpAndCallNo = CStdString(szSourceIp) + "," + sourcecallno; + + pair = m_bySrcIpAndCallNo.find(IpAndCallNo); + if(pair != m_bySrcIpAndCallNo.end()) { + session = pair->second; + + if(session.get() != NULL) { + if(!session->AddIax2Packet(iax2Packet)) { + /* Discontinuity detected? */ + Stop(session); + } + } + + return; + } + + /* Search in the destination IP map */ + pair = m_byDestIpAndCallNo.find(IpAndCallNo); + if(pair != m_byDestIpAndCallNo.end()) { + session = pair->second; + + if(session.get() != NULL) { + if(!session->AddIax2Packet(iax2Packet)) { + /* Discontinuity detected? */ + Stop(session); + } + } + + return; + } + + /* XXX Tracking?? */ + CStdString pktinfo; + iax2Packet->ToString(pktinfo); + //LOG4CXX_INFO(m_log, "Could not figure out where to place packet from "+IpAndCallNo+": [" + pktinfo +"]"); +} + +void Iax2Sessions::StopAll() +{ + time_t forceExpiryTime = time(NULL) + 2*DLLCONFIG.m_rtpSessionWithSignallingTimeoutSec; + Hoover(forceExpiryTime); +} + +void Iax2Sessions::Hoover(time_t now) +{ + CStdString numSessions; + int timeoutSeconds = 0; + Iax2SessionRef session; + std::map<CStdString, Iax2SessionRef>::iterator pair; + std::list<Iax2SessionRef> toDismiss; + std::list<Iax2SessionRef>::iterator it; + + numSessions = IntToString(m_bySrcIpAndCallNo.size()); + LOG4CXX_DEBUG(m_log, "Hoover - check " + numSessions + " sessions time:" + IntToString(now)); + timeoutSeconds = DLLCONFIG.m_rtpSessionWithSignallingTimeoutSec; + + for(pair=m_bySrcIpAndCallNo.begin(); pair!=m_bySrcIpAndCallNo.end(); pair++) { + session = pair->second; + + if((now - session->m_lastUpdated) > timeoutSeconds) + toDismiss.push_back(session); + } + + for (it=toDismiss.begin(); it!=toDismiss.end(); it++) { + session = *it; + LOG4CXX_INFO(m_log, "[" + session->m_trackingId + "] " + session->m_srcIpAndCallNo + " Expired"); + Stop(session); + } + + /* Just in case? */ + toDismiss.clear(); + for(pair=m_byDestIpAndCallNo.begin(); pair!=m_byDestIpAndCallNo.end(); pair++) { + session = pair->second; + + if((now - session->m_lastUpdated) > timeoutSeconds) + toDismiss.push_back(session); + } + + for (it=toDismiss.begin(); it!=toDismiss.end(); it++) { + session = *it; + LOG4CXX_INFO(m_log, "[" + session->m_trackingId + "] " + session->m_destIpAndCallNo + " Expired"); + Stop(session); + } +} + +//========================================================== +Iax2NewInfo::Iax2NewInfo() +{ + m_senderIp.s_addr = 0; + m_receiverIp.s_addr = 0; + m_caller = "HIDDEN"; /* Unless obtained */ + m_validated= false; +} + +void Iax2NewInfo::ToString(CStdString& string) +{ + char senderIp[16], receiverIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, + sizeof(receiverIp)); + + string.Format("sender:%s receiver: %s caller:%s callee:%s srccallno: %s", + senderIp, receiverIp, m_caller, m_callee, m_callNo); +} + +//========================================================== +Iax2AuthreqInfo::Iax2AuthreqInfo() +{ + m_senderIp.s_addr = 0; + m_receiverIp.s_addr = 0; +} + +void Iax2AuthreqInfo::ToString(CStdString& string) +{ + char senderIp[16], receiverIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, + sizeof(receiverIp)); + + string.Format("sender:%s receiver:%s sender_callno:%s receiver_callno:%s", + senderIp, receiverIp, m_sender_callno, m_receiver_callno); +} + +//========================================================== +Iax2AcceptInfo::Iax2AcceptInfo() +{ + m_senderIp.s_addr = 0; + m_receiverIp.s_addr = 0; +} + +void Iax2AcceptInfo::ToString(CStdString& string) +{ + char senderIp[16], receiverIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, + sizeof(receiverIp)); + + string.Format("sender:%s receiver:%s sender_callno:%s receiver_callno:%s", + senderIp, receiverIp, m_sender_callno, m_receiver_callno); +} + +//========================================================== +Iax2HangupInfo::Iax2HangupInfo() +{ + m_senderIp.s_addr = 0; + m_receiverIp.s_addr = 0; +} + +void Iax2HangupInfo::ToString(CStdString& string) +{ + char senderIp[16], receiverIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, + sizeof(receiverIp)); + + string.Format("sender:%s receiver:%s sender_callno:%s receiver_callno:%s", + senderIp, receiverIp, m_sender_callno, m_receiver_callno); +} + +//========================================================== +Iax2PacketInfo::Iax2PacketInfo() +{ +} + +void Iax2PacketInfo::ToString(CStdString& string) +{ + char senderIp[16], receiverIp[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&m_sourceIp, senderIp, sizeof(senderIp)); + ACE_OS::inet_ntop(AF_INET, (void*)&m_destIp, receiverIp, + sizeof(receiverIp)); + + string.Format("sender:%s receiver:%s sender_callno:%d receiver_callno:%d " + "type:%d size:%d timestamp: %d", senderIp, receiverIp, + m_sourcecallno, m_destcallno, m_payloadType, + m_payloadSize, m_timestamp); +} + diff --git a/orkaudio/audiocaptureplugins/voip/Iax2Session.h b/orkaudio/audiocaptureplugins/voip/Iax2Session.h new file mode 100644 index 0000000..ef1944f --- /dev/null +++ b/orkaudio/audiocaptureplugins/voip/Iax2Session.h @@ -0,0 +1,275 @@ +/* + * Oreka -- A media capture and retrieval platform + * + * Copyright (C) 2005, orecx LLC + * + * http://www.orecx.com + * + * This program is free software, distributed under the terms of + * the GNU General Public License. + * Please refer to http://www.gnu.org/copyleft/gpl.html + * + */ + +#ifndef __IAX2SESSION_H__ +#define __IAX2SESSION_H__ + +#include <log4cxx/logger.h> +#include "Iax2Session.h" +#include <map> +#include "ace/Singleton.h" +#include "PacketHeaderDefs.h" + +using namespace log4cxx; + +/* The frame types we're interested in */ +#define IAX2_FRAME_VOICE 2 +#define IAX2_FRAME_CONTROL 4 +#define IAX2_FRAME_IAX 6 + +/* The full frame subclass values for IAX2_FRAME_IAX frames + * which we're interested in */ +#define IAX2_COMMAND_NEW 1 +#define IAX2_COMMAND_HANGUP 5 +#define IAX2_COMMAND_REJECT 6 +#define IAX2_COMMAND_ACCEPT 7 +#define IAX2_COMMAND_AUTHREQ 8 + +/* The control frame subclass values for IAX2_FRAME_CONTROL + * which we're interested in */ +#define IAX2_CONTROL_HANGUP 1 + +/* The information elements we're interested in */ +#define IAX2_IE_CALLED_NUMBER 1 +#define IAX2_IE_CALLING_NUMBER 2 +#define IAX2_IE_USERNAME 6 +#define IAX2_IE_FORMAT 9 +#define IAX2_IE_AUTHMETHODS 14 +#define IAX2_IE_CHALLENGE 15 + +struct iax2_ies { + char *caller; + char *callee; /* Mandatory for NEW */ + unsigned int format; /* Format Mandatory for ACCEPT */ + char *username; /* Mandatory for AUTHREQ */ + unsigned int authmethods; /* Mandatory for AUTHREQ */ + char *challenge; /* Mandatory for AUTHREQ */ +}; + +/* Supported Voice Codecs */ +/* G.723.1 compression */ +#define IAX2_CODEC_G723_1 (1 << 0) +/* GSM compression */ +#define IAX2_CODEC_GSM (1 << 1) +/* Raw mu-law data (G.711) */ +#define IAX2_CODEC_ULAW (1 << 2) +/* Raw A-law data (G.711) */ +#define IAX2_CODEC_ALAW (1 << 3) +/* ADPCM (G.726, 32kbps) */ +#define IAX2_CODEC_G726 (1 << 4) +/* ADPCM (IMA) */ +#define IAX2_CODEC_ADPCM (1 << 5) +/* Raw 16-bit Signed Linear (8000 Hz) PCM */ +#define IAX2_CODEC_SLINEAR (1 << 6) +/* LPC10, 180 samples/frame */ +#define IAX2_CODEC_LPC10 (1 << 7) +/* G.729A audio */ +#define IAX2_CODEC_G729A (1 << 8) +/* SpeeX Free Compression */ +#define IAX2_CODEC_SPEEX (1 << 9) +/* iLBC Free Compression */ +#define IAX2_CODEC_ILBC (1 << 10) + +class Iax2AcceptInfo +{ +public: + Iax2AcceptInfo(); + void ToString(CStdString& string); + + struct in_addr m_senderIp; + struct in_addr m_receiverIp; + + CStdString m_sender_callno; + CStdString m_receiver_callno; +}; +typedef boost::shared_ptr<Iax2AcceptInfo> Iax2AcceptInfoRef; + + +class Iax2AuthreqInfo +{ +public: + Iax2AuthreqInfo(); + void ToString(CStdString& string); + + struct in_addr m_senderIp; + struct in_addr m_receiverIp; + + CStdString m_sender_callno; + CStdString m_receiver_callno; +}; +typedef boost::shared_ptr<Iax2AuthreqInfo> Iax2AuthreqInfoRef; + +class Iax2NewInfo +{ +public: + Iax2NewInfo(); + void ToString(CStdString& string); + + struct in_addr m_senderIp; + struct in_addr m_receiverIp; + + CStdString m_caller; /* CALLING NUMBER */ + CStdString m_callee; /* CALLED NUMBER */ + CStdString m_callNo; /* This is the source call number */ + + bool m_validated; // true when an IAX2 voice stream has been seen for the NEW +}; +typedef boost::shared_ptr<Iax2NewInfo> Iax2NewInfoRef; + +class Iax2HangupInfo +{ +public: + Iax2HangupInfo(); + void ToString(CStdString& string); + /* Even if we did not have the destination call number, + * we will be able to look it up using m_byDestIpAndCallNo */ + struct in_addr m_senderIp; + struct in_addr m_receiverIp; + + CStdString m_sender_callno; + CStdString m_receiver_callno; +}; +typedef boost::shared_ptr<Iax2HangupInfo> Iax2HangupInfoRef; + +#define IAX2_FRAME_FULL 1 +#define IAX2_FRAME_MINI 2 +#define IAX2_FRAME_TRUNK 3 + +/* IAX2_FRAME_VOICE Packet Information. May be full or mini.*/ +class Iax2PacketInfo +{ +public: + Iax2PacketInfo(); + void ToString(CStdString& string); + + struct in_addr m_sourceIp; + struct in_addr m_destIp; + unsigned short m_sourcecallno; /* Always there */ + unsigned short m_destcallno; /* May be zero for mini frames */ + + unsigned int m_frame_type; + unsigned int m_payloadSize; + unsigned short m_payloadType; + unsigned char* m_payload; + unsigned short m_seqNum; + unsigned int m_timestamp; + time_t m_arrivalTimestamp; +}; +typedef boost::shared_ptr<Iax2PacketInfo> Iax2PacketInfoRef; + +// ============================================================ + +#define IAX2_STATE_WAITING 1 +#define IAX2_STATE_LINKED 2 +#define IAX2_STATE_UP 3 + +class Iax2Session +{ +public: + Iax2Session(CStdString& trackingId); +#define IAX2_PROTOCOL_NUM 1 +#define IAX2_PROTOCOL_STR "IAX2" + void Stop(); + void Start(); + bool AddIax2Packet(Iax2PacketInfoRef& iax2Packet); + void ReportIax2New(Iax2NewInfoRef& newinfo); + void ReportIax2Accept(Iax2AcceptInfoRef& acceptinfo); + void ReportIax2Authreq(Iax2AuthreqInfoRef& authreq); + + CStdString m_trackingId; + CStdString m_srcIpAndCallNo; + CStdString m_destIpAndCallNo; + Iax2NewInfoRef m_new; + time_t m_lastUpdated; + CStdString m_localParty; + CStdString m_remoteParty; + CaptureEvent::DirectionEnum m_direction; + int m_numIax2Packets; + int m_codec; + int m_iax2_state; + +private: + /* XXX Way of "freeing" sessions which've been idle for a + * while? Just in case they never hang up. Answer is Hoover() */ + void ProcessMetadataIax2(Iax2PacketInfoRef&); + void ProcessMetadataIax2Incoming(); + void ProcessMetadataIax2Outgoing(); + void UpdateMetadataIax2(Iax2PacketInfoRef& iax2Packet, bool); + void ProcessMetadataRawIax2(Iax2PacketInfoRef&); + void ProcessMetadataSkinny(Iax2PacketInfoRef& iax2Packet); + void ReportMetadata(); + void GenerateOrkUid(); + + Iax2PacketInfoRef m_lastIax2Packet; + Iax2PacketInfoRef m_lastIax2PacketSide1; + Iax2PacketInfoRef m_lastIax2PacketSide2; + + struct in_addr m_invitorIp; + struct in_addr m_inviteeIp; + struct in_addr m_localIp; + struct in_addr m_remoteIp; + + unsigned short m_invitor_scallno; + unsigned short m_invitee_scallno; + + //struct in_addr m_localMac; + //struct in_addr m_remoteMac; + LoggerPtr m_log; + CStdString m_capturePort; + bool m_started; + bool m_stopped; + time_t m_beginDate; + CStdString m_orkUid; + bool m_hasDuplicateIax2; + unsigned int m_highestIax2SeqNumDelta; + double m_minIax2SeqDelta; + double m_minIax2TimestampDelta; + //TcpAddressList m_iax2AddressList; + std::list<Iax2NewInfoRef> m_news; +}; +typedef boost::shared_ptr<Iax2Session> Iax2SessionRef; + +//=================================================================== +class Iax2Sessions +{ +public: + Iax2Sessions(); + void Stop(Iax2SessionRef& session); + void StopAll(); + void ReportIax2New(Iax2NewInfoRef& invite); + void ReportIax2Hangup(Iax2HangupInfoRef& hangup); + void ReportIax2Accept(Iax2AcceptInfoRef& acceptinfo); + void ReportIax2Authreq(Iax2AuthreqInfoRef& authreq); + void ReportIax2Packet(Iax2PacketInfoRef& iax2Packet); + void Hoover(time_t now); +private: + std::map<CStdString, Iax2SessionRef> m_bySrcIpAndCallNo; /* With IAX2 the callnos can easily + * be duplicated across machines + * so we need to use the ip and callno */ + std::map<CStdString, Iax2SessionRef> m_byDestIpAndCallNo; /* Invitee Ip and Call Id */ + LoggerPtr m_log; + AlphaCounter m_alphaCounter; +}; +typedef ACE_Singleton<Iax2Sessions, ACE_Thread_Mutex> Iax2SessionsSingleton; + +/* Miscellaneous */ +static inline unsigned int get_unaligned_uint32(void *p) +{ + struct pckd { unsigned int d; } __attribute__((packed)); + struct pckd *pp = (struct pckd *)p; + + return pp->d; +} + +#endif + diff --git a/orkaudio/audiocaptureplugins/voip/Makefile.am b/orkaudio/audiocaptureplugins/voip/Makefile.am index 6fe21b1..5ea43a8 100644 --- a/orkaudio/audiocaptureplugins/voip/Makefile.am +++ b/orkaudio/audiocaptureplugins/voip/Makefile.am @@ -1,6 +1,6 @@ METASOURCES = AUTO lib_LTLIBRARIES = libvoip.la -libvoip_la_SOURCES = VoIpConfig.cpp VoIp.cpp Rtp.cpp RtpSession.cpp \ +libvoip_la_SOURCES = VoIpConfig.cpp VoIp.cpp Rtp.cpp Iax2Session.cpp RtpSession.cpp \ AudioCapturePluginCommon.cpp PacketHeaderDefs.cpp libvoip_la_LDFLAGS = -module AM_CPPFLAGS = -D_REENTRANT diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index efa959a..654ba95 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -215,5 +215,54 @@ typedef enum int SkinnyMessageToEnum(CStdString& msg); CStdString SkinnyMessageToString(int msgEnum); +/* + * IAX2 Packet Headers + */ + +/* XXX No support for encryption */ + +/* Full frame */ +struct Iax2FullHeader { + unsigned short scallno; + unsigned short dcallno; + unsigned int ts; + unsigned char oseqno; + unsigned char iseqno; + unsigned char type; + unsigned char c_sub; + unsigned char ie_data[0]; +} __attribute__ ((__packed__)); + +/* Mini frame for voice */ +struct Iax2MiniHeader { + unsigned short scallno; + unsigned short ts; /* Low 16 bits from transmitting peer's full 32-bit ts */ + unsigned char data[0]; +} __attribute__ ((__packed__)); + +/* Meta trunk frame */ +struct Iax2MetaTrunkHeader { + unsigned short meta; /* zero for meta frames */ + unsigned char metacmd; + unsigned char cmddata; + unsigned int ts; + unsigned char data[0]; +} __attribute__ ((__packed__)); + +/* Mini trunked frame with timestamps (trunk timestamps + * flag is set to 0 */ +struct Iax2MetaTrunkEntry { + unsigned short scallno; + unsigned short len; + unsigned char data[0]; +} __attribute__ ((__packed__)); + +/* Mini trunked frame with timestamps (trunk timestamps + * flag is set to 1 */ +struct Iax2MetaTrunkEntryTs { + unsigned short len; + struct Iax2MiniHeader mini; +} __attribute__ ((__packed__)); + #endif diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index ab3de80..ef6807f 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -37,6 +37,7 @@ #include "PacketHeaderDefs.h" #include "Rtp.h" #include "RtpSession.h" +#include "Iax2Session.h" extern AudioChunkCallBackFunction g_audioChunkCallBack; extern CaptureEventCallBackFunction g_captureEventCallBack; @@ -204,11 +205,765 @@ char* GrabLine(char* start, char* limit, CStdString& out) return c; } +static int iax2_codec_to_rtp_payloadtype(int codec) +{ + switch(codec) { + case IAX2_CODEC_ULAW: + return 0; + case IAX2_CODEC_G726: + return 2; + case IAX2_CODEC_GSM: + return 3; + case IAX2_CODEC_G723_1: + return 4; + case IAX2_CODEC_ADPCM: + return 5; + case IAX2_CODEC_LPC10: + return 7; + case IAX2_CODEC_ALAW: + return 8; + case IAX2_CODEC_SLINEAR: + return 9; + case IAX2_CODEC_G729A: + return 18; + case IAX2_CODEC_ILBC: + return 97; + default: + return -1; + } + + /* NOT REACHED */ + return -1; +} + +static int get_uncompressed_subclass(unsigned char c_sub) +{ + if (c_sub & 0x80) { + /* 'C' bit is set (refer to standard) */ + if (c_sub == 0xFF) + return -1; + else + return 1 << (c_sub & ~0x80 & 0x1F); + } else { + /* 'C' bit in SubClass component not set */ + return c_sub; + } +} + +static int parse_iax2_ies(struct iax2_ies *ies, unsigned char *data, int datalen) +{ + int len = 0, ie = 0, odlen = datalen, pass=1; + CStdString logmsg; + + memset(ies, 0, (int)sizeof(struct iax2_ies)); + while(datalen >= 2) { + ie = data[0]; + len = data[1]; + + //logmsg.Format("Looking up IE %d (len=%d)", ie, len); + //LOG4CXX_INFO(s_packetLog, logmsg); + + if (len > datalen - 2) { + /* Strange. The quoted length of the IE is past the actual + * bounds of the IEs size */ + logmsg.Format("Error parsing IEs Pass=%d Length of IE=%d, " + "datalen-2=%d, IE=%d, OrigDlen=%d", pass, len, datalen-2, ie, odlen); + LOG4CXX_INFO(s_packetLog, logmsg); + return -1; + } + + switch(ie) { + case IAX2_IE_CALLED_NUMBER: + ies->callee = (char *)data + 2; + break; + case IAX2_IE_CALLING_NUMBER: + ies->caller = (char *)data + 2; + break; + case IAX2_IE_FORMAT: + if(len == (int)sizeof(unsigned int)) + ies->format = ntohl(get_unaligned_uint32(data+2)); + else + ies->format = 0; /* Invalid */ + break; + case IAX2_IE_USERNAME: + ies->username = (char *)data + 2; + break; + case IAX2_IE_AUTHMETHODS: + if(len == (int)sizeof(unsigned int)) + ies->authmethods = ntohl(get_unaligned_uint32(data+2)); + else + ies->authmethods = 0; /* Invalid */ + break; + case IAX2_IE_CHALLENGE: + ies->challenge = (char *)data + 2; + break; + default: + /* Ignore the rest */ + break; + } + +#if 0 /* Debug headaches caused by udpHeader->len */ + char tmpt[256]; + memset(tmpt, 0, sizeof(tmpt)); + memcpy(tmpt, data+2, len); + logmsg.Format("Got %s", tmpt); + LOG4CXX_INFO(s_packetLog, logmsg); +#endif + + data[0] = 0; + datalen -= (len + 2); + data += (len + 2); + pass++; + } + + *data = '\0'; + if(datalen) { + /* IE contents likely to be invalid because we should have totally + * consumed the entire amount of data */ + CStdString logmsg; + + logmsg.Format("Error parsing IEs. datalen left=%d", len, datalen, ie); + LOG4CXX_INFO(s_packetLog, logmsg); + + return -1; + } + + return 0; +} + +void iax2_dump_frame(struct Iax2FullHeader *fh, char *source, char *dest) +{ + const char *frames[] = { + "(0?)", + "DTMF ", + "VOICE ", + "VIDEO ", + "CONTROL", + "NULL ", + "IAX ", + "TEXT ", + "IMAGE ", + "HTML ", + "CNG " }; + const char *iaxs[] = { + "(0?)", + "NEW ", + "PING ", + "PONG ", + "ACK ", + "HANGUP ", + "REJECT ", + "ACCEPT ", + "AUTHREQ", + "AUTHREP", + "INVAL ", + "LAGRQ ", + "LAGRP ", + "REGREQ ", + "REGAUTH", + "REGACK ", + "REGREJ ", + "REGREL ", + "VNAK ", + "DPREQ ", + "DPREP ", + "DIAL ", + "TXREQ ", + "TXCNT ", + "TXACC ", + "TXREADY", + "TXREL ", + "TXREJ ", + "QUELCH ", + "UNQULCH", + "POKE ", + "PAGE ", + "MWI ", + "UNSPRTD", + "TRANSFR", + "PROVISN", + "FWDWNLD", + "FWDATA " + }; + const char *cmds[] = { + "(0?)", + "HANGUP ", + "RING ", + "RINGING", + "ANSWER ", + "BUSY ", + "TKOFFHK", + "OFFHOOK" }; + char class2[20]; + char subclass2[20]; + CStdString tmp; + const char *cclass; + const char *subclass; + char *dir; + + if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) { + snprintf(class2, sizeof(class2), "(%d?)", fh->type); + cclass = class2; + } else { + cclass = frames[(int)fh->type]; + } + + if (fh->type == IAX2_FRAME_IAX) { + if (fh->c_sub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) { + snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->c_sub); + subclass = subclass2; + } else { + subclass = iaxs[(int)fh->c_sub]; + } + } else if (fh->type == IAX2_FRAME_CONTROL) { + if (fh->c_sub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { + snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->c_sub); + subclass = subclass2; + } else { + subclass = cmds[(int)fh->c_sub]; + } + } else { + snprintf(subclass2, sizeof(subclass2), "%d", fh->c_sub); + subclass = subclass2; + } + + tmp.Format("IAX2-Frame -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s", + fh->oseqno, fh->iseqno, cclass, subclass); + LOG4CXX_INFO(s_packetLog, tmp); + tmp.Format(" Timestamp: %05lums SCall: %5.5d DCall: %5.5d [Source: %s Dest: %s]", + (unsigned long)ntohl(fh->ts), + ntohs(fh->scallno) & ~0x8000, ntohs(fh->dcallno) & ~0x8000, source, dest); + + LOG4CXX_INFO(s_packetLog, tmp); +} + +/* See if this is an IAX2 NEW. If so, process */ +bool TryIax2New(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + struct iax2_ies ies; + int ies_len = 0, udp_act_payload_len = 0; + Iax2NewInfoRef info(new Iax2NewInfo()); + char source_ip[16], dest_ip[16]; + CStdString logmsg; + + memset(&ies, 0, sizeof(ies)); + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + ies_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + +#if 0 /* Debug headaches caused by udpHeader->len */ + /* Beware that udpHeader->len is not the length of the udpPayload + * but rather this includes the length of the UDP header as well. + * I.e watch out for the figure "8" as you debug ;-) */ + { + char source_ip[16], dest_ip[16]; + + ACE_OS::inet_ntop(AF_INET, (void*)&ipHeader->ip_src, source_ip, sizeof(source_ip)); + ACE_OS::inet_ntop(AF_INET, (void*)&ipHeader->ip_dest, dest_ip, sizeof(dest_ip)); + iax2_dump_frame(fh, source_ip, dest_ip); + } + + logmsg.Format("UDP_Payload=%p UDP+FH_Payload=%p FH->IEDATA=%p ies_len=%d " + "udpHeader->len-sizeof(fullhdr)=%d (ntohs(udpHeader->len)" + "-sizeof(UdpHeaderStruct))=%d", udpPayload, udpPayload+ + sizeof(*fh), fh->ie_data, ies_len, (ntohs(udpHeader->len)- + sizeof(*fh)), (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct))); + LOG4CXX_INFO(s_packetLog, logmsg); +#endif + + if(fh->type != IAX2_FRAME_IAX) + return false; /* Frame type must be IAX */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_COMMAND_NEW) + return false; /* Subclass must be NEW */ + + if(parse_iax2_ies(&ies, fh->ie_data, ies_len)) + return false; /* Invalid "full" frame received */ + + if(!ies.callee) + return false; /* According to the SPEC, a NEW MUST have a + * callee (Called Number) */ + + if(!strlen(ies.callee)) + return false; /* According to the SPEC, a NEW MUST have a + * callee (Called Number) */ + + if(!ies.caller) { + ies.caller = "WITHELD"; + } else { + if(!strlen(ies.caller)) { + ies.caller = "WITHELD"; + } + } + + /* Statistically this is most likely a NEW IAX2 frame. */ + + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_caller = CStdString(ies.caller); + info->m_callee = CStdString(ies.callee); + info->m_callNo = IntToString(ntohs(fh->scallno) & ~0x8000); + + /* Report the packet */ + Iax2SessionsSingleton::instance()->ReportIax2New(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 NEW frame"); + + return true; +} + +bool TryIax2Accept(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + struct iax2_ies ies; + int ies_len = 0, udp_act_payload_len = 0; + Iax2AcceptInfoRef info(new Iax2AcceptInfo()); + + memset(&ies, 0, sizeof(ies)); + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_IAX) + return false; /* Frame type must be IAX */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_COMMAND_ACCEPT) + return false; /* Subclass must be ACCEPT */ + + ies_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + + /* In this case, this just serves to test the integrity of the + * Information Elements */ + if(parse_iax2_ies(&ies, fh->ie_data, ies_len)) + return false; /* Invalid "full" frame received */ + + if(!ies.format) + return false; /* According to the SPEC, ACCEPT must have + * a format specified */ + + /* We have an ACCEPT */ + + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_sender_callno = IntToString(ntohs(fh->scallno) & ~0x8000); + info->m_receiver_callno = IntToString(ntohs(fh->dcallno) & ~0x8000); + + Iax2SessionsSingleton::instance()->ReportIax2Accept(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 ACCEPT frame"); + + return true; +} + +bool TryIax2Authreq(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + struct iax2_ies ies; + int ies_len = 0, udp_act_payload_len = 0; + Iax2AuthreqInfoRef info(new Iax2AuthreqInfo()); + + memset(&ies, 0, sizeof(ies)); + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_IAX) + return false; /* Frame type must be IAX */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_COMMAND_AUTHREQ) + return false; /* Subclass must be AUTHREQ */ + + ies_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + + /* In this case, this just serves to test the integrity of the + * Information Elements */ + if(parse_iax2_ies(&ies, fh->ie_data, ies_len)) + return false; /* Invalid "full" frame received */ + + + if(!ies.username) + return false; /* According to the spec AUTHREQ must have + * a user name. Can it be empty? */ + + /* + if(!strlen(ies.username)) + return false; * According to the spec AUTHREQ must have + * a user name. * + */ + + if(!ies.authmethods) + return false; /* According to the spec AUTHREQ must have + * AUTHMETHODS */ + + if(!ies.challenge) + return false; /* According to the spec, AUTHREQ must have + * a CHALLENGE string. Can it be empty? */ + + + /* We have an AUTHREQ */ + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_sender_callno = IntToString(ntohs(fh->scallno) & ~0x8000); + info->m_receiver_callno = IntToString(ntohs(fh->dcallno) & ~0x8000); + + /* Report the packet */ + Iax2SessionsSingleton::instance()->ReportIax2Authreq(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 AUTHREQ frame"); + + return true; +} + +/* HANGUP via IAX frame */ +bool TryIax2Hangup(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + struct iax2_ies ies; + int ies_len = 0, udp_act_payload_len = 0; + Iax2HangupInfoRef info(new Iax2HangupInfo()); + + memset(&ies, 0, sizeof(ies)); + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_IAX) + return false; /* Frame type must be IAX */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_COMMAND_HANGUP) + return false; /* Subclass must be HANGUP */ + + ies_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + + /* In this case, this just serves to test the integrity of the + * Information Elements */ + if(parse_iax2_ies(&ies, fh->ie_data, ies_len)) + return false; /* Invalid "full" frame received */ + + /* We have a HANGUP */ + + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_sender_callno = IntToString(ntohs(fh->scallno) & ~0x8000); + info->m_receiver_callno = IntToString(ntohs(fh->dcallno) & ~0x8000); + + /* Report the packet */ + Iax2SessionsSingleton::instance()->ReportIax2Hangup(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 HANGUP frame"); + + return true; +} + +/* HANGUP via CONTROL frame */ +bool TryIax2ControlHangup(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + Iax2HangupInfoRef info(new Iax2HangupInfo()); + int udp_act_payload_len = 0; + + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_CONTROL) + return false; /* Frame type must be CONTROL */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_CONTROL_HANGUP) + return false; /* Subclass must be HANGUP */ + + /* We have a HANGUP */ + + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_sender_callno = IntToString(ntohs(fh->scallno) & ~0x8000); + info->m_receiver_callno = IntToString(ntohs(fh->dcallno) & ~0x8000); + + /* Report the packet */ + Iax2SessionsSingleton::instance()->ReportIax2Hangup(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 CONTROL HANGUP frame"); + + return true; +} + +bool TryIax2Reject(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + struct iax2_ies ies; + int ies_len = 0, udp_act_payload_len = 0; + Iax2HangupInfoRef info(new Iax2HangupInfo()); + + memset(&ies, 0, sizeof(ies)); + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_IAX) + return false; /* Frame type must be IAX */ + + if(get_uncompressed_subclass(fh->c_sub) != IAX2_COMMAND_REJECT) + return false; /* Subclass must be REJECT */ + + ies_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + + /* In this case, this just serves to test the integrity of the + * Information Elements */ + if(parse_iax2_ies(&ies, fh->ie_data, ies_len)) + return false; /* Invalid "full" frame received */ + + /* We have a REJECT */ + + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + info->m_sender_callno = IntToString(ntohs(fh->scallno) & ~0x8000); + info->m_receiver_callno = IntToString(ntohs(fh->dcallno) & ~0x8000); + + /* Report the packet */ + Iax2SessionsSingleton::instance()->ReportIax2Hangup(info); + + LOG4CXX_INFO(s_packetLog, "Processed IAX2 REJECT frame"); + + return true; +} + +bool TryIax2FullVoiceFrame(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2FullHeader *fh = (struct Iax2FullHeader *)udpPayload; + int data_len = 0, codec = 0, pt = 0, udp_act_payload_len = 0; + Iax2PacketInfoRef info(new Iax2PacketInfo()); + + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*fh)) + return false; /* Frame too small */ + + if(!(ntohs(fh->scallno) & 0x8000)) + return false; /* Not a full frame */ + + if(fh->type != IAX2_FRAME_VOICE) + return false; /* Frame type must be VOICE */ + + codec = get_uncompressed_subclass(fh->c_sub); + if((pt = iax2_codec_to_rtp_payloadtype(codec)) < 0) { + CStdString logmsg; + + logmsg.Format("Invalid payload type %d received for " + "IAX_FRAME_VOICE, IAX2 codec %d", pt, codec); + LOG4CXX_INFO(s_packetLog, logmsg); + return false; /* Invalid codec type received */ + } + + data_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*fh)); + if(data_len == 0) + return false; /* Empty packet? */ + + /* We have a full VOICE frame */ + + info->m_sourceIp = ipHeader->ip_src; + info->m_destIp = ipHeader->ip_dest; + info->m_sourcecallno = (ntohs(fh->scallno) & ~0x8000); + info->m_destcallno = (ntohs(fh->dcallno) & ~0x8000); + info->m_payloadSize = data_len; + info->m_payload = udpPayload+sizeof(*fh); + info->m_payloadType = pt; + info->m_timestamp = ntohl(fh->ts); + info->m_arrivalTimestamp = time(NULL); + info->m_frame_type = IAX2_FRAME_FULL; + + Iax2SessionsSingleton::instance()->ReportIax2Packet(info); + + CStdString logmsg; + logmsg.Format("Processed IAX2 FULL VOICE fram, pt %d", pt); + LOG4CXX_INFO(s_packetLog, logmsg); + + return true; +} + +bool TryIax2MetaTrunkFrame(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2MetaTrunkHeader *mh = (struct Iax2MetaTrunkHeader *)udpPayload; + struct Iax2MetaTrunkEntry *supermini = NULL; + struct Iax2MetaTrunkEntryTs *mini = NULL; + int content_type = 0; /* 0 means mini frames, 1 means super mini (no timestampes) */ + int frame_ts = 0; /* Timestamp of frame */ + int data_len = 0; + int entries = 0, udp_act_payload_len = 0; + Iax2PacketInfoRef info(new Iax2PacketInfo()); + + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*mh)) + return false; /* Frame too small */ + + if(mh->meta != 0) + return false; /* Must be zero */ + + if(mh->metacmd & 0x80) + return false; /* 'V' bit must be set to zero */ + + if(mh->metacmd != 1) + return false; /* metacmd must be 1 */ + + /* Get the length of the information apart from the + * meta trunk header */ + data_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*mh)); + if(data_len == 0) + return false; /* Empty packet? */ + + /* Step over the meta trunk header */ + udpPayload += sizeof(*mh); + + /* Determine whether the trunk contents have their own + * timestamps or not */ + if(mh->cmddata & 0x01) + content_type = 1; + else + content_type = 0; + + if(content_type) { + /* Have timestamps */ + + while(data_len) { + if(data_len < sizeof(*mini)) + break; + + mini = (struct Iax2MetaTrunkEntryTs *)udpPayload; + + if(data_len < sizeof(*mini)+ntohs(mini->len)) + break; + + info->m_sourceIp = ipHeader->ip_src; + info->m_destIp = ipHeader->ip_dest; + info->m_sourcecallno = (ntohs(mini->mini.scallno) & ~0x8000); + info->m_destcallno = 0; + info->m_payloadSize = ntohs(mini->len); + info->m_payload = udpPayload+sizeof(*mini); + info->m_payloadType = 0; + info->m_timestamp = ntohs(mini->mini.ts); + info->m_arrivalTimestamp = time(NULL); + info->m_frame_type = IAX2_FRAME_MINI; + + Iax2SessionsSingleton::instance()->ReportIax2Packet(info); + entries += 1; + + udpPayload += sizeof(*mini)+ntohs(mini->len); + data_len -= sizeof(*mini)+ntohs(mini->len); + } + } else { + /* Have no timestamps */ + while(data_len) { + if(data_len < sizeof(*supermini)) + break; + + supermini = (struct Iax2MetaTrunkEntry *)udpPayload; + + if(data_len < sizeof(*supermini)+ntohs(supermini->len)) + break; + + info->m_sourceIp = ipHeader->ip_src; + info->m_destIp = ipHeader->ip_dest; + info->m_sourcecallno = (ntohs(supermini->scallno) & ~0x8000); + info->m_destcallno = 0; + info->m_payloadSize = ntohs(supermini->len); + info->m_payload = udpPayload+sizeof(*supermini); + info->m_payloadType = 0; + info->m_timestamp = 0; + info->m_arrivalTimestamp = time(NULL); + info->m_frame_type = IAX2_FRAME_MINI; + + Iax2SessionsSingleton::instance()->ReportIax2Packet(info); + entries += 1; + + udpPayload += sizeof(*supermini)+ntohs(supermini->len); + data_len -= sizeof(*supermini)+ntohs(supermini->len); + } + } + + + if(entries > 0) { + CStdString logmsg; + + logmsg.Format("Processed IAX2 Meta Trunk packet with %d entries", entries); + LOG4CXX_DEBUG(s_packetLog, logmsg); + return true; + } + + return false; /* No valid entries in this so-called meta trunk frame */ +} + +bool TryIax2MiniVoiceFrame(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, + UdpHeaderStruct* udpHeader, u_char* udpPayload) +{ + struct Iax2MiniHeader *mini = (struct Iax2MiniHeader *)udpPayload; + int data_len = 0, udp_act_payload_len = 0; + Iax2PacketInfoRef info(new Iax2PacketInfo()); + + udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + if(udp_act_payload_len < sizeof(*mini)) + return false; /* Frame too small */ + + if((ntohs(mini->scallno) & 0x8000)) + return false; /* Not a Mini frame */ + + data_len = ((u_char*)ipHeader+ntohs(ipHeader->ip_len))-(udpPayload+sizeof(*mini)); + if(data_len == 0) + return false; /* Empty packet? */ + + info->m_sourceIp = ipHeader->ip_src; + info->m_destIp = ipHeader->ip_dest; + info->m_sourcecallno = (ntohs(mini->scallno) & ~0x8000); + info->m_destcallno = 0; + info->m_payloadSize = data_len; + info->m_payload = udpPayload+sizeof(*mini); + info->m_payloadType = 0; + info->m_timestamp = ntohl(mini->ts); + info->m_arrivalTimestamp = time(NULL); + info->m_frame_type = IAX2_FRAME_MINI; + + Iax2SessionsSingleton::instance()->ReportIax2Packet(info); + + //LOG4CXX_INFO(s_packetLog, "Processed IAX2 Mini Voice packet"); + + return true; +} + bool TryRtp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload) { bool result = false; RtpHeaderStruct* rtpHeader = (RtpHeaderStruct*)udpPayload; + /* Ensure that the UDP payload is at least sizeof(RtpHeaderStruct) */ + if(ntohs(udpHeader->len) < sizeof(RtpHeaderStruct)) + return false; + if (rtpHeader->version == 2) { u_short source = ntohs(udpHeader->source); @@ -268,6 +1023,13 @@ bool TryRtp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpH bool TrySipBye(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload) { bool result = false; + int udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + + /* Judgine from the memcmp() below, we need the UDP payload + * length to be at least 3 bytes. -- Gerald */ + if(udp_act_payload_len < 3) + return false; /* Frame too small */ + if (memcmp("BYE", (void*)udpPayload, 3) == 0) { result = true; @@ -292,6 +1054,13 @@ bool TrySipInvite(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader { bool result = false; bool drop = false; + int udp_act_payload_len = (ntohs(udpHeader->len)-sizeof(UdpHeaderStruct)); + + /* Judgine from the memcmp() below, we need the UDP payload + * length to be at least 3 bytes. -- Gerald */ + if(udp_act_payload_len < 6) + return false; /* Frame too small */ + if (memcmp("INVITE", (void*)udpPayload, 6) == 0) { result = true; @@ -655,21 +1424,66 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char { UdpHeaderStruct* udpHeader = (UdpHeaderStruct*)((char *)ipHeader + ipHeaderLength); - if( ntohs(udpHeader->source) > 1024 && ntohs(udpHeader->dest) > 1024 ) - { + if(ntohs(udpHeader->source) > 1024 && ntohs(udpHeader->dest) > 1024) { + bool detectedUsefulPacket = false; u_char* udpPayload = (u_char *)udpHeader + sizeof(UdpHeaderStruct); - MutexSentinel mutexSentinel(s_mutex); // serialize access for competing pcap threads + MutexSentinel mutexSentinel(s_mutex); // serialize access for competing pcap threads + + detectedUsefulPacket = TryIax2New(ethernetHeader, ipHeader, udpHeader, udpPayload); + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2Accept(ethernetHeader, ipHeader, udpHeader, + udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2Authreq(ethernetHeader, ipHeader, udpHeader, + udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2Hangup(ethernetHeader, ipHeader, udpHeader, + udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2ControlHangup(ethernetHeader, ipHeader, udpHeader, + udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2Reject(ethernetHeader, ipHeader, udpHeader, + udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2FullVoiceFrame(ethernetHeader, ipHeader, + udpHeader, udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2MetaTrunkFrame(ethernetHeader, ipHeader, + udpHeader, udpPayload); + } + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryIax2MiniVoiceFrame(ethernetHeader, ipHeader, + udpHeader, udpPayload); + } - bool detectedUsefulPacket = TryRtp(ethernetHeader, ipHeader, udpHeader, udpPayload); + if(!detectedUsefulPacket) { + detectedUsefulPacket = TryRtp(ethernetHeader, ipHeader, udpHeader, udpPayload); + } - if(!detectedUsefulPacket) - { - detectedUsefulPacket= TrySipInvite(ethernetHeader, ipHeader, udpHeader, udpPayload); + if(!detectedUsefulPacket) { + detectedUsefulPacket= TrySipInvite(ethernetHeader, ipHeader, udpHeader, + udpPayload); } - if(!detectedUsefulPacket) - { - detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, udpPayload); + + if(!detectedUsefulPacket) { + detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, + udpPayload); } } } @@ -711,6 +1525,7 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char MutexSentinel mutexSentinel(s_mutex); // serialize access for competing pcap threads s_lastHooveringTime = now; RtpSessionsSingleton::instance()->Hoover(now); + Iax2SessionsSingleton::instance()->Hoover(now); } } diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.dsp b/orkaudio/audiocaptureplugins/voip/VoIp.dsp index cc39490..655dde1 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.dsp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.dsp @@ -124,6 +124,14 @@ SOURCE=.\Rtp.h # End Source File # Begin Source File +SOURCE=.\Iax2Session.cpp +# End Source File +# Begin Source File + +SOURCE=.\Iax2Session.h +# End Source File +# Begin Source File + SOURCE=.\RtpSession.cpp # End Source File # Begin Source File |