* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/85/852083bc1133fbdcdea60a1875ed81ffb295b2ef.svn-base b/jni/pjproject-android/.svn/pristine/85/852083bc1133fbdcdea60a1875ed81ffb295b2ef.svn-base
new file mode 100644
index 0000000..2cf6990
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/852083bc1133fbdcdea60a1875ed81ffb295b2ef.svn-base
@@ -0,0 +1,352 @@
+ 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) YYYY 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/jni/pjproject-android/.svn/pristine/85/8527272f6157c7caf3203468844db62dbbfc16b9.svn-base b/jni/pjproject-android/.svn/pristine/85/8527272f6157c7caf3203468844db62dbbfc16b9.svn-base
new file mode 100644
index 0000000..9b4861c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/8527272f6157c7caf3203468844db62dbbfc16b9.svn-base
@@ -0,0 +1,178 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+ @file fixed_arm5e.h
+ @brief ARM-tuned fixed-point operations
+*/
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_ARM5E_H
+#define FIXED_ARM5E_H
+
+#undef MULT16_16
+static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
+ int res;
+ asm ("smulbb %0,%1,%2;\n"
+ : "=&r"(res)
+ : "%r"(x),"r"(y));
+ return(res);
+}
+
+#undef MAC16_16
+static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+ int res;
+ asm ("smlabb %0,%1,%2,%3;\n"
+ : "=&r"(res)
+ : "%r"(x),"r"(y),"r"(a));
+ return(res);
+}
+
+#undef MULT16_32_Q15
+static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
+ int res;
+ asm ("smulwb %0,%1,%2;\n"
+ : "=&r"(res)
+ : "%r"(y<<1),"r"(x));
+ return(res);
+}
+
+#undef MAC16_32_Q15
+static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+ int res;
+ asm ("smlawb %0,%1,%2,%3;\n"
+ : "=&r"(res)
+ : "%r"(y<<1),"r"(x),"r"(a));
+ return(res);
+}
+
+#undef MULT16_32_Q11
+static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
+ int res;
+ asm ("smulwb %0,%1,%2;\n"
+ : "=&r"(res)
+ : "%r"(y<<5),"r"(x));
+ return(res);
+}
+
+#undef MAC16_32_Q11
+static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+ int res;
+ asm ("smlawb %0,%1,%2,%3;\n"
+ : "=&r"(res)
+ : "%r"(y<<5),"r"(x),"r"(a));
+ return(res);
+}
+
+#undef DIV32_16
+static inline short DIV32_16(int a, int b)
+{
+ int res=0;
+ int dead1, dead2, dead3, dead4, dead5;
+ __asm__ __volatile__ (
+ "\teor %5, %0, %1\n"
+ "\tmovs %4, %0\n"
+ "\trsbmi %0, %0, #0 \n"
+ "\tmovs %4, %1\n"
+ "\trsbmi %1, %1, #0 \n"
+ "\tmov %4, #1\n"
+
+ "\tsubs %3, %0, %1, asl #14 \n"
+ "\torrpl %2, %2, %4, asl #14 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #13 \n"
+ "\torrpl %2, %2, %4, asl #13 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #12 \n"
+ "\torrpl %2, %2, %4, asl #12 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #11 \n"
+ "\torrpl %2, %2, %4, asl #11 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #10 \n"
+ "\torrpl %2, %2, %4, asl #10 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #9 \n"
+ "\torrpl %2, %2, %4, asl #9 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #8 \n"
+ "\torrpl %2, %2, %4, asl #8 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #7 \n"
+ "\torrpl %2, %2, %4, asl #7 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #6 \n"
+ "\torrpl %2, %2, %4, asl #6 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #5 \n"
+ "\torrpl %2, %2, %4, asl #5 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #4 \n"
+ "\torrpl %2, %2, %4, asl #4 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #3 \n"
+ "\torrpl %2, %2, %4, asl #3 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #2 \n"
+ "\torrpl %2, %2, %4, asl #2 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1, asl #1 \n"
+ "\torrpl %2, %2, %4, asl #1 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tsubs %3, %0, %1 \n"
+ "\torrpl %2, %2, %4 \n"
+ "\tmovpl %0, %3 \n"
+
+ "\tmovs %5, %5, lsr #31 \n"
+ "\trsbne %2, %2, #0 \n"
+ : "=r" (dead1), "=r" (dead2), "=r" (res),
+ "=r" (dead3), "=r" (dead4), "=r" (dead5)
+ : "0" (a), "1" (b), "2" (res)
+ : "memory", "cc"
+ );
+ return res;
+}
+
+
+
+
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/85/8557a1aae9f2adb90e4fc84f07cb735fadf5b5e2.svn-base b/jni/pjproject-android/.svn/pristine/85/8557a1aae9f2adb90e4fc84f07cb735fadf5b5e2.svn-base
new file mode 100644
index 0000000..6299f4e
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/8557a1aae9f2adb90e4fc84f07cb735fadf5b5e2.svn-base
@@ -0,0 +1,31 @@
+# $Id$
+import inc_sip as sip
+import inc_sdp as sdp
+
+# Answer for codec AMR should not contain fmtp octet-align=1
+
+sdp = \
+"""
+v=0
+o=- 3428650655 3428650655 IN IP4 192.168.1.9
+s=pjmedia
+c=IN IP4 192.168.1.9
+t=0 0
+a=X-nat:0
+m=audio 4000 RTP/AVP 99 101
+a=rtcp:4001 IN IP4 192.168.1.9
+a=rtpmap:99 AMR/8000
+a=sendrecv
+a=rtpmap:101 telephone-event/8000
+a=fmtp:101 0-15
+"""
+
+pjsua_args = "--null-audio --auto-answer 200 --add-codec AMR"
+extra_headers = ""
+include = [""]
+exclude = ["octet-align=1"] # response must not include fmtp 'octet-align=1'
+
+sendto_cfg = sip.SendtoCfg("AMR negotiation should not contain 'octet-align=1'", pjsua_args, sdp, 200,
+ extra_headers=extra_headers,
+ resp_inc=include, resp_exc=exclude)
+
diff --git a/jni/pjproject-android/.svn/pristine/85/8563b8215db50bb7316ff04e095fc45b36d8eead.svn-base b/jni/pjproject-android/.svn/pristine/85/8563b8215db50bb7316ff04e095fc45b36d8eead.svn-base
new file mode 100644
index 0000000..1171a56
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/8563b8215db50bb7316ff04e095fc45b36d8eead.svn-base
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- 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 -->
+<!-- -->
+<!-- NOTIFY with instant termination: -->
+<!-- - UAC sends SUBSCRIBE, we reply with 200 and Expires=0 -->
+<!-- - we send NOTIFY with state=terminated -->
+<!-- -->
+
+<scenario name="NOTIFY with instant termination">
+ <!-- By adding rrs="true" (Record Route Sets), the route sets -->
+ <!-- are saved and used for following messages sent. Useful to test -->
+ <!-- against stateful SIP proxies/B2BUAs. -->
+ <recv request="SUBSCRIBE" crlf="true">
+ <action>
+ <ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+ <ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+ <assign assign_to="4" variable="5" />
+ </action>
+ </recv>
+
+
+ <!-- The '[last_*]' keyword is replaced automatically by the -->
+ <!-- specified header if it was present in the last message received -->
+ <!-- (except if it was a retransmission). If the header was not -->
+ <!-- present or if no message has been received, the '[last_*]' -->
+ <!-- keyword is discarded, and all bytes until the end of the line -->
+ <!-- are also discarded. -->
+ <!-- -->
+ <!-- If the specified header was present several times in the -->
+ <!-- message, all occurences are concatenated (CRLF seperated) -->
+ <!-- to be used in place of the '[last_*]' keyword. -->
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:sipp@[local_ip]:[local_port]>
+ Content-Length: 0
+ Expires: 0
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+ NOTIFY sip:[$5] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=z9hG4bKPj01
+ From: sipp <sip:sipp@[local_ip]>;tag=[call_number]
+ To[$3]
+ Call-ID: [call_id]
+ Cseq: 1 NOTIFY
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Event: presence
+ Subscription-State: terminated;reason=timeout
+ Content-Type: application/pidf+xml
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:op="urn:oma:xml:prs:pidf:oma-pres" entity="sip:moto_red@ptt.intra.genaker.net">
+ <tuple id="17415d5738f332a64a2f1d8cfb4ab0a5">
+ <status>
+ <basic>open</basic>
+ </status>
+ <op:willingness>
+ <op:basic>closed</op:basic>
+ </op:willingness>
+ <op:barring-state>active</op:barring-state>
+ <op:service-description>
+ <op:service-id>org.openmobilealliance:PoC-session</op:service-id>
+ <op:version>1.0</op:version>
+ </op:service-description>
+ </tuple>
+ </presence>
+ ]]>
+ </send>
+
+ <recv response="200">
+ </recv>
+
+ <pause milliseconds="32000"/>
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/jni/pjproject-android/.svn/pristine/85/857ada5193b78d9bcf8a56139a9fa5c9a76fae99.svn-base b/jni/pjproject-android/.svn/pristine/85/857ada5193b78d9bcf8a56139a9fa5c9a76fae99.svn-base
new file mode 100644
index 0000000..5cd1fb5
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/857ada5193b78d9bcf8a56139a9fa5c9a76fae99.svn-base
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+ ADD_PARAM += "--null-audio"
+
+# Call with Speex/8000 codec
+test_param = TestParam(
+ "PESQ codec Speex NB",
+ [
+ InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec speex/8000 --clock-rate 8000 --play-file wavs/input.8.wav --no-vad"),
+ InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec speex/8000 --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
+ ]
+ )
+
+pesq_threshold = 3.65
diff --git a/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base b/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base
new file mode 100644
index 0000000..a17c74c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base
@@ -0,0 +1,822 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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
+ */
+#ifndef __PJMEDIA_SDP_NEG_H__
+#define __PJMEDIA_SDP_NEG_H__
+
+
+/**
+ * @file sdp_neg.h
+ * @brief SDP negotiator header file.
+ */
+/**
+ * @defgroup PJMEDIA_SDP_NEG SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @{
+ *
+ * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration
+ * of SDP offer and answer negotiator. SDP offer and answer model is described
+ * in RFC 3264 <b>"An Offer/Answer Model with Session Description Protocol
+ * (SDP)"</b>.
+ *
+ * The SDP negotiator is represented with opaque type \a pjmedia_sdp_neg.
+ * This structure contains negotiation state and several SDP session
+ * descriptors currently being used in the negotiation.
+ *
+ *
+ * \section sdpneg_state_dia SDP Negotiator State Diagram
+ *
+ * The following diagram describes the state transition diagram of the
+ * SDP negotiator.
+ *
+ * <pre>
+ *
+ * modify_local_offer()
+ * create_w_local_offer() +-------------+ send_local_offer()
+ * ----------------------->| LOCAL_OFFER |<-----------------------
+ * | +-------------+______ |
+ * | | \_____________ |
+ * | set_remote_answer() | cancel_offer() \ |
+ * | V v |
+ * +--+---+ +-----------+ negotiate() +-~----+
+ * | NULL | | WAIT_NEGO |-------------------->| DONE |
+ * +------+ +-----------+ +------+
+ * | A ______________________^ |
+ * | set_local_answer() | / cancel_offer() |
+ * | | / |
+ * | +--------------+ set_remote_offer() |
+ * ----------------------->| REMOTE_OFFER |<----------------------
+ * create_w_remote_offer() +--------------+
+ *
+ * </pre>
+ *
+ *
+ *
+ * \section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator
+ *
+ * \subsection sdpneg_create_offer Creating Initial Offer
+ *
+ * Application creates an offer by manualy building the SDP session descriptor
+ * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to
+ * create SDP session descriptor based on capabilities that present in the
+ * endpoint by calling #pjmedia_endpt_create_sdp().
+ *
+ * Application then creates SDP negotiator instance by calling
+ * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the
+ * function arguments. The SDP negotiator keeps a copy of current local offer,
+ * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER.
+ *
+ * Application can then send the initial SDP offer that it creates to
+ * remote peer using signaling protocol such as SIP.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Generating Subsequent Offer
+ *
+ * The negotiator can only create subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ * If any previous negotiation process was successfull (i.e. the return
+ * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator
+ * keeps both active local and active remote SDP.
+ *
+ * If application does not want send modified offer, it can just send
+ * the active local SDP as the offer. In this case, application calls
+ * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP.
+ *
+ * If application wants to modify it's local offer, it MUST inform
+ * the negotiator about the modified SDP by calling
+ * #pjmedia_sdp_neg_modify_local_offer().
+ *
+ * In both cases, the negotiator will internally create a copy of the offer,
+ * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it
+ * waits until application passes the remote answer.
+ *
+ *
+ * \subsection sdpneg_receive_offer Receiving Initial Offer
+ *
+ * Application receives an offer in the incoming request from remote to
+ * establish multimedia session, such as incoming INVITE message with SDP
+ * body.
+ *
+ * Initially, when the initial offer is received, application creates the
+ * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(),
+ * specifying the remote SDP offer in one of the argument.
+ *
+ * At this stage, application may or may not ready to create an answer.
+ * For example, a SIP B2BUA needs to make outgoing call and receive SDP
+ * from the outgoing call leg in order to create a SDP answer to the
+ * incoming call leg.
+ *
+ * If application is not ready to create an answer, it passes NULL as
+ * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer().
+ *
+ * The section @ref sdpneg_create_answer describes the case when
+ * application is ready to create a SDP answer.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Receiving Subsequent Offer
+ *
+ * Application passes subsequent SDP offer received from remote by
+ * calling #pjmedia_sdp_neg_set_remote_offer().
+ *
+ * The negotiator can only receive subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ *
+ * \subsection sdpneg_recv_answer Receiving SDP Answer
+ *
+ * When application receives SDP answer from remote, it informs the
+ * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The
+ * negotiator validates the answer (#pjmedia_sdp_validate()), and if
+ * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO.
+ *
+ * Application then instruct the negotiator to negotiate the remote
+ * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of
+ * this negotiation is to verify remote answer, and update the initial
+ * offer according to the answer. For example, the initial offer may
+ * specify that a stream is \a sendrecv, while the answer specifies
+ * that remote stream is \a inactive. In this case, the negotiator
+ * will update the stream in the local active media as \a inactive
+ * too.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the updated local answer and remote answer internally. These two
+ * SDPs are called active local SDP and active remote SDP, as it describes
+ * currently active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling
+ * #pjmedia_sdp_neg_get_active_remote().
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ * \subsection sdpneg_cancel_offer Cancelling an Offer
+ *
+ * In other case, after an offer is generated (negotiator state is in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and
+ * application wants the negotiator to reset itself to its previous state.
+ * Consider this example:
+ *
+ * - media has been established, and negotiator state is
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ * - application generates a new offer for re-INVITE, so in this case
+ * it would either call #pjmedia_sdp_neg_send_local_offer() or
+ * #pjmedia_sdp_neg_modify_local_offer()
+ * - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * - the re-INVITE was rejected with an error
+ *
+ * Since an answer is not received, it is necessary to reset the negotiator
+ * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can
+ * create or receive new offer.
+ *
+ * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(),
+ * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In
+ * this case, both active local and active remote will not be modified.
+ *
+ * \subsection sdpneg_create_answer Generating SDP Answer
+ *
+ * After remote offer has been set in the negotiator, application can
+ * request the SDP negotiator to generate appropriate answer based on local
+ * capability.
+ *
+ * To do this, first the application MUST have an SDP describing its local
+ * capabilities. This SDP can be built manually, or application can generate
+ * SDP to describe local media endpoint capability by calling
+ * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA,
+ * application can treat the SDP received from the outgoing call leg as if
+ * it was it's local capability.
+ *
+ * The local SDP session descriptor DOES NOT have to match the SDP offer.
+ * For example, it can have more or less media lines than the offer, or
+ * their order may be different than the offer. The negotiator is capable
+ * to match and reorder local SDP according to remote offer, and create
+ * an answer that is suitable for the offer.
+ *
+ * After local SDP capability has been acquired, application can create
+ * a SDP answer.
+ *
+ * If application does not already have the negotiator instance, it creates
+ * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying
+ * both remote SDP offer and local SDP as the arguments. The SDP negotiator
+ * validates both remote and local SDP by calling #pjmedia_sdp_validate(),
+ * and if both SDPs are valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * If application already has the negotiator instance, it sets the local
+ * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer().
+ * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ),
+ * and if it is valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+ * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP
+ * negotiator to negotiate both offer and answer. This function returns
+ * PJ_SUCCESS if an answer can be generated AND at least one media stream
+ * is active in the session.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the remote offer and local answer internally. These two SDPs are
+ * called active local SDP and active remote SDP, as it describes currently
+ * active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the
+ * SDP answer.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ */
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This enumeration describes SDP negotiation state.
+ */
+enum pjmedia_sdp_neg_state
+{
+ /**
+ * This is the state of SDP negoator before it is initialized.
+ */
+ PJMEDIA_SDP_NEG_STATE_NULL,
+
+ /**
+ * This state occurs when SDP negotiator has sent our offer to remote and
+ * it is waiting for answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+
+ /**
+ * This state occurs when SDP negotiator has received offer from remote
+ * and currently waiting for local answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,
+
+ /**
+ * This state occurs when an offer (either local or remote) has been
+ * provided with answer. The SDP negotiator is ready to negotiate both
+ * session descriptors. Application can call #pjmedia_sdp_neg_negotiate()
+ * immediately to begin negotiation process.
+ */
+ PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+
+ /**
+ * This state occurs when SDP negotiation has completed, either
+ * successfully or not.
+ */
+ PJMEDIA_SDP_NEG_STATE_DONE
+};
+
+
+/**
+ * @see pjmedia_sdp_neg_state
+ */
+typedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state;
+
+
+/**
+ * Opaque declaration of SDP negotiator.
+ */
+typedef struct pjmedia_sdp_neg pjmedia_sdp_neg;
+
+
+/**
+ * Flags to be given to pjmedia_sdp_neg_modify_local_offer2().
+ */
+typedef enum pjmedia_mod_offer_flag
+{
+ /**
+ * Allow media type in the SDP to be changed.
+ * When generating a new offer, in the case that a media line doesn't match
+ * the active SDP, the new media line will be considered to replace the
+ * existing media at the same position.
+ */
+ PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE = 1
+
+} pjmedia_mod_offer_flag;
+
+
+/**
+ * Get the state string description of the specified state.
+ *
+ * @param state Negotiator state.
+ *
+ * @return String description of the state.
+ */
+PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state);
+
+
+/**
+ * Create the SDP negotiator with local offer. The SDP negotiator then
+ * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits
+ * until it receives answer from remote. When SDP answer from remote is
+ * received, application must call #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * After calling this function, application should send the local SDP offer
+ * to remote party using signaling protocol such as SIP and wait for SDP
+ * answer.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param local The initial local capability.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,
+ const pjmedia_sdp_session *local,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * Initialize the SDP negotiator with remote offer, and optionally
+ * specify the initial local capability, if known. Application normally
+ * calls this function when it receives initial offer from remote.
+ *
+ * If local media capability is specified, this capability will be set as
+ * initial local capability of the negotiator, and after this function is
+ * called, the SDP negotiator state will move to state
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and the negotiation function can be
+ * called.
+ *
+ * If local SDP is not specified, the negotiator will not have initial local
+ * capability, and after this function is called the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER state. Application MUST supply
+ * local answer later with #pjmedia_sdp_neg_set_local_answer(), before
+ * calling the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param initial Optional initial local capability.
+ * @param remote The remote offer.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
+ const pjmedia_sdp_session *initial,
+ const pjmedia_sdp_session *remote,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will
+ * be used.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param prefer_remote If non-zero, the negotiator will use the codec
+ * order as specified in remote offer. If zero, it
+ * will prefer to use the local codec order.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
+ pj_bool_t prefer_remote);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should answer with multiple formats or not.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS will
+ * be used.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param answer_multiple
+ * If non-zero, the negotiator will respond with
+ * multiple formats. If zero only a single format
+ * will be returned.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_answer_multiple_codecs(pjmedia_sdp_neg *neg,
+ pj_bool_t answer_multiple);
+
+
+/**
+ * Get SDP negotiator state.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return The negotiator state.
+ */
+PJ_DECL(pjmedia_sdp_neg_state)
+pjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg );
+
+/**
+ * Get the currently active local SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the local active SDP.
+ *
+ * @return PJ_SUCCESS if local active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Get the currently active remote SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the remote active SDP.
+ *
+ * @return PJ_SUCCESS if remote active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Determine whether remote sent answer (as opposed to offer) on the
+ * last negotiation. This function can only be called in state
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return Non-zero if it was remote who sent answer,
+ * otherwise zero if it was local who supplied
+ * answer.
+ */
+PJ_DECL(pj_bool_t)
+pjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Get the current remote SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be remote
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the current remote offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * remote offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Get the current local SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be local
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the current local offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * local offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer.
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote. See also
+ * #pjmedia_sdp_neg_modify_local_offer2()
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local The new local SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer.
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param flags Bitmask from pjmedia_mod_offer_flag.
+ * @param local The new local SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_modify_local_offer2( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ unsigned flags,
+ const pjmedia_sdp_session *local);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function to retrieve currently active
+ * local SDP, and then send the SDP to remote as an offer. The negotiator
+ * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits
+ * for SDP answer from remote.
+ *
+ * When SDP answer has been received from remote, application must call
+ * #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param offer Pointer to receive active local SDP to be
+ * offered to remote.
+ *
+ * @return PJ_SUCCESS if local offer can be created.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **offer);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_send_local_offer()
+ * function. Application calls this function when it receives SDP answer
+ * from remote. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote answer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function when it receives SDP offer from remote.
+ * After this function is called, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, and application MUST call the
+ * #pjmedia_sdp_neg_set_local_answer() to set local answer before it can
+ * call the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote offer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_set_remote_offer()
+ * function. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local Optional local answer. If negotiator has initial
+ * local capability, application can specify NULL on
+ * this argument; in this case, the negotiator will
+ * create answer by by negotiating remote offer with
+ * initial local capability. If negotiator doesn't have
+ * initial local capability, application MUST specify
+ * local answer here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+
+/**
+ * Call this function when the negotiator is in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO
+ * state to see if it was local who is answering the offer (instead of
+ * remote).
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_TRUE if it is local is answering an offer, PJ_FALSE
+ * if remote has answered local offer.
+ */
+PJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Cancel any pending offer, whether the offer is initiated by local or
+ * remote, and move negotiator state back to previous stable state
+ * (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator must be in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state.
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Negotiate local and remote answer. Before calling this function, the
+ * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state.
+ * After calling this function, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has
+ * been successfull or not.
+ *
+ * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS),
+ * the active local and remote SDP will be replaced with the new SDP
+ * from the negotiation process.
+ *
+ * If the negotiation fails, the active local and remote SDP will not
+ * change.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param allow_asym Should be zero.
+ *
+ * @return PJ_SUCCESS when there is at least one media
+ * is actuve common in both offer and answer, or
+ * failure code when negotiation has failed.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ pj_bool_t allow_asym);
+
+
+/**
+ * Enumeration of customized SDP format matching option flags. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ */
+typedef enum pjmedia_sdp_neg_fmt_match_flag
+{
+ /**
+ * In generating answer, the SDP fmtp in the answer candidate may need
+ * to be modified by the customized SDP format matching callback to
+ * achieve flexible SDP negotiation, e.g: AMR fmtp 'octet-align' field
+ * can be adjusted with the offer when the codec implementation support
+ * both packetization modes octet-aligned and bandwidth-efficient.
+ */
+ PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1,
+
+} pjmedia_sdp_neg_fmt_match_flag;
+
+
+/**
+ * The declaration of customized SDP format matching callback. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+typedef pj_status_t (*pjmedia_sdp_neg_fmt_match_cb)(pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+/**
+ * Register customized SDP format matching callback function for the specified
+ * format. The customized SDP format matching is needed when the format
+ * identification in a media stream session cannot be simply determined by
+ * encoding name and clock rate, but also involves one or more format specific
+ * parameters, which are specified in SDP fmtp attribute. For example,
+ * an H.264 video stream is also identified by profile, level, and
+ * packetization-mode parameters. As those parameters are format specifics,
+ * the negotiation must be done by the format or codec implementation.
+ *
+ * To unregister the callback of specific format, just call this function with
+ * parameter #cb set to NULL.
+ *
+ * @param fmt_name The format name, e.g: "H.264", "AMR", "G7221". Note
+ * that the string buffer must remain valid until the
+ * callback is unregistered.
+ * @param cb The customized SDP format negotiation callback or
+ * NULL to unregister the specified format callback.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_neg_fmt_match_cb cb);
+
+
+/**
+ * Match format in the SDP media offer and answer. The matching mechanism
+ * will be done by comparing the encoding name and clock rate, and if the
+ * custom format matching callback for the specified format is registered,
+ * see #pjmedia_sdp_neg_register_fmt_match_cb(), it will be called for more
+ * detail verification, e.g: format parameters specified in SDP fmtp.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_SDP_NEG_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/85/859ce870c7a3476f942cc8c1e8b9edcb032b98ed.svn-base b/jni/pjproject-android/.svn/pristine/85/859ce870c7a3476f942cc8c1e8b9edcb032b98ed.svn-base
new file mode 100644
index 0000000..12d1c8c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/859ce870c7a3476f942cc8c1e8b9edcb032b98ed.svn-base
@@ -0,0 +1,1491 @@
+/*
+ * srtp_driver.c
+ *
+ * a test driver for libSRTP
+ *
+ * David A. McGrew
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <string.h> /* for memcpy() */
+#include <time.h> /* for clock() */
+#include <stdlib.h> /* for malloc(), free() */
+#include <stdio.h> /* for print(), fflush() */
+#include "getopt_s.h" /* for local getopt() */
+
+#include "srtp_priv.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#elif defined HAVE_WINSOCK2_H
+# include <winsock2.h>
+#endif
+
+#define PRINT_REFERENCE_PACKET 1
+
+err_status_t
+srtp_validate(void);
+
+err_status_t
+srtp_create_big_policy(srtp_policy_t **list);
+
+err_status_t
+srtp_test_remove_stream(void);
+
+double
+srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
+
+double
+srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
+
+void
+srtp_do_timing(const srtp_policy_t *policy);
+
+void
+srtp_do_rejection_timing(const srtp_policy_t *policy);
+
+err_status_t
+srtp_test(const srtp_policy_t *policy);
+
+err_status_t
+srtcp_test(const srtp_policy_t *policy);
+
+err_status_t
+srtp_session_print_policy(srtp_t srtp);
+
+err_status_t
+srtp_print_policy(const srtp_policy_t *policy);
+
+char *
+srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
+
+double
+mips_estimate(int num_trials, int *ignore);
+
+extern uint8_t test_key[30];
+
+void
+usage(char *prog_name) {
+ printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
+ " -t run timing test\n"
+ " -r run rejection timing test\n"
+ " -c run codec timing test\n"
+ " -v run validation tests\n"
+ " -d <mod> turn on debugging module <mod>\n"
+ " -l list debugging modules\n", prog_name);
+ exit(1);
+}
+
+/*
+ * The policy_array is a null-terminated array of policy structs. it
+ * is declared at the end of this file
+ */
+
+extern const srtp_policy_t *policy_array[];
+
+
+/* the wildcard_policy is declared below; it has a wildcard ssrc */
+
+extern const srtp_policy_t wildcard_policy;
+
+/*
+ * mod_driver debug module - debugging module for this test driver
+ *
+ * we use the crypto_kernel debugging system in this driver, which
+ * makes the interface uniform and increases portability
+ */
+
+debug_module_t mod_driver = {
+ 0, /* debugging is off by default */
+ "driver" /* printable name for module */
+};
+
+int
+main (int argc, char *argv[]) {
+ char q;
+ unsigned do_timing_test = 0;
+ unsigned do_rejection_test = 0;
+ unsigned do_codec_timing = 0;
+ unsigned do_validation = 0;
+ unsigned do_list_mods = 0;
+ err_status_t status;
+
+ /*
+ * verify that the compiler has interpreted the header data
+ * structure srtp_hdr_t correctly
+ */
+ if (sizeof(srtp_hdr_t) != 12) {
+ printf("error: srtp_hdr_t has incorrect size"
+ "(size is %ld bytes, expected 12)\n",
+ sizeof(srtp_hdr_t));
+ exit(1);
+ }
+
+ /* initialize srtp library */
+ status = srtp_init();
+ if (status) {
+ printf("error: srtp init failed with error code %d\n", status);
+ exit(1);
+ }
+
+ /* load srtp_driver debug module */
+ status = crypto_kernel_load_debug_module(&mod_driver);
+ if (status) {
+ printf("error: load of srtp_driver debug module failed "
+ "with error code %d\n", status);
+ exit(1);
+ }
+
+ /* process input arguments */
+ while (1) {
+ q = getopt_s(argc, argv, "trcvld:");
+ if (q == -1)
+ break;
+ switch (q) {
+ case 't':
+ do_timing_test = 1;
+ break;
+ case 'r':
+ do_rejection_test = 1;
+ break;
+ case 'c':
+ do_codec_timing = 1;
+ break;
+ case 'v':
+ do_validation = 1;
+ break;
+ case 'l':
+ do_list_mods = 1;
+ break;
+ case 'd':
+ status = crypto_kernel_set_debug_module(optarg_s, 1);
+ if (status) {
+ printf("error: set debug module (%s) failed\n", optarg_s);
+ exit(1);
+ }
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ if (!do_validation && !do_timing_test && !do_codec_timing
+ && !do_list_mods && !do_rejection_test)
+ usage(argv[0]);
+
+ if (do_list_mods) {
+ status = crypto_kernel_list_debug_modules();
+ if (status) {
+ printf("error: list of debug modules failed\n");
+ exit(1);
+ }
+ }
+
+ if (do_validation) {
+ const srtp_policy_t **policy = policy_array;
+ srtp_policy_t *big_policy;
+
+ /* loop over policy array, testing srtp and srtcp for each policy */
+ while (*policy != NULL) {
+ printf("testing srtp_protect and srtp_unprotect\n");
+ if (srtp_test(*policy) == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+ printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
+ if (srtcp_test(*policy) == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+ policy++;
+ }
+
+ /* create a big policy list and run tests on it */
+ status = srtp_create_big_policy(&big_policy);
+ if (status) {
+ printf("unexpected failure with error code %d\n", status);
+ exit(1);
+ }
+ printf("testing srtp_protect and srtp_unprotect with big policy\n");
+ if (srtp_test(big_policy) == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+
+ /* run test on wildcard policy */
+ printf("testing srtp_protect and srtp_unprotect on "
+ "wildcard ssrc policy\n");
+ if (srtp_test(&wildcard_policy) == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+
+ /*
+ * run validation test against the reference packets - note
+ * that this test only covers the default policy
+ */
+ printf("testing srtp_protect and srtp_unprotect against "
+ "reference packets\n");
+ if (srtp_validate() == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+
+ /*
+ * test the function srtp_remove_stream()
+ */
+ printf("testing srtp_remove_stream()...");
+ if (srtp_test_remove_stream() == err_status_ok)
+ printf("passed\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+ }
+
+ if (do_timing_test) {
+ const srtp_policy_t **policy = policy_array;
+
+ /* loop over policies, run timing test for each */
+ while (*policy != NULL) {
+ srtp_print_policy(*policy);
+ srtp_do_timing(*policy);
+ policy++;
+ }
+ }
+
+ if (do_rejection_test) {
+ const srtp_policy_t **policy = policy_array;
+
+ /* loop over policies, run rejection timing test for each */
+ while (*policy != NULL) {
+ srtp_print_policy(*policy);
+ srtp_do_rejection_timing(*policy);
+ policy++;
+ }
+ }
+
+ if (do_codec_timing) {
+ srtp_policy_t policy;
+ int ignore;
+ double mips = mips_estimate(1000000000, &ignore);
+
+ crypto_policy_set_rtp_default(&policy.rtp);
+ crypto_policy_set_rtcp_default(&policy.rtcp);
+ policy.ssrc.type = ssrc_specific;
+ policy.ssrc.value = 0xdecafbad;
+ policy.key = test_key;
+ policy.next = NULL;
+
+ printf("mips estimate: %e\n", mips);
+
+ printf("testing srtp processing time for voice codecs:\n");
+ printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
+ printf("G.711\t\t%d\t\t\t%e\n", 80,
+ (double) mips * (80 * 8) /
+ srtp_bits_per_second(80, &policy) / .01 );
+ printf("G.711\t\t%d\t\t\t%e\n", 160,
+ (double) mips * (160 * 8) /
+ srtp_bits_per_second(160, &policy) / .02);
+ printf("G.726-32\t%d\t\t\t%e\n", 40,
+ (double) mips * (40 * 8) /
+ srtp_bits_per_second(40, &policy) / .01 );
+ printf("G.726-32\t%d\t\t\t%e\n", 80,
+ (double) mips * (80 * 8) /
+ srtp_bits_per_second(80, &policy) / .02);
+ printf("G.729\t\t%d\t\t\t%e\n", 10,
+ (double) mips * (10 * 8) /
+ srtp_bits_per_second(10, &policy) / .01 );
+ printf("G.729\t\t%d\t\t\t%e\n", 20,
+ (double) mips * (20 * 8) /
+ srtp_bits_per_second(20, &policy) / .02 );
+ printf("Wideband\t%d\t\t\t%e\n", 320,
+ (double) mips * (320 * 8) /
+ srtp_bits_per_second(320, &policy) / .01 );
+ printf("Wideband\t%d\t\t\t%e\n", 640,
+ (double) mips * (640 * 8) /
+ srtp_bits_per_second(640, &policy) / .02 );
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * srtp_create_test_packet(len, ssrc) returns a pointer to a
+ * (malloced) example RTP packet whose data field has the length given
+ * by pkt_octet_len and the SSRC value ssrc. The total length of the
+ * packet is twelve octets longer, since the header is at the
+ * beginning. There is room at the end of the packet for a trailer,
+ * and the four octets following the packet are filled with 0xff
+ * values to enable testing for overwrites.
+ *
+ * note that the location of the test packet can (and should) be
+ * deallocated with the free() call once it is no longer needed.
+ */
+
+srtp_hdr_t *
+srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
+ int i;
+ uint8_t *buffer;
+ srtp_hdr_t *hdr;
+ int bytes_in_hdr = 12;
+
+ /* allocate memory for test packet */
+ hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
+ + SRTP_MAX_TRAILER_LEN + 4);
+ if (!hdr)
+ return NULL;
+
+ hdr->version = 2; /* RTP version two */
+ hdr->p = 0; /* no padding needed */
+ hdr->x = 0; /* no header extension */
+ hdr->cc = 0; /* no CSRCs */
+ hdr->m = 0; /* marker bit */
+ hdr->pt = 0xf; /* payload type */
+ hdr->seq = htons(0x1234); /* sequence number */
+ hdr->ts = htonl(0xdecafbad); /* timestamp */
+ hdr->ssrc = htonl(ssrc); /* synch. source */
+
+ buffer = (uint8_t *)hdr;
+ buffer += bytes_in_hdr;
+
+ /* set RTP data to 0xab */
+ for (i=0; i < pkt_octet_len; i++)
+ *buffer++ = 0xab;
+
+ /* set post-data value to 0xffff to enable overrun checking */
+ for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
+ *buffer++ = 0xff;
+
+ return hdr;
+}
+
+void
+srtp_do_timing(const srtp_policy_t *policy) {
+ int len;
+
+ /*
+ * note: the output of this function is formatted so that it
+ * can be used in gnuplot. '#' indicates a comment, and "\r\n"
+ * terminates a record
+ */
+
+ printf("# testing srtp throughput:\r\n");
+ printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
+
+ for (len=16; len <= 2048; len *= 2)
+ printf("%d\t\t\t%f\r\n", len,
+ srtp_bits_per_second(len, policy) / 1.0E6);
+
+ /* these extra linefeeds let gnuplot know that a dataset is done */
+ printf("\r\n\r\n");
+
+}
+
+void
+srtp_do_rejection_timing(const srtp_policy_t *policy) {
+ int len;
+
+ /*
+ * note: the output of this function is formatted so that it
+ * can be used in gnuplot. '#' indicates a comment, and "\r\n"
+ * terminates a record
+ */
+
+ printf("# testing srtp rejection throughput:\r\n");
+ printf("# mesg length (octets)\trejections per second\r\n");
+
+ for (len=8; len <= 2048; len *= 2)
+ printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
+
+ /* these extra linefeeds let gnuplot know that a dataset is done */
+ printf("\r\n\r\n");
+
+}
+
+
+#define MAX_MSG_LEN 1024
+
+double
+srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
+ srtp_t srtp;
+ srtp_hdr_t *mesg;
+ int i;
+ clock_t timer;
+ int num_trials = 100000;
+ int len;
+ uint32_t ssrc;
+ err_status_t status;
+
+ /*
+ * allocate and initialize an srtp session
+ */
+ status = srtp_create(&srtp, policy);
+ if (status) {
+ printf("error: srtp_create() failed with error code %d\n", status);
+ exit(1);
+ }
+
+ /*
+ * if the ssrc is unspecified, use a predetermined one
+ */
+ if (policy->ssrc.type != ssrc_specific) {
+ ssrc = 0xdeadbeef;
+ } else {
+ ssrc = policy->ssrc.value;
+ }
+
+ /*
+ * create a test packet
+ */
+ mesg = srtp_create_test_packet(msg_len_octets, ssrc);
+ if (mesg == NULL)
+ return 0.0; /* indicate failure by returning zero */
+
+ timer = clock();
+ for (i=0; i < num_trials; i++) {
+ err_status_t status;
+ len = msg_len_octets + 12; /* add in rtp header length */
+
+ /* srtp protect message */
+ status = srtp_protect(srtp, mesg, &len);
+ if (status) {
+ printf("error: srtp_protect() failed with error code %d\n", status);
+ exit(1);
+ }
+
+ /* increment message number */
+ mesg->seq = htons(ntohs(mesg->seq) + 1);
+
+ }
+ timer = clock() - timer;
+
+ free(mesg);
+
+ return (double) (msg_len_octets) * 8 *
+ num_trials * CLOCKS_PER_SEC / timer;
+}
+
+double
+srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
+ srtp_ctx_t *srtp;
+ srtp_hdr_t *mesg;
+ int i;
+ int len;
+ clock_t timer;
+ int num_trials = 1000000;
+ uint32_t ssrc = policy->ssrc.value;
+ err_status_t status;
+
+ /*
+ * allocate and initialize an srtp session
+ */
+ status = srtp_create(&srtp, policy);
+ if (status) {
+ printf("error: srtp_create() failed with error code %d\n", status);
+ exit(1);
+ }
+
+ mesg = srtp_create_test_packet(msg_len_octets, ssrc);
+ if (mesg == NULL)
+ return 0.0; /* indicate failure by returning zero */
+
+ len = msg_len_octets;
+ srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
+
+ timer = clock();
+ for (i=0; i < num_trials; i++) {
+ len = msg_len_octets;
+ srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
+ }
+ timer = clock() - timer;
+
+ free(mesg);
+
+ return (double) num_trials * CLOCKS_PER_SEC / timer;
+}
+
+
+void
+err_check(err_status_t s) {
+ if (s == err_status_ok)
+ return;
+ else
+ fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
+ exit (1);
+}
+
+err_status_t
+srtp_test(const srtp_policy_t *policy) {
+ int i;
+ srtp_t srtp_sender;
+ srtp_t srtp_rcvr;
+ err_status_t status = err_status_ok;
+ srtp_hdr_t *hdr, *hdr2;
+ uint8_t hdr_enc[64];
+ uint8_t *pkt_end;
+ int msg_len_octets, msg_len_enc;
+ int len;
+ int tag_length = policy->rtp.auth_tag_len;
+ uint32_t ssrc;
+ srtp_policy_t *rcvr_policy;
+
+ err_check(srtp_create(&srtp_sender, policy));
+
+ /* print out policy */
+ err_check(srtp_session_print_policy(srtp_sender));
+
+ /*
+ * initialize data buffer, using the ssrc in the policy unless that
+ * value is a wildcard, in which case we'll just use an arbitrary
+ * one
+ */
+ if (policy->ssrc.type != ssrc_specific)
+ ssrc = 0xdecafbad;
+ else
+ ssrc = policy->ssrc.value;
+ msg_len_octets = 28;
+ hdr = srtp_create_test_packet(msg_len_octets, ssrc);
+
+ if (hdr == NULL)
+ return err_status_alloc_fail;
+ hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
+ if (hdr2 == NULL) {
+ free(hdr);
+ return err_status_alloc_fail;
+ }
+
+ /* set message length */
+ len = msg_len_octets;
+
+ debug_print(mod_driver, "before protection:\n%s",
+ srtp_packet_to_string(hdr, len));
+
+#if PRINT_REFERENCE_PACKET
+ debug_print(mod_driver, "reference packet before protection:\n%s",
+ octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+ err_check(srtp_protect(srtp_sender, hdr, &len));
+
+ debug_print(mod_driver, "after protection:\n%s",
+ srtp_packet_to_string(hdr, len));
+#if PRINT_REFERENCE_PACKET
+ debug_print(mod_driver, "after protection:\n%s",
+ octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+
+ /* save protected message and length */
+ memcpy(hdr_enc, hdr, len);
+ msg_len_enc = len;
+
+ /*
+ * check for overrun of the srtp_protect() function
+ *
+ * The packet is followed by a value of 0xfffff; if the value of the
+ * data following the packet is different, then we know that the
+ * protect function is overwriting the end of the packet.
+ */
+ pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
+ + msg_len_octets + tag_length;
+ for (i = 0; i < 4; i++)
+ if (pkt_end[i] != 0xff) {
+ fprintf(stdout, "overwrite in srtp_protect() function "
+ "(expected %x, found %x in trailing octet %d)\n",
+ 0xff, ((uint8_t *)hdr)[i], i);
+ free(hdr);
+ free(hdr2);
+ return err_status_algo_fail;
+ }
+
+ /*
+ * if the policy includes confidentiality, check that ciphertext is
+ * different than plaintext
+ *
+ * Note that this check will give false negatives, with some small
+ * probability, especially if the packets are short. For that
+ * reason, we skip this check if the plaintext is less than four
+ * octets long.
+ */
+ if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
+ printf("testing that ciphertext is distinct from plaintext...");
+ status = err_status_algo_fail;
+ for (i=12; i < msg_len_octets+12; i++)
+ if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+ status = err_status_ok;
+ }
+ if (status) {
+ printf("failed\n");
+ free(hdr);
+ free(hdr2);
+ return status;
+ }
+ printf("passed\n");
+ }
+
+ /*
+ * if the policy uses a 'wildcard' ssrc, then we need to make a copy
+ * of the policy that changes the direction to inbound
+ *
+ * we always copy the policy into the rcvr_policy, since otherwise
+ * the compiler would fret about the constness of the policy
+ */
+ rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
+ if (rcvr_policy == NULL)
+ return err_status_alloc_fail;
+ memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
+ if (policy->ssrc.type == ssrc_any_outbound) {
+ rcvr_policy->ssrc.type = ssrc_any_inbound;
+ }
+
+ err_check(srtp_create(&srtp_rcvr, rcvr_policy));
+
+ err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
+
+ debug_print(mod_driver, "after unprotection:\n%s",
+ srtp_packet_to_string(hdr, len));
+
+ /* verify that the unprotected packet matches the origial one */
+ for (i=0; i < msg_len_octets; i++)
+ if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+ fprintf(stdout, "mismatch at octet %d\n", i);
+ status = err_status_algo_fail;
+ }
+ if (status) {
+ free(hdr);
+ free(hdr2);
+ return status;
+ }
+
+ /*
+ * if the policy includes authentication, then test for false positives
+ */
+ if (policy->rtp.sec_serv & sec_serv_auth) {
+ char *data = ((char *)hdr) + 12;
+
+ printf("testing for false positives in replay check...");
+
+ /* set message length */
+ len = msg_len_enc;
+
+ /* unprotect a second time - should fail with a replay error */
+ status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
+ if (status != err_status_replay_fail) {
+ printf("failed with error code %d\n", status);
+ free(hdr);
+ free(hdr2);
+ return status;
+ } else {
+ printf("passed\n");
+ }
+
+ printf("testing for false positives in auth check...");
+
+ /* increment sequence number in header */
+ hdr->seq++;
+
+ /* set message length */
+ len = msg_len_octets;
+
+ /* apply protection */
+ err_check(srtp_protect(srtp_sender, hdr, &len));
+
+ /* flip bits in packet */
+ data[0] ^= 0xff;
+
+ /* unprotect, and check for authentication failure */
+ status = srtp_unprotect(srtp_rcvr, hdr, &len);
+ if (status != err_status_auth_fail) {
+ printf("failed\n");
+ free(hdr);
+ free(hdr2);
+ return status;
+ } else {
+ printf("passed\n");
+ }
+
+ }
+
+ err_check(srtp_dealloc(srtp_sender));
+ err_check(srtp_dealloc(srtp_rcvr));
+
+ free(hdr);
+ free(hdr2);
+ return err_status_ok;
+}
+
+
+err_status_t
+srtcp_test(const srtp_policy_t *policy) {
+ int i;
+ srtp_t srtcp_sender;
+ srtp_t srtcp_rcvr;
+ err_status_t status = err_status_ok;
+ srtp_hdr_t *hdr, *hdr2;
+ uint8_t hdr_enc[64];
+ uint8_t *pkt_end;
+ int msg_len_octets, msg_len_enc;
+ int len;
+ int tag_length = policy->rtp.auth_tag_len;
+ uint32_t ssrc;
+ srtp_policy_t *rcvr_policy;
+
+ err_check(srtp_create(&srtcp_sender, policy));
+
+ /* print out policy */
+ err_check(srtp_session_print_policy(srtcp_sender));
+
+ /*
+ * initialize data buffer, using the ssrc in the policy unless that
+ * value is a wildcard, in which case we'll just use an arbitrary
+ * one
+ */
+ if (policy->ssrc.type != ssrc_specific)
+ ssrc = 0xdecafbad;
+ else
+ ssrc = policy->ssrc.value;
+ msg_len_octets = 28;
+ hdr = srtp_create_test_packet(msg_len_octets, ssrc);
+
+ if (hdr == NULL)
+ return err_status_alloc_fail;
+ hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
+ if (hdr2 == NULL) {
+ free(hdr);
+ return err_status_alloc_fail;
+ }
+
+ /* set message length */
+ len = msg_len_octets;
+
+ debug_print(mod_driver, "before protection:\n%s",
+ srtp_packet_to_string(hdr, len));
+
+#if PRINT_REFERENCE_PACKET
+ debug_print(mod_driver, "reference packet before protection:\n%s",
+ octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+ err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
+
+ debug_print(mod_driver, "after protection:\n%s",
+ srtp_packet_to_string(hdr, len));
+#if PRINT_REFERENCE_PACKET
+ debug_print(mod_driver, "after protection:\n%s",
+ octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+
+ /* save protected message and length */
+ memcpy(hdr_enc, hdr, len);
+ msg_len_enc = len;
+
+ /*
+ * check for overrun of the srtp_protect() function
+ *
+ * The packet is followed by a value of 0xfffff; if the value of the
+ * data following the packet is different, then we know that the
+ * protect function is overwriting the end of the packet.
+ */
+ pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
+ + msg_len_octets + tag_length;
+ for (i = 0; i < 4; i++)
+ if (pkt_end[i] != 0xff) {
+ fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
+ "(expected %x, found %x in trailing octet %d)\n",
+ 0xff, ((uint8_t *)hdr)[i], i);
+ free(hdr);
+ free(hdr2);
+ return err_status_algo_fail;
+ }
+
+ /*
+ * if the policy includes confidentiality, check that ciphertext is
+ * different than plaintext
+ *
+ * Note that this check will give false negatives, with some small
+ * probability, especially if the packets are short. For that
+ * reason, we skip this check if the plaintext is less than four
+ * octets long.
+ */
+ if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
+ printf("testing that ciphertext is distinct from plaintext...");
+ status = err_status_algo_fail;
+ for (i=12; i < msg_len_octets+12; i++)
+ if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+ status = err_status_ok;
+ }
+ if (status) {
+ printf("failed\n");
+ free(hdr);
+ free(hdr2);
+ return status;
+ }
+ printf("passed\n");
+ }
+
+ /*
+ * if the policy uses a 'wildcard' ssrc, then we need to make a copy
+ * of the policy that changes the direction to inbound
+ *
+ * we always copy the policy into the rcvr_policy, since otherwise
+ * the compiler would fret about the constness of the policy
+ */
+ rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
+ if (rcvr_policy == NULL)
+ return err_status_alloc_fail;
+ memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
+ if (policy->ssrc.type == ssrc_any_outbound) {
+ rcvr_policy->ssrc.type = ssrc_any_inbound;
+ }
+
+ err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
+
+ err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
+
+ debug_print(mod_driver, "after unprotection:\n%s",
+ srtp_packet_to_string(hdr, len));
+
+ /* verify that the unprotected packet matches the origial one */
+ for (i=0; i < msg_len_octets; i++)
+ if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+ fprintf(stdout, "mismatch at octet %d\n", i);
+ status = err_status_algo_fail;
+ }
+ if (status) {
+ free(hdr);
+ free(hdr2);
+ return status;
+ }
+
+ /*
+ * if the policy includes authentication, then test for false positives
+ */
+ if (policy->rtp.sec_serv & sec_serv_auth) {
+ char *data = ((char *)hdr) + 12;
+
+ printf("testing for false positives in replay check...");
+
+ /* set message length */
+ len = msg_len_enc;
+
+ /* unprotect a second time - should fail with a replay error */
+ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
+ if (status != err_status_replay_fail) {
+ printf("failed with error code %d\n", status);
+ free(hdr);
+ free(hdr2);
+ return status;
+ } else {
+ printf("passed\n");
+ }
+
+ printf("testing for false positives in auth check...");
+
+ /* increment sequence number in header */
+ hdr->seq++;
+
+ /* set message length */
+ len = msg_len_octets;
+
+ /* apply protection */
+ err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
+
+ /* flip bits in packet */
+ data[0] ^= 0xff;
+
+ /* unprotect, and check for authentication failure */
+ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
+ if (status != err_status_auth_fail) {
+ printf("failed\n");
+ free(hdr);
+ free(hdr2);
+ return status;
+ } else {
+ printf("passed\n");
+ }
+
+ }
+
+ err_check(srtp_dealloc(srtcp_sender));
+ err_check(srtp_dealloc(srtcp_rcvr));
+
+ free(hdr);
+ free(hdr2);
+ return err_status_ok;
+}
+
+
+err_status_t
+srtp_session_print_policy(srtp_t srtp) {
+ char *serv_descr[4] = {
+ "none",
+ "confidentiality",
+ "authentication",
+ "confidentiality and authentication"
+ };
+ char *direction[3] = {
+ "unknown",
+ "outbound",
+ "inbound"
+ };
+ srtp_stream_t stream;
+
+ /* sanity checking */
+ if (srtp == NULL)
+ return err_status_fail;
+
+ /* if there's a template stream, print it out */
+ if (srtp->stream_template != NULL) {
+ stream = srtp->stream_template;
+ printf("# SSRC: any %s\r\n"
+ "# rtp cipher: %s\r\n"
+ "# rtp auth: %s\r\n"
+ "# rtp services: %s\r\n"
+ "# rtcp cipher: %s\r\n"
+ "# rtcp auth: %s\r\n"
+ "# rtcp services: %s\r\n",
+ direction[stream->direction],
+ stream->rtp_cipher->type->description,
+ stream->rtp_auth->type->description,
+ serv_descr[stream->rtp_services],
+ stream->rtcp_cipher->type->description,
+ stream->rtcp_auth->type->description,
+ serv_descr[stream->rtcp_services]);
+ }
+
+ /* loop over streams in session, printing the policy of each */
+ stream = srtp->stream_list;
+ while (stream != NULL) {
+ if (stream->rtp_services > sec_serv_conf_and_auth)
+ return err_status_bad_param;
+
+ printf("# SSRC: 0x%08x\r\n"
+ "# rtp cipher: %s\r\n"
+ "# rtp auth: %s\r\n"
+ "# rtp services: %s\r\n"
+ "# rtcp cipher: %s\r\n"
+ "# rtcp auth: %s\r\n"
+ "# rtcp services: %s\r\n",
+ stream->ssrc,
+ stream->rtp_cipher->type->description,
+ stream->rtp_auth->type->description,
+ serv_descr[stream->rtp_services],
+ stream->rtcp_cipher->type->description,
+ stream->rtcp_auth->type->description,
+ serv_descr[stream->rtcp_services]);
+
+ /* advance to next stream in the list */
+ stream = stream->next;
+ }
+ return err_status_ok;
+}
+
+err_status_t
+srtp_print_policy(const srtp_policy_t *policy) {
+ err_status_t status;
+ srtp_t session;
+
+ status = srtp_create(&session, policy);
+ if (status)
+ return status;
+ status = srtp_session_print_policy(session);
+ if (status)
+ return status;
+ status = srtp_dealloc(session);
+ if (status)
+ return status;
+ return err_status_ok;
+}
+
+/*
+ * srtp_print_packet(...) is for debugging only
+ * it prints an RTP packet to the stdout
+ *
+ * note that this function is *not* threadsafe
+ */
+
+#include <stdio.h>
+
+#define MTU 2048
+
+char packet_string[MTU];
+
+char *
+srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
+ int octets_in_rtp_header = 12;
+ uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
+ int hex_len = pkt_octet_len-octets_in_rtp_header;
+
+ /* sanity checking */
+ if ((hdr == NULL) || (pkt_octet_len > MTU))
+ return NULL;
+
+ /* write packet into string */
+ sprintf(packet_string,
+ "(s)rtp packet: {\n"
+ " version:\t%d\n"
+ " p:\t\t%d\n"
+ " x:\t\t%d\n"
+ " cc:\t\t%d\n"
+ " m:\t\t%d\n"
+ " pt:\t\t%x\n"
+ " seq:\t\t%x\n"
+ " ts:\t\t%x\n"
+ " ssrc:\t%x\n"
+ " data:\t%s\n"
+ "} (%d octets in total)\n",
+ hdr->version,
+ hdr->p,
+ hdr->x,
+ hdr->cc,
+ hdr->m,
+ hdr->pt,
+ hdr->seq,
+ hdr->ts,
+ hdr->ssrc,
+ octet_string_hex_string(data, hex_len),
+ pkt_octet_len);
+
+ return packet_string;
+}
+
+/*
+ * mips_estimate() is a simple function to estimate the number of
+ * instructions per second that the host can perform. note that this
+ * function can be grossly wrong; you may want to have a manual sanity
+ * check of its output!
+ *
+ * the 'ignore' pointer is there to convince the compiler to not just
+ * optimize away the function
+ */
+
+double
+mips_estimate(int num_trials, int *ignore) {
+ clock_t t;
+ int i, sum;
+
+ sum = 0;
+ t = clock();
+ for (i=0; i<num_trials; i++)
+ sum += i;
+ t = clock() - t;
+
+/* printf("%d\n", sum); */
+ *ignore = sum;
+
+ return (double) num_trials * CLOCKS_PER_SEC / t;
+}
+
+
+/*
+ * srtp_validate() verifies the correctness of libsrtp by comparing
+ * some computed packets against some pre-computed reference values.
+ * These packets were made with the default SRTP policy.
+ */
+
+
+err_status_t
+srtp_validate() {
+ unsigned char test_key[30] = {
+ 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+ 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+ 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+ 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+ };
+ uint8_t srtp_plaintext_ref[28] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab
+ };
+ uint8_t srtp_plaintext[38] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ uint8_t srtp_ciphertext[38] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
+ 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
+ 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
+ 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
+ };
+ srtp_t srtp_snd, srtp_recv;
+ err_status_t status;
+ int len;
+ srtp_policy_t policy;
+
+ /*
+ * create a session with a single stream using the default srtp
+ * policy and with the SSRC value 0xcafebabe
+ */
+ crypto_policy_set_rtp_default(&policy.rtp);
+ crypto_policy_set_rtcp_default(&policy.rtcp);
+ policy.ssrc.type = ssrc_specific;
+ policy.ssrc.value = 0xcafebabe;
+ policy.key = test_key;
+ policy.next = NULL;
+
+ status = srtp_create(&srtp_snd, &policy);
+ if (status)
+ return status;
+
+ /*
+ * protect plaintext, then compare with ciphertext
+ */
+ len = 28;
+ status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+ if (status || (len != 38))
+ return err_status_fail;
+
+ debug_print(mod_driver, "ciphertext:\n %s",
+ octet_string_hex_string(srtp_plaintext, len));
+ debug_print(mod_driver, "ciphertext reference:\n %s",
+ octet_string_hex_string(srtp_ciphertext, len));
+
+ if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+ return err_status_fail;
+
+ /*
+ * create a receiver session context comparable to the one created
+ * above - we need to do this so that the replay checking doesn't
+ * complain
+ */
+ status = srtp_create(&srtp_recv, &policy);
+ if (status)
+ return status;
+
+ /*
+ * unprotect ciphertext, then compare with plaintext
+ */
+ status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+ if (status || (len != 28))
+ return status;
+
+ if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+ return err_status_fail;
+
+ return err_status_ok;
+}
+
+
+err_status_t
+srtp_create_big_policy(srtp_policy_t **list) {
+ extern const srtp_policy_t *policy_array[];
+ srtp_policy_t *p, *tmp;
+ int i = 0;
+ uint32_t ssrc = 0;
+
+ /* sanity checking */
+ if ((list == NULL) || (policy_array[0] == NULL))
+ return err_status_bad_param;
+
+ /*
+ * loop over policy list, mallocing a new list and copying values
+ * into it (and incrementing the SSRC value as we go along)
+ */
+ tmp = NULL;
+ while (policy_array[i] != NULL) {
+ p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
+ if (p == NULL)
+ return err_status_bad_param;
+ memcpy(p, policy_array[i], sizeof(srtp_policy_t));
+ p->ssrc.type = ssrc_specific;
+ p->ssrc.value = ssrc++;
+ p->next = tmp;
+ tmp = p;
+ i++;
+ }
+ *list = p;
+
+ return err_status_ok;
+}
+
+err_status_t
+srtp_test_remove_stream() {
+ err_status_t status;
+ srtp_policy_t *policy_list;
+ srtp_t session;
+ srtp_stream_t stream;
+ /*
+ * srtp_get_stream() is a libSRTP internal function that we declare
+ * here so that we can use it to verify the correct operation of the
+ * library
+ */
+ extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
+
+
+ status = srtp_create_big_policy(&policy_list);
+ if (status)
+ return status;
+
+ status = srtp_create(&session, policy_list);
+ if (status)
+ return status;
+
+ /*
+ * check for false positives by trying to remove a stream that's not
+ * in the session
+ */
+ status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
+ if (status != err_status_no_ctx)
+ return err_status_fail;
+
+ /*
+ * check for false negatives by removing stream 0x1, then
+ * searching for streams 0x0 and 0x2
+ */
+ status = srtp_remove_stream(session, htonl(0x1));
+ if (status != err_status_ok)
+ return err_status_fail;
+ stream = srtp_get_stream(session, htonl(0x0));
+ if (stream == NULL)
+ return err_status_fail;
+ stream = srtp_get_stream(session, htonl(0x2));
+ if (stream == NULL)
+ return err_status_fail;
+
+ return err_status_ok;
+}
+
+/*
+ * srtp policy definitions - these definitions are used above
+ */
+
+unsigned char test_key[30] = {
+ 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+ 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+ 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+ 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+};
+
+
+const srtp_policy_t default_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 16, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 16, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+const srtp_policy_t aes_tmmh_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ UST_TMMHv2, /* authentication func type */
+ 94, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ UST_TMMHv2, /* authentication func type */
+ 94, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+const srtp_policy_t tmmh_only_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ UST_TMMHv2, /* authentication func type */
+ 94, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ UST_TMMHv2, /* authentication func type */
+ 94, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+const srtp_policy_t aes_only_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 0, /* auth tag length in octets */
+ sec_serv_conf /* security services flag */
+ },
+ {
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 0, /* auth tag length in octets */
+ sec_serv_conf /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+const srtp_policy_t hmac_only_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+const srtp_policy_t null_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 0, /* auth tag length in octets */
+ sec_serv_none /* security services flag */
+ },
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 0, /* auth tag length in octets */
+ sec_serv_none /* security services flag */
+ },
+ test_key,
+ NULL
+};
+
+
+/*
+ * an array of pointers to the policies listed above
+ *
+ * This array is used to test various aspects of libSRTP for
+ * different cryptographic policies. The order of the elements
+ * matters - the timing test generates output that can be used
+ * in a plot (see the gnuplot script file 'timing'). If you
+ * add to this list, you should do it at the end.
+ */
+
+#define USE_TMMH 0
+
+const srtp_policy_t *
+policy_array[] = {
+ &hmac_only_policy,
+#if USE_TMMH
+ &tmmh_only_policy,
+#endif
+ &aes_only_policy,
+#if USE_TMMH
+ &aes_tmmh_policy,
+#endif
+ &default_policy,
+ &null_policy,
+ NULL
+};
+
+const srtp_policy_t wildcard_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 16, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_128_ICM, /* cipher type */
+ 30, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 16, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_key,
+ NULL
+};
diff --git a/jni/pjproject-android/.svn/pristine/85/85a821cd35e56dc68e9de7ece9b322cc117f89e7.svn-base b/jni/pjproject-android/.svn/pristine/85/85a821cd35e56dc68e9de7ece9b322cc117f89e7.svn-base
new file mode 100644
index 0000000..1c8b168d
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/85a821cd35e56dc68e9de7ece9b322cc117f89e7.svn-base
@@ -0,0 +1,57 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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
+ */
+#ifndef __PJMEDIA_STREAM_COMMON_H__
+#define __PJMEDIA_STREAM_COMMON_H__
+
+
+/**
+ * @file stream_common.h
+ * @brief Stream common functions.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/sdp.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * This is internal function for parsing SDP format parameter of specific
+ * format or payload type, used by stream in generating stream info from SDP.
+ *
+ * @param pool Pool to allocate memory, if pool is NULL, the fmtp
+ * string pointers will point to the original string in
+ * the SDP media descriptor.
+ * @param m The SDP media containing the format parameter to
+ * be parsed.
+ * @param pt The format or payload type.
+ * @param fmtp The format parameter to store the parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp(pj_pool_t *pool,
+ const pjmedia_sdp_media *m,
+ unsigned pt,
+ pjmedia_codec_fmtp *fmtp);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_STREAM_COMMON_H__ */
diff --git a/jni/pjproject-android/.svn/pristine/85/85bdd669f9851b0c239589ad5bb9ada4ad459e56.svn-base b/jni/pjproject-android/.svn/pristine/85/85bdd669f9851b0c239589ad5bb9ada4ad459e56.svn-base
new file mode 100644
index 0000000..de9b1ec
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/85bdd669f9851b0c239589ad5bb9ada4ad459e56.svn-base
@@ -0,0 +1,12 @@
+ </TD></TD></TABLE>
+<p> </p>
+<hr><center>
+PJNATH - Open Source NAT traversal helper library supporting STUN, TURN, and ICE<br>
+Copyright (C) 2006-2009 Teluu Inc.
+</center>
+
+
+<!--#include virtual="/footer.html" -->
+
+</BODY>
+</HTML>
diff --git a/jni/pjproject-android/.svn/pristine/85/85e6f71909ff09d67b592cb35d05c7296742e0f0.svn-base b/jni/pjproject-android/.svn/pristine/85/85e6f71909ff09d67b592cb35d05c7296742e0f0.svn-base
new file mode 100644
index 0000000..e4ae4d7
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/85e6f71909ff09d67b592cb35d05c7296742e0f0.svn-base
@@ -0,0 +1,744 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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
+ */
+#ifndef __PJNATH_TURN_SESSION_H__
+#define __PJNATH_TURN_SESSION_H__
+
+/**
+ * @file turn_session.h
+ * @brief Transport independent TURN client session.
+ */
+#include <pjnath/stun_session.h>
+#include <pjlib-util/resolver.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+@addtogroup PJNATH_TURN_SESSION
+@{
+
+The \ref PJNATH_TURN_SESSION is a transport-independent object to
+manage a client TURN session. It contains the core logic for manage
+the TURN client session as listed in \ref turn_op_sec, but
+in transport-independent manner (i.e. it doesn't have a socket), so
+that developer can integrate TURN client functionality into existing
+framework that already has its own means to send and receive data,
+or to support new transport types to TURN, such as TLS.
+
+
+\section turn_sess_using_sec Using the TURN session
+
+These steps describes how to use the TURN session:
+
+ - <b>Creating the session</b>:\n
+ use #pj_turn_session_create() to create the session.
+
+ - <b>Configuring credential</b>:\n
+ all TURN operations requires the use of authentication (it uses STUN
+ long term autentication method). Use #pj_turn_session_set_credential()
+ to configure the TURN credential to be used by the session.
+
+ - <b>Configuring server</b>:\n
+ application must call #pj_turn_session_set_server() before it can send
+ Allocate request (with pj_turn_session_alloc()). This function will
+ resolve the TURN server using DNS SRV resolution if the \a resolver
+ is set. The server resolution process will complete asynchronously,
+ and application will be notified in \a on_state() callback of the
+ #pj_turn_session_cb structurewith the session state set to
+ PJ_TURN_STATE_RESOLVED.
+
+ - <b>Creating allocation</b>:\n
+ create one "relay port" (or called <b>relayed-transport-address</b>
+ in TURN terminology) in the TURN server by using #pj_turn_session_alloc().
+ This will send Allocate request to the server. This function will complete
+ immediately, and application will be notified about the allocation
+ result in the \a on_state() callback of the #pj_turn_session_cb structure.
+
+ - <b>Getting the allocation result</b>:\n
+ if allocation is successful, the session state will progress to
+ \a PJ_TURN_STATE_READY, otherwise the state will be
+ \a PJ_TURN_STATE_DEALLOCATED or higher. Session state progression is
+ reported in the \a on_state() callback of the #pj_turn_session_cb
+ structure. On successful allocation, application may retrieve the
+ allocation info by calling #pj_turn_session_get_info().
+
+ - <b>Sending data through the relay</b>.\n
+ Once allocation has been created, client may send data to any remote
+ endpoints (called peers in TURN terminology) via the "relay port". It does
+ so by calling #pj_turn_session_sendto(), giving the peer address
+ in the function argument. But note that at this point peers are not allowed
+ to send data towards the client (via the "relay port") before permission is
+ installed for that peer.
+
+ - <b>Creating permissions</b>.\n
+ Permission needs to be created in the TURN server so that a peer can send
+ data to the client via the relay port (a peer in this case is identified by
+ its IP address). Without this, when the TURN server receives data from the
+ peer in the "relay port", it will drop this data. Create the permission by
+ calling #pj_turn_session_set_perm(), specifying the peer IP address in the
+ argument (the port part of the address is ignored). More than one IP
+ addresses may be specified.
+
+ - <b>Receiving data from peers</b>.\n
+ Once permission has been installed for the peer, any data received by the
+ TURN server (from that peer) in the "relay port" will be relayed back to
+ client by the server, and application will be notified via \a on_rx_data
+ callback of the #pj_turn_session_cb.
+
+ - <b>Using ChannelData</b>.\n
+ TURN provides optimized framing to the data by using ChannelData
+ packetization. The client activates this format for the specified peer by
+ calling #pj_turn_session_bind_channel(). Data sent or received to/for
+ this peer will then use ChannelData format instead of Send or Data
+ Indications.
+
+ - <b>Refreshing the allocation, permissions, and channel bindings</b>.\n
+ Allocations, permissions, and channel bindings will be refreshed by the
+ session automatically when they about to expire.
+
+ - <b>Destroying the allocation</b>.\n
+ Once the "relay port" is no longer needed, client destroys the allocation
+ by calling #pj_turn_session_shutdown(). This function will return
+ immediately, and application will be notified about the deallocation
+ result in the \a on_state() callback of the #pj_turn_session_cb structure.
+ Once the state has reached PJ_TURN_STATE_DESTROYING, application must
+ assume that the session will be destroyed shortly after.
+
+ */
+
+/**
+ * Opaque declaration for TURN client session.
+ */
+typedef struct pj_turn_session pj_turn_session;
+
+
+/**
+ * TURN transport types, which will be used both to specify the connection
+ * type for reaching TURN server and the type of allocation transport to be
+ * requested to server (the REQUESTED-TRANSPORT attribute).
+ */
+typedef enum pj_turn_tp_type
+{
+ /**
+ * UDP transport, which value corresponds to IANA protocol number.
+ */
+ PJ_TURN_TP_UDP = 17,
+
+ /**
+ * TCP transport, which value corresponds to IANA protocol number.
+ */
+ PJ_TURN_TP_TCP = 6,
+
+ /**
+ * TLS transport. The TLS transport will only be used as the connection
+ * type to reach the server and never as the allocation transport type.
+ */
+ PJ_TURN_TP_TLS = 255
+
+} pj_turn_tp_type;
+
+
+/** TURN session state */
+typedef enum pj_turn_state_t
+{
+ /**
+ * TURN session has just been created.
+ */
+ PJ_TURN_STATE_NULL,
+
+ /**
+ * TURN server has been configured and now is being resolved via
+ * DNS SRV resolution.
+ */
+ PJ_TURN_STATE_RESOLVING,
+
+ /**
+ * TURN server has been resolved. If there is pending allocation to
+ * be done, it will be invoked immediately.
+ */
+ PJ_TURN_STATE_RESOLVED,
+
+ /**
+ * TURN session has issued ALLOCATE request and is waiting for response
+ * from the TURN server.
+ */
+ PJ_TURN_STATE_ALLOCATING,
+
+ /**
+ * TURN session has successfully allocated relay resoruce and now is
+ * ready to be used.
+ */
+ PJ_TURN_STATE_READY,
+
+ /**
+ * TURN session has issued deallocate request and is waiting for a
+ * response from the TURN server.
+ */
+ PJ_TURN_STATE_DEALLOCATING,
+
+ /**
+ * Deallocate response has been received. Normally the session will
+ * proceed to DESTROYING state immediately.
+ */
+ PJ_TURN_STATE_DEALLOCATED,
+
+ /**
+ * TURN session is being destroyed.
+ */
+ PJ_TURN_STATE_DESTROYING
+
+} pj_turn_state_t;
+
+
+#pragma pack(1)
+
+/**
+ * This structure ChannelData header. All the fields are in network byte
+ * order when it's on the wire.
+ */
+typedef struct pj_turn_channel_data
+{
+ pj_uint16_t ch_number; /**< Channel number. */
+ pj_uint16_t length; /**< Payload length. */
+} pj_turn_channel_data;
+
+
+#pragma pack()
+
+
+/**
+ * Callback to receive events from TURN session.
+ */
+typedef struct pj_turn_session_cb
+{
+ /**
+ * This callback will be called by the TURN session whenever it
+ * needs to send outgoing message. Since the TURN session doesn't
+ * have a socket on its own, this callback must be implemented.
+ *
+ * @param sess The TURN session.
+ * @param pkt The packet/data to be sent.
+ * @param pkt_len Length of the packet/data.
+ * @param dst_addr Destination address of the packet.
+ * @param addr_len Length of the destination address.
+ *
+ * @return The callback should return the status of the
+ * send operation.
+ */
+ pj_status_t (*on_send_pkt)(pj_turn_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+ /**
+ * Notification when peer address has been bound successfully to
+ * a channel number.
+ *
+ * This callback is optional since the nature of this callback is
+ * for information only.
+ *
+ * @param sess The TURN session.
+ * @param peer_addr The peer address.
+ * @param addr_len Length of the peer address.
+ * @param ch_num The channel number associated with this peer address.
+ */
+ void (*on_channel_bound)(pj_turn_session *sess,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len,
+ unsigned ch_num);
+
+ /**
+ * Notification when incoming data has been received, either through
+ * Data indication or ChannelData message from the TURN server.
+ *
+ * @param sess The TURN session.
+ * @param pkt The data/payload of the Data Indication or ChannelData
+ * packet.
+ * @param pkt_len Length of the data/payload.
+ * @param peer_addr Peer address where this payload was received by
+ * the TURN server.
+ * @param addr_len Length of the peer address.
+ */
+ void (*on_rx_data)(pj_turn_session *sess,
+ void *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+ /**
+ * Notification when TURN session state has changed. Application should
+ * implement this callback at least to know that the TURN session is
+ * going to be destroyed.
+ *
+ * @param sess The TURN session.
+ * @param old_state The previous state of the session.
+ * @param new_state The current state of the session.
+ */
+ void (*on_state)(pj_turn_session *sess,
+ pj_turn_state_t old_state,
+ pj_turn_state_t new_state);
+
+} pj_turn_session_cb;
+
+
+/**
+ * Allocation parameter, which can be given when application calls
+ * pj_turn_session_alloc() to allocate relay address in the TURN server.
+ * Application should call pj_turn_alloc_param_default() to initialize
+ * this structure with the default values.
+ */
+typedef struct pj_turn_alloc_param
+{
+ /**
+ * The requested BANDWIDTH. Default is zero to not request any
+ * specific bandwidth. Note that this attribute has been deprecated
+ * after TURN-08 draft, hence application should only use this
+ * attribute when talking to TURN-07 or older version.
+ */
+ int bandwidth;
+
+ /**
+ * The requested LIFETIME. Default is zero to not request any
+ * explicit allocation lifetime.
+ */
+ int lifetime;
+
+ /**
+ * If set to non-zero, the TURN session will periodically send blank
+ * Send Indication every PJ_TURN_KEEP_ALIVE_SEC to refresh local
+ * NAT bindings. Default is zero.
+ */
+ int ka_interval;
+
+} pj_turn_alloc_param;
+
+
+/**
+ * This structure describes TURN session info.
+ */
+typedef struct pj_turn_session_info
+{
+ /**
+ * Session state.
+ */
+ pj_turn_state_t state;
+
+ /**
+ * Last error (if session was terminated because of error)
+ */
+ pj_status_t last_status;
+
+ /**
+ * Type of connection to the TURN server.
+ */
+ pj_turn_tp_type conn_type;
+
+ /**
+ * The selected TURN server address.
+ */
+ pj_sockaddr server;
+
+ /**
+ * Mapped address, as reported by the TURN server.
+ */
+ pj_sockaddr mapped_addr;
+
+ /**
+ * The relay address
+ */
+ pj_sockaddr relay_addr;
+
+ /**
+ * Current seconds before allocation expires.
+ */
+ int lifetime;
+
+} pj_turn_session_info;
+
+
+/**
+ * Initialize pj_turn_alloc_param with the default values.
+ *
+ * @param prm The TURN allocation parameter to be initialized.
+ */
+PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm);
+
+
+/**
+ * Duplicate pj_turn_alloc_param.
+ *
+ * @param pool Pool to allocate memory (currently not used)
+ * @param dst Destination parameter.
+ * @param src Source parameter.
+ */
+PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool,
+ pj_turn_alloc_param *dst,
+ const pj_turn_alloc_param *src);
+
+/**
+ * Get string representation for the given TURN state.
+ *
+ * @param state The TURN session state.
+ *
+ * @return The state name as NULL terminated string.
+ */
+PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state);
+
+
+/**
+ * Create a TURN session instance with the specified address family and
+ * connection type. Once TURN session instance is created, application
+ * must call pj_turn_session_alloc() to allocate a relay address in the TURN
+ * server.
+ *
+ * @param cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this session.
+ * @param name Optional name to identify this session in the log.
+ * @param af Address family of the client connection. Currently
+ * pj_AF_INET() and pj_AF_INET6() are supported.
+ * @param conn_type Connection type to the TURN server.
+ * @param grp_lock Optional group lock object to be used by this session.
+ * If this value is NULL, the session will create
+ * a group lock internally.
+ * @param cb Callback to receive events from the TURN session.
+ * @param options Option flags, currently this value must be zero.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_sess Pointer to receive the created instance of the
+ * TURN session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg,
+ const char *name,
+ int af,
+ pj_turn_tp_type conn_type,
+ pj_grp_lock_t *grp_lock,
+ const pj_turn_session_cb *cb,
+ unsigned options,
+ void *user_data,
+ pj_turn_session **p_sess);
+
+/**
+ * Shutdown TURN client session. This will gracefully deallocate and
+ * destroy the client session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess);
+
+
+/**
+ * Forcefully destroy the TURN session. This will destroy the session
+ * immediately. If there is an active allocation, the server will not
+ * be notified about the client destruction.
+ *
+ * @param sess The TURN client session.
+ * @param last_err Optional error code to be set to the session,
+ * which would be returned back in the \a info
+ * parameter of #pj_turn_session_get_info(). If
+ * this argument value is PJ_SUCCESS, the error
+ * code will not be set. If the session already
+ * has an error code set, this function will not
+ * overwrite that error code either.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess,
+ pj_status_t last_err);
+
+
+/**
+ * Get the information about this TURN session and the allocation, if
+ * any.
+ *
+ * @param sess The TURN client session.
+ * @param info The structure to be initialized with the TURN
+ * session info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess,
+ pj_turn_session_info *info);
+
+/**
+ * Associate a user data with this TURN session. The user data may then
+ * be retrieved later with pj_turn_session_get_user_data().
+ *
+ * @param sess The TURN client session.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess,
+ void *user_data);
+
+/**
+ * Retrieve the previously assigned user data associated with this TURN
+ * session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return The user/application data.
+ */
+PJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess);
+
+
+/**
+ * Get the group lock for this TURN session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return The group lock.
+ */
+PJ_DECL(pj_grp_lock_t *) pj_turn_session_get_grp_lock(pj_turn_session *sess);
+
+
+/**
+ * Configure message logging. By default all flags are enabled.
+ *
+ * @param sess The TURN client session.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess,
+ unsigned flags);
+
+
+/**
+ * Configure the SOFTWARE name to be sent in all STUN requests by the
+ * TURN session.
+ *
+ * @param sess The TURN client session.
+ * @param sw Software name string. If this argument is NULL or
+ * empty, the session will not include SOFTWARE attribute
+ * in STUN requests and responses.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_software_name(pj_turn_session *sess,
+ const pj_str_t *sw);
+
+
+/**
+ * Set the server or domain name of the server. Before the application
+ * can send Allocate request (with pj_turn_session_alloc()), it must first
+ * resolve the server address(es) using this function. This function will
+ * resolve the TURN server using DNS SRV resolution if the \a resolver
+ * is set. The server resolution process will complete asynchronously,
+ * and application will be notified in \a on_state() callback with the
+ * session state set to PJ_TURN_STATE_RESOLVED.
+ *
+ * Application may call with pj_turn_session_alloc() before the server
+ * resolution completes. In this case, the operation will be queued by
+ * the session, and it will be sent once the server resolution completes.
+ *
+ * @param sess The TURN client session.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default TURN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the resolution process will be notified
+ * to application in \a on_state() callback.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess,
+ const pj_str_t *domain,
+ int default_port,
+ pj_dns_resolver *resolver);
+
+
+/**
+ * Set credential to be used to authenticate against TURN server.
+ * Application must call this function before sending Allocate request
+ * with pj_turn_session_alloc().
+ *
+ * @param sess The TURN client session
+ * @param cred STUN credential to be used.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess,
+ const pj_stun_auth_cred *cred);
+
+
+/**
+ * Allocate a relay address/resource in the TURN server by sending TURN
+ * Allocate request. Application must first initiate the server resolution
+ * process with pj_turn_session_set_server() and set the credential to be
+ * used with pj_turn_session_set_credential() before calling this function.
+ *
+ * This function will complete asynchronously, and the application will be
+ * notified about the allocation result in \a on_state() callback. The
+ * TURN session state will move to PJ_TURN_STATE_READY if allocation is
+ * successful, and PJ_TURN_STATE_DEALLOCATING or greater state if allocation
+ * has failed.
+ *
+ * Once allocation has been successful, the TURN session will keep this
+ * allocation alive until the session is destroyed, by sending periodic
+ * allocation refresh to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param param Optional TURN allocation parameter.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,
+ const pj_turn_alloc_param *param);
+
+
+/**
+ * Create or renew permission in the TURN server for the specified peer IP
+ * addresses. Application must install permission for a particular (peer)
+ * IP address before it sends any data to that IP address, or otherwise
+ * the TURN server will drop the data.
+ *
+ * @param sess The TURN client session.
+ * @param addr_cnt Number of IP addresses.
+ * @param addr Array of peer IP addresses. Only the address family
+ * and IP address portion of the socket address matter.
+ * @param options Specify 1 to let the TURN client session automatically
+ * renew the permission later when they are about to
+ * expire.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * issued, or the appropriate error code. Note that
+ * the operation itself will complete asynchronously.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_perm(pj_turn_session *sess,
+ unsigned addr_cnt,
+ const pj_sockaddr addr[],
+ unsigned options);
+
+
+/**
+ * Send a data to the specified peer address via the TURN relay. This
+ * function will encapsulate the data as STUN Send Indication or TURN
+ * ChannelData packet and send the message to the TURN server. The TURN
+ * server then will send the data to the peer.
+ *
+ * The allocation (pj_turn_session_alloc()) must have been successfully
+ * created before application can relay any data.
+ *
+ * Since TURN session is transport independent, this function will
+ * ultimately call \a on_send_pkt() callback to request the application
+ * to actually send the packet containing the data to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param peer_addr The remote peer address (the ultimate destination
+ * of the data, and not the TURN server address).
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+/**
+ * Optionally establish channel binding for the specified a peer address.
+ * This function will assign a unique channel number for the peer address
+ * and request channel binding to the TURN server for this address. When
+ * a channel has been bound to a peer, the TURN client and TURN server
+ * will exchange data using ChannelData encapsulation format, which has
+ * lower bandwidth overhead than Send Indication (the default format used
+ * when peer address is not bound to a channel).
+ *
+ * This function will complete asynchronously, and application will be
+ * notified about the result in \a on_channel_bound() callback.
+ *
+ * @param sess The TURN client session.
+ * @param peer The remote peer address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated, or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess,
+ const pj_sockaddr_t *peer,
+ unsigned addr_len);
+
+/**
+ * Notify TURN client session upon receiving a packet from server. Since
+ * the TURN session is transport independent, it does not read packet from
+ * any sockets, and rather relies on application giving it packets that
+ * are received from the TURN server. The session then processes this packet
+ * and decides whether it is part of TURN protocol exchange or if it is a
+ * data to be reported back to user, which in this case it will call the
+ * \a on_rx_data() callback.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The packet as received from the TURN server. This
+ * should contain either STUN encapsulated message or
+ * a ChannelData packet.
+ * @param pkt_len The length of the packet.
+ * @param parsed_len Optional argument to receive the number of parsed
+ * or processed data from the packet.
+ *
+ * @return The function may return non-PJ_SUCCESS if it receives
+ * non-STUN and non-ChannelData packet, or if the
+ * \a on_rx_data() returns non-PJ_SUCCESS;
+ */
+PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
+ void *pkt,
+ pj_size_t pkt_len,
+ pj_size_t *parsed_len);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_TURN_SESSION_H__ */
+