* #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*)¶m->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, ¶m->rec_id);
+ make_global_index(f->sys.drv_idx, ¶m->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(¶m, 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, ¶m, 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, ¶m->rec_id);
+ make_global_index(strm->sys.drv_idx, ¶m->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);
+}
+
+