* #27232: jni: added pjproject checkout as regular git content

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
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/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>&nbsp;</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/85e114f5587589ebecc0ef4c808a7455af252ca2.svn-base b/jni/pjproject-android/.svn/pristine/85/85e114f5587589ebecc0ef4c808a7455af252ca2.svn-base
new file mode 100644
index 0000000..f31a19f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/85e114f5587589ebecc0ef4c808a7455af252ca2.svn-base
@@ -0,0 +1,636 @@
+/* $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 
+ */
+#include <pjlib-util/scanner.h>
+#include <pj/ctype.h>
+#include <pj/string.h>
+#include <pj/except.h>
+#include <pj/os.h>
+#include <pj/errno.h>
+#include <pj/assert.h>
+
+#define PJ_SCAN_IS_SPACE(c)		((c)==' ' || (c)=='\t')
+#define PJ_SCAN_IS_NEWLINE(c)		((c)=='\r' || (c)=='\n')
+#define PJ_SCAN_IS_PROBABLY_SPACE(c)	((c) <= 32)
+#define PJ_SCAN_CHECK_EOF(s)		(s != scanner->end)
+
+
+#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0
+#  include "scanner_cis_bitwise.c"
+#else
+#  include "scanner_cis_uint.c"
+#endif
+
+
+static void pj_scan_syntax_err(pj_scanner *scanner)
+{
+    (*scanner->callback)(scanner);
+}
+
+
+PJ_DEF(void) pj_cis_add_range(pj_cis_t *cis, int cstart, int cend)
+{
+    /* Can not set zero. This is the requirement of the parser. */
+    pj_assert(cstart > 0);
+
+    while (cstart != cend) {
+        PJ_CIS_SET(cis, cstart);
+	++cstart;
+    }
+}
+
+PJ_DEF(void) pj_cis_add_alpha(pj_cis_t *cis)
+{
+    pj_cis_add_range( cis, 'a', 'z'+1);
+    pj_cis_add_range( cis, 'A', 'Z'+1);
+}
+
+PJ_DEF(void) pj_cis_add_num(pj_cis_t *cis)
+{
+    pj_cis_add_range( cis, '0', '9'+1);
+}
+
+PJ_DEF(void) pj_cis_add_str( pj_cis_t *cis, const char *str)
+{
+    while (*str) {
+        PJ_CIS_SET(cis, *str);
+	++str;
+    }
+}
+
+PJ_DEF(void) pj_cis_add_cis( pj_cis_t *cis, const pj_cis_t *rhs)
+{
+    int i;
+    for (i=0; i<256; ++i) {
+	if (PJ_CIS_ISSET(rhs, i))
+	    PJ_CIS_SET(cis, i);
+    }
+}
+
+PJ_DEF(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend)
+{
+    while (cstart != cend) {
+        PJ_CIS_CLR(cis, cstart);
+        cstart++;
+    }
+}
+
+PJ_DEF(void) pj_cis_del_str( pj_cis_t *cis, const char *str)
+{
+    while (*str) {
+        PJ_CIS_CLR(cis, *str);
+	++str;
+    }
+}
+
+PJ_DEF(void) pj_cis_invert( pj_cis_t *cis )
+{
+    unsigned i;
+    /* Can not set zero. This is the requirement of the parser. */
+    for (i=1; i<256; ++i) {
+	if (PJ_CIS_ISSET(cis,i))
+            PJ_CIS_CLR(cis,i);
+        else
+            PJ_CIS_SET(cis,i);
+    }
+}
+
+PJ_DEF(void) pj_scan_init( pj_scanner *scanner, char *bufstart, 
+			   pj_size_t buflen, unsigned options, 
+			   pj_syn_err_func_ptr callback )
+{
+    PJ_CHECK_STACK();
+
+    scanner->begin = scanner->curptr = bufstart;
+    scanner->end = bufstart + buflen;
+    scanner->line = 1;
+    scanner->start_line = scanner->begin;
+    scanner->callback = callback;
+    scanner->skip_ws = options;
+
+    if (scanner->skip_ws) 
+	pj_scan_skip_whitespace(scanner);
+}
+
+
+PJ_DEF(void) pj_scan_fini( pj_scanner *scanner )
+{
+    PJ_CHECK_STACK();
+    PJ_UNUSED_ARG(scanner);
+}
+
+PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
+{
+    register char *s = scanner->curptr;
+
+    while (PJ_SCAN_IS_SPACE(*s)) {
+	++s;
+    }
+
+    if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE)) {
+	for (;;) {
+	    if (*s == '\r') {
+		++s;
+		if (*s == '\n') ++s;
+		++scanner->line;
+		scanner->curptr = scanner->start_line = s;
+	    } else if (*s == '\n') {
+		++s;
+		++scanner->line;
+		scanner->curptr = scanner->start_line = s;
+	    } else if (PJ_SCAN_IS_SPACE(*s)) {
+		do {
+		    ++s;
+		} while (PJ_SCAN_IS_SPACE(*s));
+	    } else {
+		break;
+	    }
+	}
+    }
+
+    if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==PJ_SCAN_AUTOSKIP_WS_HEADER) {
+	/* Check for header continuation. */
+	scanner->curptr = s;
+
+	if (*s == '\r') {
+	    ++s;
+	}
+	if (*s == '\n') {
+	    ++s;
+	}
+	scanner->start_line = s;
+
+	if (PJ_SCAN_IS_SPACE(*s)) {
+	    register char *t = s;
+	    do {
+		++t;
+	    } while (PJ_SCAN_IS_SPACE(*t));
+
+	    ++scanner->line;
+	    scanner->curptr = t;
+	}
+    } else {
+	scanner->curptr = s;
+    }
+}
+
+PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
+{
+    char *s = pj_ansi_strchr(scanner->curptr, '\n');
+    if (!s) {
+	scanner->curptr = scanner->end;
+    } else {
+	scanner->curptr = scanner->start_line = s+1;
+	scanner->line++;
+   }
+}
+
+PJ_DEF(int) pj_scan_peek( pj_scanner *scanner,
+			  const pj_cis_t *spec, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+
+    if (s >= scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+
+    /* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */
+    while (pj_cis_match(spec, *s))
+	++s;
+
+    pj_strset3(out, scanner->curptr, s);
+    return *s;
+}
+
+
+PJ_DEF(int) pj_scan_peek_n( pj_scanner *scanner,
+			     pj_size_t len, pj_str_t *out)
+{
+    char *endpos = scanner->curptr + len;
+
+    if (endpos > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+
+    pj_strset(out, scanner->curptr, len);
+    return *endpos;
+}
+
+
+PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
+				const pj_cis_t *spec, 
+				pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+
+    if (s >= scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+
+    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match( spec, *s))
+	++s;
+
+    pj_strset3(out, scanner->curptr, s);
+    return *s;
+}
+
+
+PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
+			  const pj_cis_t *spec, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+
+    pj_assert(pj_cis_match(spec,0)==0);
+
+    /* EOF is detected implicitly */
+    if (!pj_cis_match(spec, *s)) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    do {
+	++s;
+    } while (pj_cis_match(spec, *s));
+    /* No need to check EOF here (PJ_SCAN_CHECK_EOF(s)) because
+     * buffer is NULL terminated and pj_cis_match(spec,0) should be
+     * false.
+     */
+
+    pj_strset3(out, scanner->curptr, s);
+
+    scanner->curptr = s;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);    
+    }
+}
+
+
+PJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner,
+				   const pj_cis_t *spec, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+    char *dst = s;
+
+    pj_assert(pj_cis_match(spec,0)==0);
+
+    /* Must not match character '%' */
+    pj_assert(pj_cis_match(spec,'%')==0);
+
+    /* EOF is detected implicitly */
+    if (!pj_cis_match(spec, *s) && *s != '%') {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    out->ptr = s;
+    do {
+	if (*s == '%') {
+	    if (s+3 <= scanner->end && pj_isxdigit(*(s+1)) && 
+		pj_isxdigit(*(s+2))) 
+	    {
+		*dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(s+1)) << 4) +
+				      pj_hex_digit_to_val(*(s+2)));
+		++dst;
+		s += 3;
+	    } else {
+		*dst++ = *s++;
+		*dst++ = *s++;
+		break;
+	    }
+	}
+	
+	if (pj_cis_match(spec, *s)) {
+	    char *start = s;
+	    do {
+		++s;
+	    } while (pj_cis_match(spec, *s));
+
+	    if (dst != start) pj_memmove(dst, start, s-start);
+	    dst += (s-start);
+	} 
+	
+    } while (*s == '%');
+
+    scanner->curptr = s;
+    out->slen = (dst - out->ptr);
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);    
+    }
+}
+
+
+PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
+				int begin_quote, int end_quote, 
+				pj_str_t *out)
+{
+    char beg = (char)begin_quote;
+    char end = (char)end_quote;
+    pj_scan_get_quotes(scanner, &beg, &end, 1, out);
+}
+
+PJ_DEF(void) pj_scan_get_quotes(pj_scanner *scanner,
+                                const char *begin_quote, const char *end_quote,
+                                int qsize, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+    int qpair = -1;
+    int i;
+
+    pj_assert(qsize > 0);
+
+    /* Check and eat the begin_quote. */
+    for (i = 0; i < qsize; ++i) {
+	if (*s == begin_quote[i]) {
+	    qpair = i;
+	    break;
+	}
+    }
+    if (qpair == -1) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+    ++s;
+
+    /* Loop until end_quote is found. 
+     */
+    do {
+	/* loop until end_quote is found. */
+	while (PJ_SCAN_CHECK_EOF(s) && *s != '\n' && *s != end_quote[qpair]) {
+	    ++s;
+	}
+
+	/* check that no backslash character precedes the end_quote. */
+	if (*s == end_quote[qpair]) {
+	    if (*(s-1) == '\\') {
+		if (s-2 == scanner->begin) {
+		    break;
+		} else {
+		    char *q = s-2;
+		    char *r = s-2;
+
+		    while (r != scanner->begin && *r == '\\') {
+			--r;
+		    }
+		    /* break from main loop if we have odd number of backslashes */
+		    if (((unsigned)(q-r) & 0x01) == 1) {
+			break;
+		    }
+		    ++s;
+		}
+	    } else {
+		/* end_quote is not preceeded by backslash. break now. */
+		break;
+	    }
+	} else {
+	    /* loop ended by non-end_quote character. break now. */
+	    break;
+	}
+    } while (1);
+
+    /* Check and eat the end quote. */
+    if (*s != end_quote[qpair]) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+    ++s;
+
+    pj_strset3(out, scanner->curptr, s);
+
+    scanner->curptr = s;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+
+PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
+			    unsigned N, pj_str_t *out)
+{
+    if (scanner->curptr + N > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    pj_strset(out, scanner->curptr, N);
+    
+    scanner->curptr += N;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+
+PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
+{
+    int chr = *scanner->curptr;
+
+    if (!chr) {
+	pj_scan_syntax_err(scanner);
+	return 0;
+    }
+
+    ++scanner->curptr;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+    return chr;
+}
+
+
+PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
+{
+    if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    if (*scanner->curptr == '\r') {
+	++scanner->curptr;
+    }
+    if (*scanner->curptr == '\n') {
+	++scanner->curptr;
+    }
+
+    ++scanner->line;
+    scanner->start_line = scanner->curptr;
+
+    /**
+     * This probably is a bug, see PROTOS test #2480.
+     * This would cause scanner to incorrectly eat two new lines, e.g.
+     * when parsing:
+     *   
+     *	Content-Length: 120\r\n
+     *	\r\n
+     *	<space><space><space>...
+     *
+     * When pj_scan_get_newline() is called to parse the first newline
+     * in the Content-Length header, it will eat the second newline
+     * too because it thinks that it's a header continuation.
+     *
+     * if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
+     *    pj_scan_skip_whitespace(scanner);
+     * }
+     */
+}
+
+
+PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
+				const pj_cis_t *spec, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+
+    if (s >= scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match(spec, *s)) {
+	++s;
+    }
+
+    pj_strset3(out, scanner->curptr, s);
+
+    scanner->curptr = s;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+
+PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner, 
+				   int until_char, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+
+    if (s >= scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    while (PJ_SCAN_CHECK_EOF(s) && *s != until_char) {
+	++s;
+    }
+
+    pj_strset3(out, scanner->curptr, s);
+
+    scanner->curptr = s;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+
+PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,
+				     const char *until_spec, pj_str_t *out)
+{
+    register char *s = scanner->curptr;
+    pj_size_t speclen;
+
+    if (s >= scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    speclen = strlen(until_spec);
+    while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) {
+	++s;
+    }
+
+    pj_strset3(out, scanner->curptr, s);
+
+    scanner->curptr = s;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+PJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,
+				 unsigned N, pj_bool_t skip_ws)
+{
+    if (scanner->curptr + N > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return;
+    }
+
+    scanner->curptr += N;
+
+    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
+	pj_scan_skip_whitespace(scanner);
+    }
+}
+
+
+PJ_DEF(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len)
+{
+    if (scanner->curptr + len > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+    return strncmp(scanner->curptr, s, len);
+}
+
+
+PJ_DEF(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len)
+{
+    if (scanner->curptr + len > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+    return pj_ansi_strnicmp(scanner->curptr, s, len);
+}
+
+PJ_DEF(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s, 
+				   int len)
+{
+    if (scanner->curptr + len > scanner->end) {
+	pj_scan_syntax_err(scanner);
+	return -1;
+    }
+    return strnicmp_alnum(scanner->curptr, s, len);
+}
+
+PJ_DEF(void) pj_scan_save_state( const pj_scanner *scanner, 
+				 pj_scan_state *state)
+{
+    state->curptr = scanner->curptr;
+    state->line = scanner->line;
+    state->start_line = scanner->start_line;
+}
+
+
+PJ_DEF(void) pj_scan_restore_state( pj_scanner *scanner, 
+				    pj_scan_state *state)
+{
+    scanner->curptr = state->curptr;
+    scanner->line = state->line;
+    scanner->start_line = state->start_line;
+}
+
+