* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/39/392d8c7eaad03fc5f5726e57936fad180f73c9f5.svn-base b/jni/pjproject-android/.svn/pristine/39/392d8c7eaad03fc5f5726e57936fad180f73c9f5.svn-base
new file mode 100644
index 0000000..8221175
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/392d8c7eaad03fc5f5726e57936fad180f73c9f5.svn-base
@@ -0,0 +1,232 @@
+/* $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 <pjmedia/resample.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+#define BYTES_PER_SAMPLE	2
+#define SIGNATURE		PJMEDIA_SIG_PORT_RESAMPLE
+
+
+struct resample_port
+{
+    pjmedia_port	 base;
+    pjmedia_port	*dn_port;
+    unsigned		 options;
+    pjmedia_resample	*resample_get;
+    pjmedia_resample	*resample_put;
+    pj_int16_t		*get_buf;
+    pj_int16_t		*put_buf;
+};
+
+
+
+static pj_status_t resample_put_frame(pjmedia_port *this_port,
+				      pjmedia_frame *frame);
+static pj_status_t resample_get_frame(pjmedia_port *this_port, 
+				      pjmedia_frame *frame);
+static pj_status_t resample_destroy(pjmedia_port *this_port);
+
+
+
+PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
+						  pjmedia_port *dn_port,
+						  unsigned clock_rate,
+						  unsigned opt,
+						  pjmedia_port **p_port  )
+{
+    const pj_str_t name = pj_str("resample");
+    struct resample_port *rport;
+    pjmedia_audio_format_detail *d_afd, *r_afd;
+    pj_status_t status;
+
+    /* Validate arguments. */
+    PJ_ASSERT_RETURN(pool && dn_port && clock_rate && p_port, PJ_EINVAL);
+
+    /* Only supports 16bit samples per frame */
+    PJ_ASSERT_RETURN(PJMEDIA_PIA_BITS(&dn_port->info) == 16, PJMEDIA_ENCBITS);
+
+    d_afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, 1);
+
+    /* Create and initialize port. */
+    rport = PJ_POOL_ZALLOC_T(pool, struct resample_port);
+    PJ_ASSERT_RETURN(rport != NULL, PJ_ENOMEM);
+
+    pjmedia_port_info_init(&rport->base.info, &name, SIGNATURE, clock_rate,
+		           d_afd->channel_count, BYTES_PER_SAMPLE * 8,
+			   clock_rate * d_afd->frame_time_usec / 1000000);
+
+    rport->dn_port = dn_port;
+    rport->options = opt;
+
+    r_afd = pjmedia_format_get_audio_format_detail(&rport->base.info.fmt, 1);
+
+    /* Create buffers. 
+     * We need separate buffer for get_frame() and put_frame() since
+     * both functions may run simultaneously.
+     */
+    rport->get_buf = (pj_int16_t*)
+		     pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
+    PJ_ASSERT_RETURN(rport->get_buf != NULL, PJ_ENOMEM);
+
+    rport->put_buf = (pj_int16_t*)
+		     pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
+    PJ_ASSERT_RETURN(rport->put_buf != NULL, PJ_ENOMEM);
+
+
+    /* Create "get_frame" resample */
+    status = pjmedia_resample_create(pool, 
+				     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,
+				     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
+				     d_afd->channel_count,
+				     d_afd->clock_rate,
+				     r_afd->clock_rate,
+				     PJMEDIA_PIA_SPF(&dn_port->info),
+				     &rport->resample_get);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Create "put_frame" resample */
+    status = pjmedia_resample_create(pool, 
+				     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0, 
+				     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
+				     d_afd->channel_count,
+				     r_afd->clock_rate,
+				     d_afd->clock_rate,
+				     PJMEDIA_PIA_SPF(&rport->base.info),
+				     &rport->resample_put);
+
+    /* Media port interface */
+    rport->base.get_frame = &resample_get_frame;
+    rport->base.put_frame = &resample_put_frame;
+    rport->base.on_destroy = &resample_destroy;
+
+
+    /* Done */
+    *p_port = &rport->base;
+
+    return PJ_SUCCESS;
+}
+
+
+
+static pj_status_t resample_put_frame(pjmedia_port *this_port,
+				      pjmedia_frame *frame)
+{
+    struct resample_port *rport = (struct resample_port*) this_port;
+    pjmedia_frame downstream_frame;
+
+    /* Return if we don't have downstream port. */
+    if (rport->dn_port == NULL) {
+	return PJ_SUCCESS;
+    }
+
+    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
+	pjmedia_resample_run( rport->resample_put, 
+			      (const pj_int16_t*) frame->buf, 
+			      rport->put_buf);
+
+	downstream_frame.buf = rport->put_buf;
+	downstream_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);
+    } else {
+	downstream_frame.buf = frame->buf;
+	downstream_frame.size = frame->size;
+    }
+
+    downstream_frame.type = frame->type;
+    downstream_frame.timestamp.u64 = frame->timestamp.u64;
+
+    return pjmedia_port_put_frame( rport->dn_port, &downstream_frame );
+}
+
+
+
+static pj_status_t resample_get_frame(pjmedia_port *this_port, 
+				      pjmedia_frame *frame)
+{
+    struct resample_port *rport = (struct resample_port*) this_port;
+    pjmedia_frame tmp_frame;
+    pj_status_t status;
+
+    /* Return silence if we don't have downstream port */
+    if (rport->dn_port == NULL) {
+	pj_bzero(frame->buf, frame->size);
+	return PJ_SUCCESS;
+    }
+
+    tmp_frame.buf = rport->get_buf;
+    tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);
+    tmp_frame.timestamp.u64 = frame->timestamp.u64;
+    tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+    status = pjmedia_port_get_frame( rport->dn_port, &tmp_frame);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if (tmp_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	frame->type = tmp_frame.type;
+	frame->timestamp = tmp_frame.timestamp;
+	/* Copy whatever returned as long as the buffer size is enough */
+	frame->size = tmp_frame.size < PJMEDIA_PIA_AVG_FSZ(&rport->base.info) ?
+		      tmp_frame.size : PJMEDIA_PIA_AVG_FSZ(&rport->base.info);
+	if (tmp_frame.size) {
+	    pjmedia_copy_samples((pj_int16_t*)frame->buf, 
+				 (const pj_int16_t*)tmp_frame.buf, 
+				 (unsigned)frame->size >> 1);
+	}
+	return PJ_SUCCESS;
+    }
+
+    pjmedia_resample_run( rport->resample_get, 
+			  (const pj_int16_t*) tmp_frame.buf, 
+			  (pj_int16_t*) frame->buf);
+
+    frame->size = PJMEDIA_PIA_AVG_FSZ(&rport->base.info);
+    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+    return PJ_SUCCESS;
+}
+
+
+static pj_status_t resample_destroy(pjmedia_port *this_port)
+{
+    struct resample_port *rport = (struct resample_port*) this_port;
+
+    if ((rport->options & PJMEDIA_RESAMPLE_DONT_DESTROY_DN)==0) {
+	pjmedia_port_destroy(rport->dn_port);
+	rport->dn_port = NULL;
+    }
+
+    if (rport->resample_get) {
+	pjmedia_resample_destroy(rport->resample_get);
+	rport->resample_get = NULL;
+    }
+
+    if (rport->resample_put) {
+	pjmedia_resample_destroy(rport->resample_put);
+	rport->resample_put = NULL;
+    }
+
+    return PJ_SUCCESS;
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/39/393b184745dea2f2c15a355f413788f0bab43e14.svn-base b/jni/pjproject-android/.svn/pristine/39/393b184745dea2f2c15a355f413788f0bab43e14.svn-base
new file mode 100644
index 0000000..d9644e2
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/393b184745dea2f2c15a355f413788f0bab43e14.svn-base
@@ -0,0 +1,19 @@
+[Last Update: 2006/03/04]
+
+This directory contains two static libraries:
+ - pjmedia
+   The multimedia framework.
+
+ - pjmedia-codec
+   Codec collections.
+
+pjmedia has G711 codecs (Alaw and ULaw).
+
+pjmedia-codec has:
+ - GSM-FR implementation
+   Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+   Universitaet Berlin
+
+ - Speex 1.1.12
+   http://www.speex.org
+
diff --git a/jni/pjproject-android/.svn/pristine/39/3946511838b77bab13ff4badbb3194b7b280b102.svn-base b/jni/pjproject-android/.svn/pristine/39/3946511838b77bab13ff4badbb3194b7b280b102.svn-base
new file mode 100644
index 0000000..a5f407f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/3946511838b77bab13ff4badbb3194b7b280b102.svn-base
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------
+ *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*
+ *-------------------------------------------------------------------
+ *
+ *  A sample implementation of the example 3GPP authentication and
+ *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is
+ *  a byte-oriented implementation of the functions, and of the block
+ *  cipher kernel function Rijndael.
+ *
+ *  This has been coded for clarity, not necessarily for efficiency.
+ *
+ *  The functions f2, f3, f4 and f5 share the same inputs and have
+ *  been coded together as a single function.  f1, f1* and f5* are
+ *  all coded separately.
+ *
+ *-----------------------------------------------------------------*/
+
+#ifndef MILENAGE_H
+#define MILENAGE_H
+
+typedef unsigned char u8;
+
+
+void f1    ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
+             u8 mac_a[8], u8 op[16] );
+void f2345 ( u8 k[16], u8 rand[16],
+             u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] );
+void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
+             u8 mac_s[8], u8 op[16] );
+void f5star( u8 k[16], u8 rand[16],
+             u8 ak[6], u8 op[16] );
+void ComputeOPc( u8 op_c[16], u8 op[16] );
+
+
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/39/39625474ad5c006e4d1f9a9930d5717ee0665a77.svn-base b/jni/pjproject-android/.svn/pristine/39/39625474ad5c006e4d1f9a9930d5717ee0665a77.svn-base
new file mode 100644
index 0000000..33d12b1
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/39625474ad5c006e4d1f9a9930d5717ee0665a77.svn-base
@@ -0,0 +1,15 @@
+# $Id$
+import inc_sip as sip
+import inc_sdp as sdp
+
+pjsua = "--null-audio --id=sip:CLIENT --registrar sip:127.0.0.1:$PORT"
+
+req1 = sip.RecvfromTransaction("", 401,
+				include=["REGISTER sip"], 
+				exclude=["Authorization"],
+				resp_hdr=["WWW-Authenticate: Digest realm=\"python\", nonce=\"1234\""],
+				expect="PJSIP_ENOCREDENTIAL"
+			  )
+
+recvfrom_cfg = sip.RecvfromCfg("Failed registration test",
+			       pjsua, [req1])
diff --git a/jni/pjproject-android/.svn/pristine/39/397f6a8ea0aafa1486b9a9ccaece468dd72fa89a.svn-base b/jni/pjproject-android/.svn/pristine/39/397f6a8ea0aafa1486b9a9ccaece468dd72fa89a.svn-base
new file mode 100644
index 0000000..e8f8fdc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/397f6a8ea0aafa1486b9a9ccaece468dd72fa89a.svn-base
@@ -0,0 +1,41 @@
+/* $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 <pjmedia/rtp.h>
+#include <stdio.h>
+
+int rtp_test()
+{
+    pjmedia_rtp_session rtp;
+    FILE *fhnd = fopen("RTP.DAT", "wb");
+    const void *rtphdr;
+    int hdrlen;
+
+    if (!fhnd)
+	return -1;
+
+    pjmedia_rtp_session_init (&rtp, 4, 0x12345678);
+    pjmedia_rtp_encode_rtp (&rtp, 4, 0, 0, 160, &rtphdr, &hdrlen);
+    if (fwrite (rtphdr, hdrlen, 1, fhnd) != 1) {
+	fclose(fhnd);
+	return -1;
+    }
+    fclose(fhnd);
+    return 0;
+}
diff --git a/jni/pjproject-android/.svn/pristine/39/399de60db3b2c639d3ffee9632f88f64c7f751ba.svn-base b/jni/pjproject-android/.svn/pristine/39/399de60db3b2c639d3ffee9632f88f64c7f751ba.svn-base
new file mode 100644
index 0000000..e7e8c59
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/399de60db3b2c639d3ffee9632f88f64c7f751ba.svn-base
@@ -0,0 +1,511 @@
+/*
+ * aes_icm.c
+ *
+ * AES Integer Counter Mode
+ *
+ * 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.
+ *
+ */
+
+
+#define ALIGN_32 0
+
+#include "aes_icm.h"
+#include "alloc.h"
+
+
+debug_module_t mod_aes_icm = {
+  0,                 /* debugging is off by default */
+  "aes icm"          /* printable module name       */
+};
+
+/*
+ * integer counter mode works as follows:
+ *
+ * 16 bits
+ * <----->
+ * +------+------+------+------+------+------+------+------+ 
+ * |           nonce           |    pakcet index    |  ctr |---+
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   v
+ * |                      salt                      |000000|->(+)
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ *                                                        +---------+
+ *							  | encrypt |
+ *							  +---------+
+ *							       | 
+ * +------+------+------+------+------+------+------+------+   |
+ * |                    keystream block                    |<--+ 
+ * +------+------+------+------+------+------+------+------+   
+ *
+ * All fields are big-endian
+ *
+ * ctr is the block counter, which increments from zero for
+ * each packet (16 bits wide)
+ * 
+ * packet index is distinct for each packet (48 bits wide)
+ *
+ * nonce can be distinct across many uses of the same key, or
+ * can be a fixed value per key, or can be per-packet randomness
+ * (64 bits)
+ *
+ */
+
+err_status_t
+aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
+  extern cipher_type_t aes_icm;
+  uint8_t *pointer;
+  int tmp;
+
+  debug_print(mod_aes_icm, 
+            "allocating cipher with key length %d", key_len);
+
+  /*
+   * Ismacryp, for example, uses 16 byte key + 8 byte 
+   * salt  so this function is called with key_len = 24.
+   * The check for key_len = 30 does not apply. Our usage
+   * of aes functions with key_len = values other than 30
+   * has not broken anything. Don't know what would be the
+   * effect of skipping this check for srtp in general.
+   */
+  if (!forIsmacryp && key_len != 30)
+    return err_status_bad_param;
+
+  /* allocate memory a cipher of type aes_icm */
+  tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
+  pointer = (uint8_t*)crypto_alloc(tmp);
+  if (pointer == NULL) 
+    return err_status_alloc_fail;
+
+  /* set pointers */
+  *c = (cipher_t *)pointer;
+  (*c)->type = &aes_icm;
+  (*c)->state = pointer + sizeof(cipher_t);
+
+  /* increment ref_count */
+  aes_icm.ref_count++;
+
+  /* set key size        */
+  (*c)->key_len = key_len;
+
+  return err_status_ok;  
+}
+
+err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {
+  return aes_icm_alloc_ismacryp(c, key_len, 0);
+}
+
+err_status_t
+aes_icm_dealloc(cipher_t *c) {
+  extern cipher_type_t aes_icm;
+
+  /* zeroize entire state*/
+  octet_string_set_to_zero((uint8_t *)c, 
+			   sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
+
+  /* free memory */
+  crypto_free(c);
+
+  /* decrement ref_count */
+  aes_icm.ref_count--;
+  
+  return err_status_ok;  
+}
+
+
+/*
+ * aes_icm_context_init(...) initializes the aes_icm_context
+ * using the value in key[].
+ *
+ * the key is the secret key 
+ *
+ * the salt is unpredictable (but not necessarily secret) data which
+ * randomizes the starting point in the keystream
+ */
+
+err_status_t
+aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {
+  v128_t tmp_key;
+
+  /* set counter and initial values to 'offset' value */
+  /* FIX!!! this assumes the salt is at key + 16, and thus that the */
+  /* FIX!!! cipher key length is 16!  Also note this copies past the
+            end of the 'key' array by 2 bytes! */
+  v128_copy_octet_string(&c->counter, key + 16);
+  v128_copy_octet_string(&c->offset, key + 16);
+
+  /* force last two octets of the offset to zero (for srtp compatibility) */
+  c->offset.v8[14] = c->offset.v8[15] = 0;
+  c->counter.v8[14] = c->counter.v8[15] = 0;
+  
+  /* set tmp_key (for alignment) */
+  v128_copy_octet_string(&tmp_key, key);
+
+  debug_print(mod_aes_icm, 
+	      "key:  %s", v128_hex_string(&tmp_key)); 
+  debug_print(mod_aes_icm, 
+	      "offset: %s", v128_hex_string(&c->offset)); 
+
+  /* expand key */
+  aes_expand_encryption_key(&tmp_key, c->expanded_key);
+
+  /* indicate that the keystream_buffer is empty */
+  c->bytes_in_buffer = 0;
+
+  return err_status_ok;
+}
+
+/*
+ * aes_icm_set_octet(c, i) sets the counter of the context which it is
+ * passed so that the next octet of keystream that will be generated
+ * is the ith octet
+ */
+
+err_status_t
+aes_icm_set_octet(aes_icm_ctx_t *c,
+		  uint64_t octet_num) {
+
+#ifdef NO_64BIT_MATH
+  int tail_num       = low32(octet_num) & 0x0f;
+  /* 64-bit right-shift 4 */
+  uint64_t block_num = make64(high32(octet_num) >> 4,
+							  ((high32(octet_num) & 0x0f)<<(32-4)) |
+							   (low32(octet_num) >> 4));
+#else
+  int tail_num       = octet_num % 16;
+  uint64_t block_num = octet_num / 16;
+#endif
+  
+
+  /* set counter value */
+  /* FIX - There's no way this is correct */
+  c->counter.v64[0] = c->offset.v64[0];
+#ifdef NO_64BIT_MATH
+  c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
+							 low32(c->offset.v64[0])  ^ low32(block_num));
+#else
+  c->counter.v64[0] = c->offset.v64[0] ^ block_num;
+#endif
+
+  debug_print(mod_aes_icm, 
+	      "set_octet: %s", v128_hex_string(&c->counter)); 
+
+  /* fill keystream buffer, if needed */
+  if (tail_num) {
+    v128_copy(&c->keystream_buffer, &c->counter);
+    aes_encrypt(&c->keystream_buffer, c->expanded_key);
+    c->bytes_in_buffer = sizeof(v128_t);
+
+    debug_print(mod_aes_icm, "counter:    %s", 
+	      v128_hex_string(&c->counter));
+    debug_print(mod_aes_icm, "ciphertext: %s", 
+	      v128_hex_string(&c->keystream_buffer));    
+    
+    /*  indicate number of bytes in keystream_buffer  */
+    c->bytes_in_buffer = sizeof(v128_t) - tail_num;
+  
+  } else {
+    
+    /* indicate that keystream_buffer is empty */
+    c->bytes_in_buffer = 0;
+  }
+
+  return err_status_ok;
+}
+
+/*
+ * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+
+err_status_t
+aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
+  v128_t *nonce = (v128_t *) iv;
+
+  debug_print(mod_aes_icm, 
+	      "setting iv: %s", v128_hex_string(nonce)); 
+ 
+  v128_xor(&c->counter, &c->offset, nonce);
+  
+  debug_print(mod_aes_icm, 
+	      "set_counter: %s", v128_hex_string(&c->counter)); 
+
+  /* indicate that the keystream_buffer is empty */
+  c->bytes_in_buffer = 0;
+
+  return err_status_ok;
+}
+
+
+
+/*
+ * aes_icm_advance(...) refills the keystream_buffer and
+ * advances the block index of the sicm_context forward by one
+ *
+ * this is an internal, hopefully inlined function
+ */
+  
+static inline void
+aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
+  /* fill buffer with new keystream */
+  v128_copy(&c->keystream_buffer, &c->counter);
+  aes_encrypt(&c->keystream_buffer, c->expanded_key);
+  c->bytes_in_buffer = sizeof(v128_t);
+
+  debug_print(mod_aes_icm, "counter:    %s", 
+	      v128_hex_string(&c->counter));
+  debug_print(mod_aes_icm, "ciphertext: %s", 
+	      v128_hex_string(&c->keystream_buffer));    
+  
+  /* clock counter forward */
+
+  if (forIsmacryp) {
+    uint32_t temp;    
+    //alex's clock counter forward
+    temp = ntohl(c->counter.v32[3]);
+    c->counter.v32[3] = htonl(++temp);
+  } else {
+    if (!++(c->counter.v8[15])) 
+      ++(c->counter.v8[14]);
+  }
+}
+
+inline void aes_icm_advance(aes_icm_ctx_t *c) {
+  aes_icm_advance_ismacryp(c, 0);
+}
+
+
+/*e
+ * icm_encrypt deals with the following cases:
+ *
+ * bytes_to_encr < bytes_in_buffer
+ *  - add keystream into data
+ *
+ * bytes_to_encr > bytes_in_buffer
+ *  - add keystream into data until keystream_buffer is depleted
+ *  - loop over blocks, filling keystream_buffer and then
+ *    adding keystream into data
+ *  - fill buffer then add in remaining (< 16) bytes of keystream 
+ */
+
+err_status_t
+aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
+              unsigned char *buf, unsigned int *enc_len, 
+              int forIsmacryp) {
+  unsigned int bytes_to_encr = *enc_len;
+  unsigned int i;
+  uint32_t *b;
+
+  /* check that there's enough segment left but not for ismacryp*/
+  if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
+    return err_status_terminus;
+
+ debug_print(mod_aes_icm, "block index: %d", 
+           htons(c->counter.v16[7]));
+  if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
+    
+    /* deal with odd case of small bytes_to_encr */
+    for (i = (sizeof(v128_t) - c->bytes_in_buffer);
+		 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) 
+	{
+      *buf++ ^= c->keystream_buffer.v8[i];
+	}
+
+    c->bytes_in_buffer -= bytes_to_encr;
+
+    /* return now to avoid the main loop */
+    return err_status_ok;
+
+  } else {
+    
+    /* encrypt bytes until the remaining data is 16-byte aligned */    
+    for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) 
+      *buf++ ^= c->keystream_buffer.v8[i];
+
+    bytes_to_encr -= c->bytes_in_buffer;
+    c->bytes_in_buffer = 0;
+
+  }
+  
+  /* now loop over entire 16-byte blocks of keystream */
+  for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
+
+    /* fill buffer with new keystream */
+    aes_icm_advance_ismacryp(c, forIsmacryp);
+
+    /*
+     * add keystream into the data buffer (this would be a lot faster
+     * if we could assume 32-bit alignment!)
+     */
+
+#if ALIGN_32
+    b = (uint32_t *)buf;
+    *b++ ^= c->keystream_buffer.v32[0];
+    *b++ ^= c->keystream_buffer.v32[1];
+    *b++ ^= c->keystream_buffer.v32[2];
+    *b++ ^= c->keystream_buffer.v32[3];
+    buf = (uint8_t *)b;
+#else    
+    if ((((unsigned long) buf) & 0x03) != 0) {
+      *buf++ ^= c->keystream_buffer.v8[0];
+      *buf++ ^= c->keystream_buffer.v8[1];
+      *buf++ ^= c->keystream_buffer.v8[2];
+      *buf++ ^= c->keystream_buffer.v8[3];
+      *buf++ ^= c->keystream_buffer.v8[4];
+      *buf++ ^= c->keystream_buffer.v8[5];
+      *buf++ ^= c->keystream_buffer.v8[6];
+      *buf++ ^= c->keystream_buffer.v8[7];
+      *buf++ ^= c->keystream_buffer.v8[8];
+      *buf++ ^= c->keystream_buffer.v8[9];
+      *buf++ ^= c->keystream_buffer.v8[10];
+      *buf++ ^= c->keystream_buffer.v8[11];
+      *buf++ ^= c->keystream_buffer.v8[12];
+      *buf++ ^= c->keystream_buffer.v8[13];
+      *buf++ ^= c->keystream_buffer.v8[14];
+      *buf++ ^= c->keystream_buffer.v8[15];
+    } else {
+      b = (uint32_t *)buf;
+      *b++ ^= c->keystream_buffer.v32[0];
+      *b++ ^= c->keystream_buffer.v32[1];
+      *b++ ^= c->keystream_buffer.v32[2];
+      *b++ ^= c->keystream_buffer.v32[3];
+      buf = (uint8_t *)b;
+    }
+#endif /* #if ALIGN_32 */
+
+  }
+  
+  /* if there is a tail end of the data, process it */
+  if ((bytes_to_encr & 0xf) != 0) {
+    
+    /* fill buffer with new keystream */
+    aes_icm_advance_ismacryp(c, forIsmacryp);
+    
+    for (i=0; i < (bytes_to_encr & 0xf); i++)
+      *buf++ ^= c->keystream_buffer.v8[i];
+    
+    /* reset the keystream buffer size to right value */
+    c->bytes_in_buffer = sizeof(v128_t) - i;  
+  } else {
+
+    /* no tail, so just reset the keystream buffer size to zero */
+    c->bytes_in_buffer = 0;
+
+  }
+
+  return err_status_ok;
+}
+
+err_status_t
+aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
+  return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
+}
+
+err_status_t
+aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
+  unsigned int len = num_octets_to_output;
+  
+  /* zeroize the buffer */
+  octet_string_set_to_zero(buffer, num_octets_to_output);
+  
+  /* exor keystream into buffer */
+  return aes_icm_encrypt(c, buffer, &len);
+}
+
+
+char 
+aes_icm_description[] = "aes integer counter mode";
+
+uint8_t aes_icm_test_case_0_key[30] = {
+  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+
+uint8_t aes_icm_test_case_0_nonce[16] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t aes_icm_test_case_0_plaintext[32] =  {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+};
+
+uint8_t aes_icm_test_case_0_ciphertext[32] = {
+  0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+  0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+  0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+  0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
+};
+
+cipher_test_case_t aes_icm_test_case_0 = {
+  30,                                    /* octets in key            */
+  aes_icm_test_case_0_key,               /* key                      */
+  aes_icm_test_case_0_nonce,             /* packet index             */
+  32,                                    /* octets in plaintext      */
+  aes_icm_test_case_0_plaintext,         /* plaintext                */
+  32,                                    /* octets in ciphertext     */
+  aes_icm_test_case_0_ciphertext,        /* ciphertext               */
+  NULL                                   /* pointer to next testcase */
+};
+
+
+/*
+ * note: the encrypt function is identical to the decrypt function
+ */
+
+cipher_type_t aes_icm = {
+  (cipher_alloc_func_t)          aes_icm_alloc,
+  (cipher_dealloc_func_t)        aes_icm_dealloc,  
+  (cipher_init_func_t)           aes_icm_context_init,
+  (cipher_encrypt_func_t)        aes_icm_encrypt,
+  (cipher_decrypt_func_t)        aes_icm_encrypt,
+  (cipher_set_iv_func_t)         aes_icm_set_iv,
+  (char *)                       aes_icm_description,
+  (int)                          0,   /* instance count */
+  (cipher_test_case_t *)        &aes_icm_test_case_0,
+  (debug_module_t *)            &mod_aes_icm
+};
+
diff --git a/jni/pjproject-android/.svn/pristine/39/39c04e9489084beb2e876aba54eeecaa75e959e0.svn-base b/jni/pjproject-android/.svn/pristine/39/39c04e9489084beb2e876aba54eeecaa75e959e0.svn-base
new file mode 100644
index 0000000..9132319
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/39c04e9489084beb2e876aba54eeecaa75e959e0.svn-base
@@ -0,0 +1,87 @@
+
+
+
+              Build Instructions for PJLIB/PJMEDIA/PJSIP RTEMS Port
+
+
+
+The RTEMS port uses the POSIX abstraction layer at the moment, and has been 
+tested with RTEMS 4.6 on i386 target.
+
+
+Building RTEMS
+---------------
+I use RTEMS 4.6 on a cygwin host with i386/pc386 as target, but I think it 
+should work with different RTEMS versions/hosts/targets. 
+
+RTEMS was built with the following commands:
+
+  $ /opt/src/rtems-4.6.6/configure --enable-cxx --enable-posix --enable-networking --enable-rdbg --enable-tests --enable-rtemsbsp=pc386 --target=i386-rtems
+  $ make
+  $ make install
+
+
+Supported Targets
+-----------------
+At the moment, pjlib supports i386 and mpc860 CPU target. For other targets, 
+you would need to create/tweak the appropriate "m-xxx.mak" in "build" directory
+and the corresponding "m_xxx.h" header file in "pj/compat" directory.
+
+Please refer to pjlib porting guide about how to port PJLIB to new CPU target.
+
+
+Building PJLIB/PJMEDIA/PJSIP
+----------------------------
+Use the following steps to build the libraries:
+
+
+1. Set RTEMS_LIBRARY_PATH environment variable to point to your BSP directory 
+   (which is <RTEMS INSTALLATION POINT>/<BOARD SUPPORT PACKAGE>). 
+
+   For example (with sh):
+ 
+   $ export RTEMS_LIBRARY_PATH=/opt/rtems-4.6/i386-rtems/pc386
+
+
+2. Unfortunately pjproject's configure script is unable to create "build.mak" 
+   for cross compilation (but this may change in the future), so we need to 
+   create "build.mak" manually.
+
+   The file "README-configure" has some info about the variables in "build.mak".
+
+   For example, the "build.mak" for i386 target:
+
+   export MACHINE_NAME := i386
+   export OS_NAME := rtems
+   export HOST_NAME := mingw
+   export CC_NAME := gcc
+   export TARGET_NAME := i386-rtems
+   export CROSS_COMPILE := i386-rtems-
+
+
+3. Put additional CFLAGS or LDFLAGS that are specific to your target in 
+   "user.mak".
+
+   For example, my "user.mak" looks like this:
+
+   export CFLAGS += 
+   export LDFLAGS += -Wl,-Ttext,0x00100000 -Wl,--defsym -Wl,HeapSize=0x400000
+
+
+4. Build the libraries:
+
+   $ make dep && make distclean && make
+
+
+5. That should be it. The libraries should be in "lib" directory and 
+   applications in "bin" directory.
+
+
+
+Acknowledgements
+----------------
+Many thanks for Phil Torre <ptorre at zetron dot com>, who did most of the 
+initial porting and testing with pjlib etc. All credits go to him.
+
+
+
diff --git a/jni/pjproject-android/.svn/pristine/39/39ec95514f79760d3c7c66096bbf0698a7dbf81e.svn-base b/jni/pjproject-android/.svn/pristine/39/39ec95514f79760d3c7c66096bbf0698a7dbf81e.svn-base
new file mode 100644
index 0000000..5f32bb3
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/39ec95514f79760d3c7c66096bbf0698a7dbf81e.svn-base
Binary files differ
diff --git a/jni/pjproject-android/.svn/pristine/39/39f4f18650c453f2f2e3cd1917b920929210696e.svn-base b/jni/pjproject-android/.svn/pristine/39/39f4f18650c453f2f2e3cd1917b920929210696e.svn-base
new file mode 100644
index 0000000..4ccce9f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/39/39f4f18650c453f2f2e3cd1917b920929210696e.svn-base
@@ -0,0 +1,843 @@
+/* $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 <pjmedia-audiodev/audiodev_imp.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+#define THIS_FILE   "audiodev.c"
+
+#define DEFINE_CAP(name, info)	{name, info}
+
+/* Capability names */
+static struct cap_info
+{
+    const char *name;
+    const char *info;
+} cap_infos[] = 
+{
+    DEFINE_CAP("ext-fmt",     "Extended/non-PCM format"),
+    DEFINE_CAP("latency-in",  "Input latency/buffer size setting"),
+    DEFINE_CAP("latency-out", "Output latency/buffer size setting"),
+    DEFINE_CAP("vol-in",      "Input volume setting"),
+    DEFINE_CAP("vol-out",     "Output volume setting"),
+    DEFINE_CAP("meter-in",    "Input meter"),
+    DEFINE_CAP("meter-out",   "Output meter"),
+    DEFINE_CAP("route-in",    "Input routing"),
+    DEFINE_CAP("route-out",   "Output routing"),
+    DEFINE_CAP("aec",	      "Accoustic echo cancellation"),
+    DEFINE_CAP("aec-tail",    "Tail length setting for AEC"),
+    DEFINE_CAP("vad",	      "Voice activity detection"),
+    DEFINE_CAP("cng",	      "Comfort noise generation"),
+    DEFINE_CAP("plg",	      "Packet loss concealment")
+};
+
+
+/*
+ * The device index seen by application and driver is different. 
+ *
+ * At application level, device index is index to global list of device.
+ * At driver level, device index is index to device list on that particular
+ * factory only.
+ */
+#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
+#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
+#define GET_FID(dev_id)		   ((dev_id) >> 16)
+#define DEFAULT_DEV_ID		    0
+
+
+/* extern functions to create factories */
+#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
+pjmedia_aud_dev_factory* pjmedia_pa_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
+pjmedia_aud_dev_factory* pjmedia_coreaudio_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_ALSA
+pjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_OPENSL
+pjmedia_aud_dev_factory* pjmedia_opensl_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI
+pjmedia_aud_dev_factory* pjmedia_android_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_BB10
+pjmedia_aud_dev_factory* pjmedia_bb10_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_WMME
+pjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
+pjmedia_aud_dev_factory* pjmedia_bdimad_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
+pjmedia_aud_dev_factory* pjmedia_symb_vas_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
+pjmedia_aud_dev_factory* pjmedia_aps_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
+pjmedia_aud_dev_factory* pjmedia_symb_mda_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
+pjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf);
+#endif
+
+#define MAX_DRIVERS	16
+#define MAX_DEVS	64
+
+
+/* driver structure */
+struct driver
+{
+    /* Creation function */
+    pjmedia_aud_dev_factory_create_func_ptr create;
+    /* Factory instance */
+    pjmedia_aud_dev_factory *f;
+    char		     name[32];	/* Driver name			    */
+    unsigned		     dev_cnt;	/* Number of devices		    */
+    unsigned		     start_idx;	/* Start index in global list	    */
+    int			     rec_dev_idx;/* Default capture device.	    */
+    int			     play_dev_idx;/* Default playback device	    */
+    int			     dev_idx;	/* Default device.		    */
+};
+
+/* The audio subsystem */
+static struct aud_subsys
+{
+    unsigned	     init_count;	/* How many times init() is called  */
+    pj_pool_factory *pf;		/* The pool factory.		    */
+
+    unsigned	     drv_cnt;		/* Number of drivers.		    */
+    struct driver    drv[MAX_DRIVERS];	/* Array of drivers.		    */
+
+    unsigned	     dev_cnt;		/* Total number of devices.	    */
+    pj_uint32_t	     dev_list[MAX_DEVS];/* Array of device IDs.		    */
+
+} aud_subsys;
+
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					     const char **p_desc)
+{
+    const char *desc;
+    unsigned i;
+
+    if (p_desc==NULL) p_desc = &desc;
+
+    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
+	if ((1 << i)==cap)
+	    break;
+    }
+
+    if (i==PJ_ARRAY_SIZE(cap_infos)) {
+	*p_desc = "??";
+	return "??";
+    }
+
+    *p_desc = cap_infos[i].info;
+    return cap_infos[i].name;
+}
+
+static pj_status_t get_cap_pointer(const pjmedia_aud_param *param,
+				   pjmedia_aud_dev_cap cap,
+				   void **ptr,
+				   unsigned *size)
+{
+#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
+			    *size = sizeof(param->name)
+
+    switch (cap) {
+    case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT:
+	FIELD_INFO(ext_fmt);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY:
+	FIELD_INFO(input_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY:
+	FIELD_INFO(output_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
+	FIELD_INFO(input_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
+	FIELD_INFO(output_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE:
+	FIELD_INFO(input_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
+	FIELD_INFO(output_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC:
+	FIELD_INFO(ec_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC_TAIL:
+	FIELD_INFO(ec_tail_ms);
+	break;
+    /* vad is no longer in "fmt" in 2.0.
+    case PJMEDIA_AUD_DEV_CAP_VAD:
+	FIELD_INFO(ext_fmt.vad);
+	break;
+    */
+    case PJMEDIA_AUD_DEV_CAP_CNG:
+	FIELD_INFO(cng_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_PLC:
+	FIELD_INFO(plc_enabled);
+	break;
+    default:
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+#undef FIELD_INFO
+
+    return PJ_SUCCESS;
+}
+
+/* API: set cap value to param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       const void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_memcpy(cap_ptr, pval, cap_size);
+    param->flags |= cap;
+
+    return PJ_SUCCESS;
+}
+
+/* API: get cap value from param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if ((param->flags & cap) == 0) {
+	pj_bzero(cap_ptr, cap_size);
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+    pj_memcpy(pval, cap_ptr, cap_size);
+    return PJ_SUCCESS;
+}
+
+/* Internal: init driver */
+static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
+{
+    struct driver *drv = &aud_subsys.drv[drv_idx];
+    pjmedia_aud_dev_factory *f;
+    unsigned i, dev_cnt;
+    pj_status_t status;
+
+    if (!refresh) {
+	/* Create the factory */
+	f = (*drv->create)(aud_subsys.pf);
+	if (!f)
+	    return PJ_EUNKNOWN;
+
+	/* Call factory->init() */
+	status = f->op->init(f);
+	if (status != PJ_SUCCESS) {
+	    f->op->destroy(f);
+	    return status;
+	}
+    } else {
+	f = drv->f;
+    }
+
+    /* Get number of devices */
+    dev_cnt = f->op->get_dev_count(f);
+    if (dev_cnt + aud_subsys.dev_cnt > MAX_DEVS) {
+	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
+			      " there are too many devices",
+			      aud_subsys.dev_cnt + dev_cnt - MAX_DEVS));
+	dev_cnt = MAX_DEVS - aud_subsys.dev_cnt;
+    }
+
+    /* enabling this will cause pjsua-lib initialization to fail when there
+     * is no sound device installed in the system, even when pjsua has been
+     * run with --null-audio
+     *
+    if (dev_cnt == 0) {
+	f->op->destroy(f);
+	return PJMEDIA_EAUD_NODEV;
+    }
+    */
+
+    /* Fill in default devices */
+    drv->play_dev_idx = drv->rec_dev_idx = drv->dev_idx = -1;
+    for (i=0; i<dev_cnt; ++i) {
+	pjmedia_aud_dev_info info;
+
+	status = f->op->get_dev_info(f, i, &info);
+	if (status != PJ_SUCCESS) {
+	    f->op->destroy(f);
+	    return status;
+	}
+
+	if (drv->name[0]=='\0') {
+	    /* Set driver name */
+	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
+	    drv->name[sizeof(drv->name)-1] = '\0';
+	}
+
+	if (drv->play_dev_idx < 0 && info.output_count) {
+	    /* Set default playback device */
+	    drv->play_dev_idx = i;
+	}
+	if (drv->rec_dev_idx < 0 && info.input_count) {
+	    /* Set default capture device */
+	    drv->rec_dev_idx = i;
+	}
+	if (drv->dev_idx < 0 && info.input_count &&
+	    info.output_count)
+	{
+	    /* Set default capture and playback device */
+	    drv->dev_idx = i;
+	}
+
+	if (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0 && 
+	    drv->dev_idx >= 0) 
+	{
+	    /* Done. */
+	    break;
+	}
+    }
+
+    /* Register the factory */
+    drv->f = f;
+    drv->f->sys.drv_idx = drv_idx;
+    drv->start_idx = aud_subsys.dev_cnt;
+    drv->dev_cnt = dev_cnt;
+
+    /* Register devices to global list */
+    for (i=0; i<dev_cnt; ++i) {
+	aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Internal: deinit driver */
+static void deinit_driver(unsigned drv_idx)
+{
+    struct driver *drv = &aud_subsys.drv[drv_idx];
+
+    if (drv->f) {
+	drv->f->op->destroy(drv->f);
+	drv->f = NULL;
+    }
+
+    drv->dev_cnt = 0;
+    drv->play_dev_idx = drv->rec_dev_idx = drv->dev_idx = -1;
+}
+
+/* API: Initialize the audio subsystem. */
+PJ_DEF(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf)
+{
+    unsigned i;
+    pj_status_t status;
+
+    /* Allow init() to be called multiple times as long as there is matching
+     * number of shutdown().
+     */
+    if (aud_subsys.init_count++ != 0) {
+	return PJ_SUCCESS;
+    }
+
+    /* Register error subsystem */
+    status = pj_register_strerror(PJMEDIA_AUDIODEV_ERRNO_START, 
+				  PJ_ERRNO_SPACE_SIZE, 
+				  &pjmedia_audiodev_strerror);
+    pj_assert(status == PJ_SUCCESS);
+
+    /* Init */
+    aud_subsys.pf = pf;
+    aud_subsys.drv_cnt = 0;
+    aud_subsys.dev_cnt = 0;
+
+    /* Register creation functions */
+#if PJMEDIA_AUDIO_DEV_HAS_OPENSL
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_opensl_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_android_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_BB10
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bb10_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_ALSA
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_alsa_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_coreaudio_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_pa_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_WMME
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bdimad_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_vas_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_aps_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_mda_factory;
+#endif
+#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
+    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory;
+#endif
+
+    /* Initialize each factory and build the device ID list */
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	status = init_driver(i, PJ_FALSE);
+	if (status != PJ_SUCCESS) {
+	    deinit_driver(i);
+	    continue;
+	}
+    }
+
+    return aud_subsys.dev_cnt ? PJ_SUCCESS : status;
+}
+
+/* API: register an audio device factory to the audio subsystem. */
+PJ_DEF(pj_status_t)
+pjmedia_aud_register_factory(pjmedia_aud_dev_factory_create_func_ptr adf)
+{
+    pj_status_t status;
+
+    if (aud_subsys.init_count == 0)
+	return PJMEDIA_EAUD_INIT;
+
+    aud_subsys.drv[aud_subsys.drv_cnt].create = adf;
+    status = init_driver(aud_subsys.drv_cnt, PJ_FALSE);
+    if (status == PJ_SUCCESS) {
+	aud_subsys.drv_cnt++;
+    } else {
+	deinit_driver(aud_subsys.drv_cnt);
+    }
+
+    return status;
+}
+
+/* API: unregister an audio device factory from the audio subsystem. */
+PJ_DEF(pj_status_t)
+pjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf)
+{
+    unsigned i, j;
+
+    if (aud_subsys.init_count == 0)
+	return PJMEDIA_EAUD_INIT;
+
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	struct driver *drv = &aud_subsys.drv[i];
+
+	if (drv->create == adf) {
+	    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
+	    {
+		aud_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV;
+	    }
+
+	    deinit_driver(i);
+	    pj_bzero(drv, sizeof(*drv));
+	    return PJ_SUCCESS;
+	}
+    }
+
+    return PJMEDIA_EAUD_ERR;
+}
+
+/* API: get the pool factory registered to the audio subsystem. */
+PJ_DEF(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void)
+{
+    return aud_subsys.pf;
+}
+
+/* API: Shutdown the audio subsystem. */
+PJ_DEF(pj_status_t) pjmedia_aud_subsys_shutdown(void)
+{
+    unsigned i;
+
+    /* Allow shutdown() to be called multiple times as long as there is matching
+     * number of init().
+     */
+    if (aud_subsys.init_count == 0) {
+	return PJ_SUCCESS;
+    }
+    --aud_subsys.init_count;
+
+    if (aud_subsys.init_count == 0) {
+	for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	    deinit_driver(i);
+	}
+
+	aud_subsys.pf = NULL;
+    }
+    return PJ_SUCCESS;
+}
+
+/* API: Refresh the list of sound devices installed in the system. */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void)
+{
+    unsigned i;
+    
+    aud_subsys.dev_cnt = 0;
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	struct driver *drv = &aud_subsys.drv[i];
+	
+	if (drv->f && drv->f->op->refresh) {
+	    pj_status_t status = drv->f->op->refresh(drv->f);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device "
+						 "list for %s", drv->name));
+	    }
+	}
+	init_driver(i, PJ_TRUE);
+    }
+    return PJ_SUCCESS;
+}
+
+/* API: Get the number of sound devices installed in the system. */
+PJ_DEF(unsigned) pjmedia_aud_dev_count(void)
+{
+    return aud_subsys.dev_cnt;
+}
+
+/* Internal: convert local index to global device index */
+static pj_status_t make_global_index(unsigned drv_idx, 
+				     pjmedia_aud_dev_index *id)
+{
+    if (*id < 0) {
+	return PJ_SUCCESS;
+    }
+
+    /* Check that factory still exists */
+    PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG);
+
+    /* Check that device index is valid */
+    PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt, 
+		     PJ_EBUG);
+
+    *id += aud_subsys.drv[drv_idx].start_idx;
+    return PJ_SUCCESS;
+}
+
+/* Internal: lookup device id */
+static pj_status_t lookup_dev(pjmedia_aud_dev_index id,
+			      pjmedia_aud_dev_factory **p_f,
+			      unsigned *p_local_index)
+{
+    int f_id, index;
+
+    if (id < 0) {
+	unsigned i;
+
+	if (id == PJMEDIA_AUD_INVALID_DEV)
+	    return PJMEDIA_EAUD_INVDEV;
+
+	for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	    struct driver *drv = &aud_subsys.drv[i];
+	    if (drv->dev_idx >= 0) {
+		id = drv->dev_idx;
+		make_global_index(i, &id);
+		break;
+	    } else if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV && 
+		drv->rec_dev_idx >= 0) 
+	    {
+		id = drv->rec_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV && 
+		drv->play_dev_idx >= 0) 
+	    {
+		id = drv->play_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    }
+	}
+
+	if (id < 0) {
+	    return PJMEDIA_EAUD_NODEFDEV;
+	}
+    }
+
+    f_id = GET_FID(aud_subsys.dev_list[id]);
+    index = GET_INDEX(aud_subsys.dev_list[id]);
+
+    if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    *p_f = aud_subsys.drv[f_id].f;
+    *p_local_index = (unsigned)index;
+
+    return PJ_SUCCESS;
+
+}
+
+/* API: Get device information. */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
+					     pjmedia_aud_dev_info *info)
+{
+    pjmedia_aud_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return f->op->get_dev_info(f, index, info);
+}
+
+/* API: find device */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,
+					    const char *dev_name,
+					    pjmedia_aud_dev_index *id)
+{
+    pjmedia_aud_dev_factory *f = NULL;
+    unsigned drv_idx, dev_idx;
+
+    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) {
+	if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) {
+	    f = aud_subsys.drv[drv_idx].f;
+	    break;
+	}
+    }
+
+    if (!f)
+	return PJ_ENOTFOUND;
+
+    for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) {
+	pjmedia_aud_dev_info info;
+	pj_status_t status;
+
+	status = f->op->get_dev_info(f, dev_idx, &info);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (!pj_ansi_stricmp(dev_name, info.name))
+	    break;
+    }
+
+    if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt)
+	return PJ_ENOTFOUND;
+
+    *id = dev_idx;
+    make_global_index(drv_idx, id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Initialize the audio device parameters with default values for the
+ * specified device.
+ */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+						  pjmedia_aud_param *param)
+{
+    pjmedia_aud_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = f->op->default_param(f, index, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device IDs */
+    make_global_index(f->sys.drv_idx, &param->rec_id);
+    make_global_index(f->sys.drv_idx, &param->play_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Open audio stream object using the specified parameters. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm,
+					      pjmedia_aud_rec_cb rec_cb,
+					      pjmedia_aud_play_cb play_cb,
+					      void *user_data,
+					      pjmedia_aud_stream **p_aud_strm)
+{
+    pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL;
+    pjmedia_aud_param param;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
+		     prm->dir==PJMEDIA_DIR_PLAYBACK ||
+		     prm->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK,
+		     PJ_EINVAL);
+
+    /* Must make copy of param because we're changing device ID */
+    pj_memcpy(&param, prm, sizeof(param));
+
+    /* Normalize rec_id */
+    if (param.dir & PJMEDIA_DIR_CAPTURE) {
+	unsigned index;
+
+	if (param.rec_id < 0)
+	    param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+
+	status = lookup_dev(param.rec_id, &rec_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.rec_id = index;
+	f = rec_f;
+    }
+
+    /* Normalize play_id */
+    if (param.dir & PJMEDIA_DIR_PLAYBACK) {
+	unsigned index;
+
+	if (param.play_id < 0)
+	    param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+
+	status = lookup_dev(param.play_id, &play_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.play_id = index;
+	f = play_f;
+    }
+
+    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
+
+    /* For now, rec_id and play_id must belong to the same factory */
+    PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_PLAYBACK) || 
+		     (rec_f == play_f),
+		     PJMEDIA_EAUD_INVDEV);
+
+    /* Create the stream */
+    status = f->op->create_stream(f, &param, rec_cb, play_cb,
+				  user_data, p_aud_strm);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Assign factory id to the stream */
+    (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx;
+    return PJ_SUCCESS;
+}
+
+/* API: Get the running parameters for the specified audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
+						 pjmedia_aud_param *param)
+{
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = strm->op->get_param(strm, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device id's */
+    make_global_index(strm->sys.drv_idx, &param->rec_id);
+    make_global_index(strm->sys.drv_idx, &param->play_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Get the value of a specific capability of the audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
+					       pjmedia_aud_dev_cap cap,
+					       void *value)
+{
+    return strm->op->get_cap(strm, cap, value);
+}
+
+/* API: Set the value of a specific capability of the audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
+					       pjmedia_aud_dev_cap cap,
+					       const void *value)
+{
+    return strm->op->set_cap(strm, cap, value);
+}
+
+/* API: Start the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm)
+{
+    return strm->op->start(strm);
+}
+
+/* API: Stop the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm)
+{
+    return strm->op->stop(strm);
+}
+
+/* API: Destroy the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm)
+{
+    return strm->op->destroy(strm);
+}
+
+