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

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/.svn/pristine/c0/c010b202e72fc19904befc46db5996a505b03bce.svn-base b/jni/pjproject-android/.svn/pristine/c0/c010b202e72fc19904befc46db5996a505b03bce.svn-base
new file mode 100644
index 0000000..ec4b0fd
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c010b202e72fc19904befc46db5996a505b03bce.svn-base
@@ -0,0 +1,23 @@
+# $Id$
+import inc_sip as sip
+import inc_sdp as sdp
+
+sdp = \
+"""
+v=0
+o=- 0 0 IN IP4 127.0.0.1
+s=pjmedia
+c=IN IP4 127.0.0.1
+t=0 0
+m=audio 4000 RTP/AVP 0
+"""
+
+pjsua_args = "--null-audio --auto-answer 200"
+extra_headers = "Replaces: abcd;from_tag=1\r\nReplaces: efgh;from_tag=2\r\n"
+include = []
+exclude = []
+
+sendto_cfg = sip.SendtoCfg("Duplicate replaces header", pjsua_args, sdp, 400,
+			   extra_headers=extra_headers,
+			   resp_inc=include, resp_exc=exclude) 
+
diff --git a/jni/pjproject-android/.svn/pristine/c0/c03bf19e26731344e6f1a85d9b9368ff93017c5c.svn-base b/jni/pjproject-android/.svn/pristine/c0/c03bf19e26731344e6f1a85d9b9368ff93017c5c.svn-base
new file mode 100644
index 0000000..252f7fc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c03bf19e26731344e6f1a85d9b9368ff93017c5c.svn-base
@@ -0,0 +1,1932 @@
+/* $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 
+ */
+/*
+ * Contributors:
+ * - Thanks for Zetron, Inc. (Phil Torre, ptorre@zetron.com) for donating
+ *   the RTEMS port.
+ */
+#ifndef _GNU_SOURCE
+#   define _GNU_SOURCE
+#endif
+#include <pj/os.h>
+#include <pj/assert.h>
+#include <pj/pool.h>
+#include <pj/log.h>
+#include <pj/rand.h>
+#include <pj/string.h>
+#include <pj/guid.h>
+#include <pj/except.h>
+#include <pj/errno.h>
+
+#if defined(PJ_HAS_SEMAPHORE_H) && PJ_HAS_SEMAPHORE_H != 0
+#  include <semaphore.h>
+#endif
+
+#include <unistd.h>	    // getpid()
+#include <errno.h>	    // errno
+
+#include <pthread.h>
+
+#define THIS_FILE   "os_core_unix.c"
+
+#define SIGNATURE1  0xDEAFBEEF
+#define SIGNATURE2  0xDEADC0DE
+
+struct pj_thread_t
+{
+    char	    obj_name[PJ_MAX_OBJ_NAME];
+    pthread_t	    thread;
+    pj_thread_proc *proc;
+    void	   *arg;
+    pj_uint32_t	    signature1;
+    pj_uint32_t	    signature2;
+
+    pj_mutex_t	   *suspended_mutex;
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    pj_uint32_t	    stk_size;
+    pj_uint32_t	    stk_max_usage;
+    char	   *stk_start;
+    const char	   *caller_file;
+    int		    caller_line;
+#endif
+};
+
+struct pj_atomic_t
+{
+    pj_mutex_t	       *mutex;
+    pj_atomic_value_t	value;
+};
+
+struct pj_mutex_t
+{
+    pthread_mutex_t     mutex;
+    char		obj_name[PJ_MAX_OBJ_NAME];
+#if PJ_DEBUG
+    int		        nesting_level;
+    pj_thread_t	       *owner;
+    char		owner_name[PJ_MAX_OBJ_NAME];
+#endif
+};
+
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+struct pj_sem_t
+{
+    sem_t	       *sem;
+    char		obj_name[PJ_MAX_OBJ_NAME];
+};
+#endif /* PJ_HAS_SEMAPHORE */
+
+#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
+struct pj_event_t
+{
+    enum event_state {
+	EV_STATE_OFF,
+	EV_STATE_SET,
+	EV_STATE_PULSED
+    } state;
+
+    pj_mutex_t		mutex;
+    pthread_cond_t	cond;
+
+    pj_bool_t		auto_reset;
+    unsigned		threads_waiting;
+    unsigned		threads_to_release;
+};
+#endif	/* PJ_HAS_EVENT_OBJ */
+
+
+/*
+ * Flag and reference counter for PJLIB instance.
+ */
+static int initialized;
+
+#if PJ_HAS_THREADS
+    static pj_thread_t main_thread;
+    static long thread_tls_id;
+    static pj_mutex_t critical_section;
+#else
+#   define MAX_THREADS 32
+    static int tls_flag[MAX_THREADS];
+    static void *tls[MAX_THREADS];
+#endif
+
+static unsigned atexit_count;
+static void (*atexit_func[32])(void);
+
+static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type);
+
+/*
+ * pj_init(void).
+ * Init PJLIB!
+ */
+PJ_DEF(pj_status_t) pj_init(void)
+{
+    char dummy_guid[PJ_GUID_MAX_LENGTH];
+    pj_str_t guid;
+    pj_status_t rc;
+
+    /* Check if PJLIB have been initialized */
+    if (initialized) {
+	++initialized;
+	return PJ_SUCCESS;
+    }
+
+#if PJ_HAS_THREADS
+    /* Init this thread's TLS. */
+    if ((rc=pj_thread_init()) != 0) {
+	return rc;
+    }
+
+    /* Critical section. */
+    if ((rc=init_mutex(&critical_section, "critsec", PJ_MUTEX_RECURSE)) != 0)
+	return rc;
+
+#endif
+
+    /* Init logging */
+    pj_log_init();
+
+    /* Initialize exception ID for the pool. 
+     * Must do so after critical section is configured.
+     */
+    rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
+    if (rc != PJ_SUCCESS)
+        return rc;
+    
+    /* Init random seed. */
+    /* Or probably not. Let application in charge of this */
+    /* pj_srand( clock() ); */
+
+    /* Startup GUID. */
+    guid.ptr = dummy_guid;
+    pj_generate_unique_string( &guid );
+
+    /* Startup timestamp */
+#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
+    {
+	pj_timestamp dummy_ts;
+	if ((rc=pj_get_timestamp(&dummy_ts)) != 0) {
+	    return rc;
+	}
+    }
+#endif   
+
+    /* Flag PJLIB as initialized */
+    ++initialized;
+    pj_assert(initialized == 1);
+
+    PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized",
+	      PJ_VERSION));
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_atexit()
+ */
+PJ_DEF(pj_status_t) pj_atexit(void (*func)(void))
+{
+    if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))
+	return PJ_ETOOMANY;
+
+    atexit_func[atexit_count++] = func;
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_shutdown(void)
+ */
+PJ_DEF(void) pj_shutdown()
+{
+    int i;
+
+    /* Only perform shutdown operation when 'initialized' reaches zero */
+    pj_assert(initialized > 0);
+    if (--initialized != 0)
+	return;
+
+    /* Call atexit() functions */
+    for (i=atexit_count-1; i>=0; --i) {
+	(*atexit_func[i])();
+    }
+    atexit_count = 0;
+
+    /* Free exception ID */
+    if (PJ_NO_MEMORY_EXCEPTION != -1) {
+	pj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);
+	PJ_NO_MEMORY_EXCEPTION = -1;
+    }
+
+#if PJ_HAS_THREADS
+    /* Destroy PJLIB critical section */
+    pj_mutex_destroy(&critical_section);
+
+    /* Free PJLIB TLS */
+    if (thread_tls_id != -1) {
+	pj_thread_local_free(thread_tls_id);
+	thread_tls_id = -1;
+    }
+
+    /* Ticket #1132: Assertion when (re)starting PJLIB on different thread */
+    pj_bzero(&main_thread, sizeof(main_thread));
+#endif
+
+    /* Clear static variables */
+    pj_errno_clear_handlers();
+}
+
+
+/*
+ * pj_getpid(void)
+ */
+PJ_DEF(pj_uint32_t) pj_getpid(void)
+{
+    PJ_CHECK_STACK();
+    return getpid();
+}
+
+/*
+ * Check if this thread has been registered to PJLIB.
+ */
+PJ_DEF(pj_bool_t) pj_thread_is_registered(void)
+{
+#if PJ_HAS_THREADS
+    return pj_thread_local_get(thread_tls_id) != 0;
+#else
+    pj_assert("pj_thread_is_registered() called in non-threading mode!");
+    return PJ_TRUE;
+#endif
+}
+
+
+/*
+ * Get thread priority value for the thread.
+ */
+PJ_DEF(int) pj_thread_get_prio(pj_thread_t *thread)
+{
+#if PJ_HAS_THREADS
+    struct sched_param param;
+    int policy;
+    int rc;
+
+    rc = pthread_getschedparam (thread->thread, &policy, &param);
+    if (rc != 0)
+	return -1;
+
+    return param.sched_priority;
+#else
+    PJ_UNUSED_ARG(thread);
+    return 1;
+#endif
+}
+
+
+/*
+ * Set the thread priority.
+ */
+PJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio)
+{
+#if PJ_HAS_THREADS
+    struct sched_param param;
+    int policy;
+    int rc;
+
+    rc = pthread_getschedparam (thread->thread, &policy, &param);
+    if (rc != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+
+    param.sched_priority = prio;
+
+    rc = pthread_setschedparam(thread->thread, policy, &param);
+    if (rc != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+
+    return PJ_SUCCESS;
+#else
+    PJ_UNUSED_ARG(thread);
+    PJ_UNUSED_ARG(prio);
+    pj_assert("pj_thread_set_prio() called in non-threading mode!");
+    return 1;
+#endif
+}
+
+
+/*
+ * Get the lowest priority value available on this system.
+ */
+PJ_DEF(int) pj_thread_get_prio_min(pj_thread_t *thread)
+{
+    struct sched_param param;
+    int policy;
+    int rc;
+
+    rc = pthread_getschedparam(thread->thread, &policy, &param);
+    if (rc != 0)
+	return -1;
+
+#if defined(_POSIX_PRIORITY_SCHEDULING)
+    return sched_get_priority_min(policy);
+#elif defined __OpenBSD__
+    /* Thread prio min/max are declared in OpenBSD private hdr */
+    return 0;
+#else
+    pj_assert("pj_thread_get_prio_min() not supported!");
+    return 0;
+#endif
+}
+
+
+/*
+ * Get the highest priority value available on this system.
+ */
+PJ_DEF(int) pj_thread_get_prio_max(pj_thread_t *thread)
+{
+    struct sched_param param;
+    int policy;
+    int rc;
+
+    rc = pthread_getschedparam(thread->thread, &policy, &param);
+    if (rc != 0)
+	return -1;
+
+#if defined(_POSIX_PRIORITY_SCHEDULING)
+    return sched_get_priority_max(policy);
+#elif defined __OpenBSD__
+    /* Thread prio min/max are declared in OpenBSD private hdr */
+    return 31;
+#else
+    pj_assert("pj_thread_get_prio_max() not supported!");
+    return 0;
+#endif
+}
+
+
+/*
+ * Get native thread handle
+ */
+PJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread) 
+{
+    PJ_ASSERT_RETURN(thread, NULL);
+
+#if PJ_HAS_THREADS
+    return &thread->thread;
+#else
+    pj_assert("pj_thread_is_registered() called in non-threading mode!");
+    return NULL;
+#endif
+}
+
+/*
+ * pj_thread_register(..)
+ */
+PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
+					 pj_thread_desc desc,
+					 pj_thread_t **ptr_thread)
+{
+#if PJ_HAS_THREADS
+    char stack_ptr;
+    pj_status_t rc;
+    pj_thread_t *thread = (pj_thread_t *)desc;
+    pj_str_t thread_name = pj_str((char*)cstr_thread_name);
+
+    /* Size sanity check. */
+    if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {
+	pj_assert(!"Not enough pj_thread_desc size!");
+	return PJ_EBUG;
+    }
+
+    /* Warn if this thread has been registered before */
+    if (pj_thread_local_get (thread_tls_id) != 0) {
+	// 2006-02-26 bennylp:
+	//  This wouldn't work in all cases!.
+	//  If thread is created by external module (e.g. sound thread),
+	//  thread may be reused while the pool used for the thread descriptor
+	//  has been deleted by application.
+	//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);
+        //return PJ_SUCCESS;
+	PJ_LOG(4,(THIS_FILE, "Info: possibly re-registering existing "
+			     "thread"));
+    }
+
+    /* On the other hand, also warn if the thread descriptor buffer seem to
+     * have been used to register other threads.
+     */
+    pj_assert(thread->signature1 != SIGNATURE1 ||
+	      thread->signature2 != SIGNATURE2 ||
+	      (thread->thread == pthread_self()));
+
+    /* Initialize and set the thread entry. */
+    pj_bzero(desc, sizeof(struct pj_thread_t));
+    thread->thread = pthread_self();
+    thread->signature1 = SIGNATURE1;
+    thread->signature2 = SIGNATURE2;
+
+    if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)
+	pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), 
+			 cstr_thread_name, thread->thread);
+    else
+	pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), 
+			 "thr%p", (void*)thread->thread);
+    
+    rc = pj_thread_local_set(thread_tls_id, thread);
+    if (rc != PJ_SUCCESS) {
+	pj_bzero(desc, sizeof(struct pj_thread_t));
+	return rc;
+    }
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    thread->stk_start = &stack_ptr;
+    thread->stk_size = 0xFFFFFFFFUL;
+    thread->stk_max_usage = 0;
+#else
+    stack_ptr = '\0';
+#endif
+
+    *ptr_thread = thread;
+    return PJ_SUCCESS;
+#else
+    pj_thread_t *thread = (pj_thread_t*)desc;
+    *ptr_thread = thread;
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_thread_init(void)
+ */
+pj_status_t pj_thread_init(void)
+{
+#if PJ_HAS_THREADS
+    pj_status_t rc;
+    pj_thread_t *dummy;
+
+    rc = pj_thread_local_alloc(&thread_tls_id );
+    if (rc != PJ_SUCCESS) {
+	return rc;
+    }
+    return pj_thread_register("thr%p", (long*)&main_thread, &dummy);
+#else
+    PJ_LOG(2,(THIS_FILE, "Thread init error. Threading is not enabled!"));
+    return PJ_EINVALIDOP;
+#endif
+}
+
+#if PJ_HAS_THREADS
+/*
+ * thread_main()
+ *
+ * This is the main entry for all threads.
+ */
+static void *thread_main(void *param)
+{
+    pj_thread_t *rec = (pj_thread_t*)param;
+    void *result;
+    pj_status_t rc;
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    rec->stk_start = (char*)&rec;
+#endif
+
+    /* Set current thread id. */
+    rc = pj_thread_local_set(thread_tls_id, rec);
+    if (rc != PJ_SUCCESS) {
+	pj_assert(!"Thread TLS ID is not set (pj_init() error?)");
+    }
+
+    /* Check if suspension is required. */
+    if (rec->suspended_mutex) {
+	pj_mutex_lock(rec->suspended_mutex);
+	pj_mutex_unlock(rec->suspended_mutex);
+    }
+
+    PJ_LOG(6,(rec->obj_name, "Thread started"));
+
+    /* Call user's entry! */
+    result = (void*)(long)(*rec->proc)(rec->arg);
+
+    /* Done. */
+    PJ_LOG(6,(rec->obj_name, "Thread quitting"));
+
+    return result;
+}
+#endif
+
+/*
+ * pj_thread_create(...)
+ */
+PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, 
+				      const char *thread_name,
+				      pj_thread_proc *proc, 
+				      void *arg,
+				      pj_size_t stack_size, 
+				      unsigned flags,
+				      pj_thread_t **ptr_thread)
+{
+#if PJ_HAS_THREADS
+    pj_thread_t *rec;
+    pthread_attr_t thread_attr;
+    void *stack_addr;
+    int rc;
+
+    PJ_UNUSED_ARG(stack_addr);
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);
+
+    /* Create thread record and assign name for the thread */
+    rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));
+    PJ_ASSERT_RETURN(rec, PJ_ENOMEM);
+    
+    /* Set name. */
+    if (!thread_name) 
+	thread_name = "thr%p";
+    
+    if (strchr(thread_name, '%')) {
+	pj_ansi_snprintf(rec->obj_name, PJ_MAX_OBJ_NAME, thread_name, rec);
+    } else {
+	strncpy(rec->obj_name, thread_name, PJ_MAX_OBJ_NAME);
+	rec->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
+    }
+
+    /* Set default stack size */
+    if (stack_size == 0)
+	stack_size = PJ_THREAD_DEFAULT_STACK_SIZE;
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    rec->stk_size = stack_size;
+    rec->stk_max_usage = 0;
+#endif
+
+    /* Emulate suspended thread with mutex. */
+    if (flags & PJ_THREAD_SUSPENDED) {
+	rc = pj_mutex_create_simple(pool, NULL, &rec->suspended_mutex);
+	if (rc != PJ_SUCCESS) {
+	    return rc;
+	}
+
+	pj_mutex_lock(rec->suspended_mutex);
+    } else {
+	pj_assert(rec->suspended_mutex == NULL);
+    }
+    
+
+    /* Init thread attributes */
+    pthread_attr_init(&thread_attr);
+
+#if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0
+    /* Set thread's stack size */
+    rc = pthread_attr_setstacksize(&thread_attr, stack_size);
+    if (rc != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+#endif	/* PJ_THREAD_SET_STACK_SIZE */
+
+
+#if defined(PJ_THREAD_ALLOCATE_STACK) && PJ_THREAD_ALLOCATE_STACK!=0
+    /* Allocate memory for the stack */
+    stack_addr = pj_pool_alloc(pool, stack_size);
+    PJ_ASSERT_RETURN(stack_addr, PJ_ENOMEM);
+
+    rc = pthread_attr_setstackaddr(&thread_attr, stack_addr);
+    if (rc != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+#endif	/* PJ_THREAD_ALLOCATE_STACK */
+
+
+    /* Create the thread. */
+    rec->proc = proc;
+    rec->arg = arg;
+    rc = pthread_create( &rec->thread, &thread_attr, &thread_main, rec);
+    if (rc != 0) {
+	return PJ_RETURN_OS_ERROR(rc);
+    }
+
+    *ptr_thread = rec;
+
+    PJ_LOG(6, (rec->obj_name, "Thread created"));
+    return PJ_SUCCESS;
+#else
+    pj_assert(!"Threading is disabled!");
+    return PJ_EINVALIDOP;
+#endif
+}
+
+/*
+ * pj_thread-get_name()
+ */
+PJ_DEF(const char*) pj_thread_get_name(pj_thread_t *p)
+{
+#if PJ_HAS_THREADS
+    pj_thread_t *rec = (pj_thread_t*)p;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(p, "");
+
+    return rec->obj_name;
+#else
+    return "";
+#endif
+}
+
+/*
+ * pj_thread_resume()
+ */
+PJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *p)
+{
+    pj_status_t rc;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(p, PJ_EINVAL);
+
+    rc = pj_mutex_unlock(p->suspended_mutex);
+
+    return rc;
+}
+
+/*
+ * pj_thread_this()
+ */
+PJ_DEF(pj_thread_t*) pj_thread_this(void)
+{
+#if PJ_HAS_THREADS
+    pj_thread_t *rec = (pj_thread_t*)pj_thread_local_get(thread_tls_id);
+    
+    if (rec == NULL) {
+	pj_assert(!"Calling pjlib from unknown/external thread. You must "
+		   "register external threads with pj_thread_register() "
+		   "before calling any pjlib functions.");
+    }
+
+    /*
+     * MUST NOT check stack because this function is called
+     * by PJ_CHECK_STACK() itself!!!
+     *
+     */
+
+    return rec;
+#else
+    pj_assert(!"Threading is not enabled!");
+    return NULL;
+#endif
+}
+
+/*
+ * pj_thread_join()
+ */
+PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
+{
+#if PJ_HAS_THREADS
+    pj_thread_t *rec = (pj_thread_t *)p;
+    void *ret;
+    int result;
+
+    PJ_CHECK_STACK();
+
+    PJ_LOG(6, (pj_thread_this()->obj_name, "Joining thread %s", p->obj_name));
+    result = pthread_join( rec->thread, &ret);
+
+    if (result == 0)
+	return PJ_SUCCESS;
+    else {
+	/* Calling pthread_join() on a thread that no longer exists and 
+	 * getting back ESRCH isn't an error (in this context). 
+	 * Thanks Phil Torre <ptorre@zetron.com>.
+	 */
+	return result==ESRCH ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(result);
+    }
+#else
+    PJ_CHECK_STACK();
+    pj_assert(!"No multithreading support!");
+    return PJ_EINVALIDOP;
+#endif
+}
+
+/*
+ * pj_thread_destroy()
+ */
+PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
+{
+    PJ_CHECK_STACK();
+
+    /* Destroy mutex used to suspend thread */
+    if (p->suspended_mutex) {
+	pj_mutex_destroy(p->suspended_mutex);
+	p->suspended_mutex = NULL;
+    }
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_thread_sleep()
+ */
+PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
+{
+/* TODO: should change this to something like PJ_OS_HAS_NANOSLEEP */
+#if defined(PJ_RTEMS) && PJ_RTEMS!=0
+    enum { NANOSEC_PER_MSEC = 1000000 };
+    struct timespec req;
+
+    PJ_CHECK_STACK();
+    req.tv_sec = msec / 1000;
+    req.tv_nsec = (msec % 1000) * NANOSEC_PER_MSEC;
+
+    if (nanosleep(&req, NULL) == 0)
+	return PJ_SUCCESS;
+
+    return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+    PJ_CHECK_STACK();
+
+    pj_set_os_error(0);
+
+    usleep(msec * 1000);
+
+    /* MacOS X (reported on 10.5) seems to always set errno to ETIMEDOUT.
+     * It does so because usleep() is declared to return int, and we're
+     * supposed to check for errno only when usleep() returns non-zero. 
+     * Unfortunately, usleep() is declared to return void in other platforms
+     * so it's not possible to always check for the return value (unless 
+     * we add a detection routine in autoconf).
+     *
+     * As a workaround, here we check if ETIMEDOUT is returned and
+     * return successfully if it is.
+     */
+    if (pj_get_native_os_error() == ETIMEDOUT)
+	return PJ_SUCCESS;
+
+    return pj_get_os_error();
+
+#endif	/* PJ_RTEMS */
+}
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+/*
+ * pj_thread_check_stack()
+ * Implementation for PJ_CHECK_STACK()
+ */
+PJ_DEF(void) pj_thread_check_stack(const char *file, int line)
+{
+    char stk_ptr;
+    pj_uint32_t usage;
+    pj_thread_t *thread = pj_thread_this();
+
+    /* Calculate current usage. */
+    usage = (&stk_ptr > thread->stk_start) ? &stk_ptr - thread->stk_start :
+		thread->stk_start - &stk_ptr;
+
+    /* Assert if stack usage is dangerously high. */
+    pj_assert("STACK OVERFLOW!! " && (usage <= thread->stk_size - 128));
+
+    /* Keep statistic. */
+    if (usage > thread->stk_max_usage) {
+	thread->stk_max_usage = usage;
+	thread->caller_file = file;
+	thread->caller_line = line;
+    }
+}
+
+/*
+ * pj_thread_get_stack_max_usage()
+ */
+PJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)
+{
+    return thread->stk_max_usage;
+}
+
+/*
+ * pj_thread_get_stack_info()
+ */
+PJ_DEF(pj_status_t) pj_thread_get_stack_info( pj_thread_t *thread,
+					      const char **file,
+					      int *line )
+{
+    pj_assert(thread);
+
+    *file = thread->caller_file;
+    *line = thread->caller_line;
+    return 0;
+}
+
+#endif	/* PJ_OS_HAS_CHECK_STACK */
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * pj_atomic_create()
+ */
+PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, 
+				      pj_atomic_value_t initial,
+				      pj_atomic_t **ptr_atomic)
+{
+    pj_status_t rc;
+    pj_atomic_t *atomic_var;
+
+    atomic_var = PJ_POOL_ZALLOC_T(pool, pj_atomic_t);
+
+    PJ_ASSERT_RETURN(atomic_var, PJ_ENOMEM);
+    
+#if PJ_HAS_THREADS
+    rc = pj_mutex_create(pool, "atm%p", PJ_MUTEX_SIMPLE, &atomic_var->mutex);
+    if (rc != PJ_SUCCESS)
+	return rc;
+#endif
+    atomic_var->value = initial;
+
+    *ptr_atomic = atomic_var;
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_atomic_destroy()
+ */
+PJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var )
+{
+    PJ_ASSERT_RETURN(atomic_var, PJ_EINVAL);
+#if PJ_HAS_THREADS
+    return pj_mutex_destroy( atomic_var->mutex );
+#else
+    return 0;
+#endif
+}
+
+/*
+ * pj_atomic_set()
+ */
+PJ_DEF(void) pj_atomic_set(pj_atomic_t *atomic_var, pj_atomic_value_t value)
+{
+    PJ_CHECK_STACK();
+
+#if PJ_HAS_THREADS
+    pj_mutex_lock( atomic_var->mutex );
+#endif
+    atomic_var->value = value;
+#if PJ_HAS_THREADS
+    pj_mutex_unlock( atomic_var->mutex);
+#endif 
+}
+
+/*
+ * pj_atomic_get()
+ */
+PJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)
+{
+    pj_atomic_value_t oldval;
+    
+    PJ_CHECK_STACK();
+
+#if PJ_HAS_THREADS
+    pj_mutex_lock( atomic_var->mutex );
+#endif
+    oldval = atomic_var->value;
+#if PJ_HAS_THREADS
+    pj_mutex_unlock( atomic_var->mutex);
+#endif
+    return oldval;
+}
+
+/*
+ * pj_atomic_inc_and_get()
+ */
+PJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var)
+{
+    pj_atomic_value_t new_value;
+
+    PJ_CHECK_STACK();
+
+#if PJ_HAS_THREADS
+    pj_mutex_lock( atomic_var->mutex );
+#endif
+    new_value = ++atomic_var->value;
+#if PJ_HAS_THREADS
+    pj_mutex_unlock( atomic_var->mutex);
+#endif
+
+    return new_value;
+}
+/*
+ * pj_atomic_inc()
+ */
+PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var)
+{
+    pj_atomic_inc_and_get(atomic_var);
+}
+
+/*
+ * pj_atomic_dec_and_get()
+ */
+PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var)
+{
+    pj_atomic_value_t new_value;
+
+    PJ_CHECK_STACK();
+
+#if PJ_HAS_THREADS
+    pj_mutex_lock( atomic_var->mutex );
+#endif
+    new_value = --atomic_var->value;
+#if PJ_HAS_THREADS
+    pj_mutex_unlock( atomic_var->mutex);
+#endif
+
+    return new_value;
+}
+
+/*
+ * pj_atomic_dec()
+ */
+PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)
+{
+    pj_atomic_dec_and_get(atomic_var);
+}
+
+/*
+ * pj_atomic_add_and_get()
+ */ 
+PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var, 
+                                                 pj_atomic_value_t value )
+{
+    pj_atomic_value_t new_value;
+
+#if PJ_HAS_THREADS
+    pj_mutex_lock(atomic_var->mutex);
+#endif
+    
+    atomic_var->value += value;
+    new_value = atomic_var->value;
+
+#if PJ_HAS_THREADS
+    pj_mutex_unlock(atomic_var->mutex);
+#endif
+
+    return new_value;
+}
+
+/*
+ * pj_atomic_add()
+ */ 
+PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var, 
+                            pj_atomic_value_t value )
+{
+    pj_atomic_add_and_get(atomic_var, value);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * pj_thread_local_alloc()
+ */
+PJ_DEF(pj_status_t) pj_thread_local_alloc(long *p_index)
+{
+#if PJ_HAS_THREADS
+    pthread_key_t key;
+    int rc;
+
+    PJ_ASSERT_RETURN(p_index != NULL, PJ_EINVAL);
+
+    pj_assert( sizeof(pthread_key_t) <= sizeof(long));
+    if ((rc=pthread_key_create(&key, NULL)) != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+
+    *p_index = key;
+    return PJ_SUCCESS;
+#else
+    int i;
+    for (i=0; i<MAX_THREADS; ++i) {
+	if (tls_flag[i] == 0)
+	    break;
+    }
+    if (i == MAX_THREADS) 
+	return PJ_ETOOMANY;
+    
+    tls_flag[i] = 1;
+    tls[i] = NULL;
+
+    *p_index = i;
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_thread_local_free()
+ */
+PJ_DEF(void) pj_thread_local_free(long index)
+{
+    PJ_CHECK_STACK();
+#if PJ_HAS_THREADS
+    pthread_key_delete(index);
+#else
+    tls_flag[index] = 0;
+#endif
+}
+
+/*
+ * pj_thread_local_set()
+ */
+PJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)
+{
+    //Can't check stack because this function is called in the
+    //beginning before main thread is initialized.
+    //PJ_CHECK_STACK();
+#if PJ_HAS_THREADS
+    int rc=pthread_setspecific(index, value);
+    return rc==0 ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(rc);
+#else
+    pj_assert(index >= 0 && index < MAX_THREADS);
+    tls[index] = value;
+    return PJ_SUCCESS;
+#endif
+}
+
+PJ_DEF(void*) pj_thread_local_get(long index)
+{
+    //Can't check stack because this function is called
+    //by PJ_CHECK_STACK() itself!!!
+    //PJ_CHECK_STACK();
+#if PJ_HAS_THREADS
+    return pthread_getspecific(index);
+#else
+    pj_assert(index >= 0 && index < MAX_THREADS);
+    return tls[index];
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+PJ_DEF(void) pj_enter_critical_section(void)
+{
+#if PJ_HAS_THREADS
+    pj_mutex_lock(&critical_section);
+#endif
+}
+
+PJ_DEF(void) pj_leave_critical_section(void)
+{
+#if PJ_HAS_THREADS
+    pj_mutex_unlock(&critical_section);
+#endif
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_LINUX) && PJ_LINUX!=0
+PJ_BEGIN_DECL
+PJ_DECL(int) pthread_mutexattr_settype(pthread_mutexattr_t*,int);
+PJ_END_DECL
+#endif
+
+static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
+{
+#if PJ_HAS_THREADS
+    pthread_mutexattr_t attr;
+    int rc;
+
+    PJ_CHECK_STACK();
+
+    rc = pthread_mutexattr_init(&attr);
+    if (rc != 0)
+	return PJ_RETURN_OS_ERROR(rc);
+
+    if (type == PJ_MUTEX_SIMPLE) {
+#if (defined(PJ_LINUX) && PJ_LINUX!=0) || \
+    defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP);
+#elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \
+       defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)
+	/* Nothing to do, default is simple */
+#else
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+#endif
+    } else {
+#if (defined(PJ_LINUX) && PJ_LINUX!=0) || \
+     defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \
+       defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)
+	// Phil Torre <ptorre@zetron.com>:
+	// The RTEMS implementation of POSIX mutexes doesn't include 
+	// pthread_mutexattr_settype(), so what follows is a hack
+	// until I get RTEMS patched to support the set/get functions.
+	//
+	// More info:
+	//   newlib's pthread also lacks pthread_mutexattr_settype(),
+	//   but it seems to have mutexattr.recursive.
+	PJ_TODO(FIX_RTEMS_RECURSIVE_MUTEX_TYPE)
+	attr.recursive = 1;
+#else
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+#endif
+    }
+    
+    if (rc != 0) {
+	return PJ_RETURN_OS_ERROR(rc);
+    }
+
+    rc = pthread_mutex_init(&mutex->mutex, &attr);
+    if (rc != 0) {
+	return PJ_RETURN_OS_ERROR(rc);
+    }
+    
+    rc = pthread_mutexattr_destroy(&attr);
+    if (rc != 0) {
+	pj_status_t status = PJ_RETURN_OS_ERROR(rc);
+	pthread_mutex_destroy(&mutex->mutex);
+	return status;
+    }
+
+#if PJ_DEBUG
+    /* Set owner. */
+    mutex->nesting_level = 0;
+    mutex->owner = NULL;
+#endif
+
+    /* Set name. */
+    if (!name) {
+	name = "mtx%p";
+    }
+    if (strchr(name, '%')) {
+	pj_ansi_snprintf(mutex->obj_name, PJ_MAX_OBJ_NAME, name, mutex);
+    } else {
+	strncpy(mutex->obj_name, name, PJ_MAX_OBJ_NAME);
+	mutex->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
+    }
+
+    PJ_LOG(6, (mutex->obj_name, "Mutex created"));
+    return PJ_SUCCESS;
+#else /* PJ_HAS_THREADS */
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_mutex_create()
+ */
+PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool, 
+				    const char *name, 
+				    int type,
+				    pj_mutex_t **ptr_mutex)
+{
+#if PJ_HAS_THREADS
+    pj_status_t rc;
+    pj_mutex_t *mutex;
+
+    PJ_ASSERT_RETURN(pool && ptr_mutex, PJ_EINVAL);
+
+    mutex = PJ_POOL_ALLOC_T(pool, pj_mutex_t);
+    PJ_ASSERT_RETURN(mutex, PJ_ENOMEM);
+
+    if ((rc=init_mutex(mutex, name, type)) != PJ_SUCCESS)
+	return rc;
+    
+    *ptr_mutex = mutex;
+    return PJ_SUCCESS;
+#else /* PJ_HAS_THREADS */
+    *ptr_mutex = (pj_mutex_t*)1;
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_mutex_create_simple()
+ */
+PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, 
+                                            const char *name,
+					    pj_mutex_t **mutex )
+{
+    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);
+}
+
+/*
+ * pj_mutex_create_recursive()
+ */
+PJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
+					       const char *name,
+					       pj_mutex_t **mutex )
+{
+    return pj_mutex_create(pool, name, PJ_MUTEX_RECURSE, mutex);
+}
+
+/*
+ * pj_mutex_lock()
+ */
+PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
+{
+#if PJ_HAS_THREADS
+    pj_status_t status;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+#if PJ_DEBUG
+    PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting (mutex owner=%s)", 
+				pj_thread_this()->obj_name,
+				mutex->owner_name));
+#else
+    PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting", 
+				pj_thread_this()->obj_name));
+#endif
+
+    status = pthread_mutex_lock( &mutex->mutex );
+
+
+#if PJ_DEBUG
+    if (status == PJ_SUCCESS) {
+	mutex->owner = pj_thread_this();
+	pj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);
+	++mutex->nesting_level;
+    }
+
+    PJ_LOG(6,(mutex->obj_name, 
+	      (status==0 ? 
+		"Mutex acquired by thread %s (level=%d)" : 
+		"Mutex acquisition FAILED by %s (level=%d)"),
+	      pj_thread_this()->obj_name,
+	      mutex->nesting_level));
+#else
+    PJ_LOG(6,(mutex->obj_name, 
+	      (status==0 ? "Mutex acquired by thread %s" : "FAILED by %s"),
+	      pj_thread_this()->obj_name));
+#endif
+
+    if (status == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(status);
+#else	/* PJ_HAS_THREADS */
+    pj_assert( mutex == (pj_mutex_t*)1 );
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_mutex_unlock()
+ */
+PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
+{
+#if PJ_HAS_THREADS
+    pj_status_t status;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+#if PJ_DEBUG
+    pj_assert(mutex->owner == pj_thread_this());
+    if (--mutex->nesting_level == 0) {
+	mutex->owner = NULL;
+	mutex->owner_name[0] = '\0';
+    }
+
+    PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s (level=%d)", 
+				pj_thread_this()->obj_name, 
+				mutex->nesting_level));
+#else
+    PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s", 
+				pj_thread_this()->obj_name));
+#endif
+
+    status = pthread_mutex_unlock( &mutex->mutex );
+    if (status == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(status);
+
+#else /* PJ_HAS_THREADS */
+    pj_assert( mutex == (pj_mutex_t*)1 );
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_mutex_trylock()
+ */
+PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
+{
+#if PJ_HAS_THREADS
+    int status;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+    PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is trying", 
+				pj_thread_this()->obj_name));
+
+    status = pthread_mutex_trylock( &mutex->mutex );
+
+    if (status==0) {
+#if PJ_DEBUG
+	mutex->owner = pj_thread_this();
+	pj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);
+	++mutex->nesting_level;
+
+	PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s (level=%d)", 
+				   pj_thread_this()->obj_name,
+				   mutex->nesting_level));
+#else
+	PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s", 
+				  pj_thread_this()->obj_name));
+#endif
+    } else {
+	PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s's trylock() failed", 
+				    pj_thread_this()->obj_name));
+    }
+    
+    if (status==0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(status);
+#else	/* PJ_HAS_THREADS */
+    pj_assert( mutex == (pj_mutex_t*)1);
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_mutex_destroy()
+ */
+PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
+{
+    enum { RETRY = 4 };
+    int status = 0;
+    unsigned retry;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+#if PJ_HAS_THREADS
+    PJ_LOG(6,(mutex->obj_name, "Mutex destroyed by thread %s",
+			       pj_thread_this()->obj_name));
+
+    for (retry=0; retry<RETRY; ++retry) {
+	status = pthread_mutex_destroy( &mutex->mutex );
+	if (status == PJ_SUCCESS)
+	    break;
+	else if (retry<RETRY-1 && status == EBUSY)
+	    pthread_mutex_unlock(&mutex->mutex);
+    }
+
+    if (status == 0)
+	return PJ_SUCCESS;
+    else {
+	return PJ_RETURN_OS_ERROR(status);
+    }
+#else
+    pj_assert( mutex == (pj_mutex_t*)1 );
+    status = PJ_SUCCESS;
+    return status;
+#endif
+}
+
+#if PJ_DEBUG
+PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
+{
+#if PJ_HAS_THREADS
+    return mutex->owner == pj_thread_this();
+#else
+    return 1;
+#endif
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Include Read/Write mutex emulation for POSIX platforms that lack it (e.g.
+ * RTEMS). Otherwise use POSIX rwlock.
+ */
+#if defined(PJ_EMULATE_RWMUTEX) && PJ_EMULATE_RWMUTEX!=0
+    /* We need semaphore functionality to emulate rwmutex */
+#   if !defined(PJ_HAS_SEMAPHORE) || PJ_HAS_SEMAPHORE==0
+#	error "Semaphore support needs to be enabled to emulate rwmutex"
+#   endif
+#   include "os_rwmutex.c"
+#else
+struct pj_rwmutex_t
+{
+    pthread_rwlock_t rwlock;
+};
+
+PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
+				      pj_rwmutex_t **p_mutex)
+{
+    pj_rwmutex_t *rwm;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(name);
+    
+    rwm = PJ_POOL_ALLOC_T(pool, pj_rwmutex_t);
+    PJ_ASSERT_RETURN(rwm, PJ_ENOMEM);
+
+    status = pthread_rwlock_init(&rwm->rwlock, NULL);
+    if (status != 0)
+	return PJ_RETURN_OS_ERROR(status);
+
+    *p_mutex = rwm;
+    return PJ_SUCCESS;
+}
+
+/*
+ * Lock the mutex for reading.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)
+{
+    pj_status_t status;
+
+    status = pthread_rwlock_rdlock(&mutex->rwlock);
+    if (status != 0)
+	return PJ_RETURN_OS_ERROR(status);
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * Lock the mutex for writing.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)
+{
+    pj_status_t status;
+
+    status = pthread_rwlock_wrlock(&mutex->rwlock);
+    if (status != 0)
+	return PJ_RETURN_OS_ERROR(status);
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * Release read lock.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)
+{
+    return pj_rwmutex_unlock_write(mutex);
+}
+
+/*
+ * Release write lock.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)
+{
+    pj_status_t status;
+
+    status = pthread_rwlock_unlock(&mutex->rwlock);
+    if (status != 0)
+	return PJ_RETURN_OS_ERROR(status);
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * Destroy reader/writer mutex.
+ *
+ */
+PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
+{
+    pj_status_t status;
+
+    status = pthread_rwlock_destroy(&mutex->rwlock);
+    if (status != 0)
+	return PJ_RETURN_OS_ERROR(status);
+
+    return PJ_SUCCESS;
+}
+
+#endif	/* PJ_EMULATE_RWMUTEX */
+
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+
+/*
+ * pj_sem_create()
+ */
+PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool, 
+				   const char *name,
+				   unsigned initial, 
+				   unsigned max,
+				   pj_sem_t **ptr_sem)
+{
+#if PJ_HAS_THREADS
+    pj_sem_t *sem;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);
+
+    sem = PJ_POOL_ALLOC_T(pool, pj_sem_t);
+    PJ_ASSERT_RETURN(sem, PJ_ENOMEM);
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    /* MacOS X doesn't support anonymous semaphore */
+    {
+	char sem_name[PJ_GUID_MAX_LENGTH+1];
+	pj_str_t nam;
+
+	/* We should use SEM_NAME_LEN, but this doesn't seem to be 
+	 * declared anywhere? The value here is just from trial and error
+	 * to get the longest name supported.
+	 */
+#	define MAX_SEM_NAME_LEN	23
+
+	/* Create a unique name for the semaphore. */
+	if (PJ_GUID_STRING_LENGTH <= MAX_SEM_NAME_LEN) {
+	    nam.ptr = sem_name;
+	    pj_generate_unique_string(&nam);
+	    sem_name[nam.slen] = '\0';
+	} else {
+	    pj_create_random_string(sem_name, MAX_SEM_NAME_LEN);
+	    sem_name[MAX_SEM_NAME_LEN] = '\0';
+	}
+
+	/* Create semaphore */
+	sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 
+			    initial);
+	if (sem->sem == SEM_FAILED)
+	    return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+
+	/* And immediately release the name as we don't need it */
+	sem_unlink(sem_name);
+    }
+#else
+    sem->sem = PJ_POOL_ALLOC_T(pool, sem_t);
+    if (sem_init( sem->sem, 0, initial) != 0) 
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#endif
+    
+    /* Set name. */
+    if (!name) {
+	name = "sem%p";
+    }
+    if (strchr(name, '%')) {
+	pj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);
+    } else {
+	strncpy(sem->obj_name, name, PJ_MAX_OBJ_NAME);
+	sem->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
+    }
+
+    PJ_LOG(6, (sem->obj_name, "Semaphore created"));
+
+    *ptr_sem = sem;
+    return PJ_SUCCESS;
+#else
+    *ptr_sem = (pj_sem_t*)1;
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_sem_wait()
+ */
+PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
+{
+#if PJ_HAS_THREADS
+    int result;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(sem, PJ_EINVAL);
+
+    PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s is waiting", 
+			      pj_thread_this()->obj_name));
+
+    result = sem_wait( sem->sem );
+    
+    if (result == 0) {
+	PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s", 
+				  pj_thread_this()->obj_name));
+    } else {
+	PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s FAILED to acquire", 
+				  pj_thread_this()->obj_name));
+    }
+
+    if (result == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+    pj_assert( sem == (pj_sem_t*) 1 );
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_sem_trywait()
+ */
+PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
+{
+#if PJ_HAS_THREADS
+    int result;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(sem, PJ_EINVAL);
+
+    result = sem_trywait( sem->sem );
+    
+    if (result == 0) {
+	PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s", 
+				  pj_thread_this()->obj_name));
+    } 
+    if (result == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+    pj_assert( sem == (pj_sem_t*)1 );
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_sem_post()
+ */
+PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
+{
+#if PJ_HAS_THREADS
+    int result;
+    PJ_LOG(6, (sem->obj_name, "Semaphore released by thread %s",
+			      pj_thread_this()->obj_name));
+    result = sem_post( sem->sem );
+
+    if (result == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+    pj_assert( sem == (pj_sem_t*) 1);
+    return PJ_SUCCESS;
+#endif
+}
+
+/*
+ * pj_sem_destroy()
+ */
+PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
+{
+#if PJ_HAS_THREADS
+    int result;
+
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(sem, PJ_EINVAL);
+
+    PJ_LOG(6, (sem->obj_name, "Semaphore destroyed by thread %s",
+			      pj_thread_this()->obj_name));
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    result = sem_close( sem->sem );
+#else
+    result = sem_destroy( sem->sem );
+#endif
+
+    if (result == 0)
+	return PJ_SUCCESS;
+    else
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#else
+    pj_assert( sem == (pj_sem_t*) 1 );
+    return PJ_SUCCESS;
+#endif
+}
+
+#endif	/* PJ_HAS_SEMAPHORE */
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
+
+/*
+ * pj_event_create()
+ */
+PJ_DEF(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
+				    pj_bool_t manual_reset, pj_bool_t initial,
+				    pj_event_t **ptr_event)
+{
+    pj_event_t *event;
+
+    event = PJ_POOL_ALLOC_T(pool, pj_event_t);
+
+    init_mutex(&event->mutex, name, PJ_MUTEX_SIMPLE);
+    pthread_cond_init(&event->cond, 0);
+    event->auto_reset = !manual_reset;
+    event->threads_waiting = 0;
+
+    if (initial) {
+	event->state = EV_STATE_SET;
+	event->threads_to_release = 1;
+    } else {
+	event->state = EV_STATE_OFF;
+	event->threads_to_release = 0;
+    }
+
+    *ptr_event = event;
+    return PJ_SUCCESS;
+}
+
+static void event_on_one_release(pj_event_t *event)
+{
+    if (event->state == EV_STATE_SET) {
+	if (event->auto_reset) {
+	    event->threads_to_release = 0;
+	    event->state = EV_STATE_OFF;
+	} else {
+	    /* Manual reset remains on */
+	}
+    } else {
+	if (event->auto_reset) {
+	    /* Only release one */
+	    event->threads_to_release = 0;
+	    event->state = EV_STATE_OFF;
+	} else {
+	    event->threads_to_release--;
+	    pj_assert(event->threads_to_release >= 0);
+	    if (event->threads_to_release==0)
+		event->state = EV_STATE_OFF;
+	}
+    }
+}
+
+/*
+ * pj_event_wait()
+ */
+PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)
+{
+    pthread_mutex_lock(&event->mutex.mutex);
+    event->threads_waiting++;
+    while (event->state == EV_STATE_OFF)
+	pthread_cond_wait(&event->cond, &event->mutex.mutex);
+    event->threads_waiting--;
+    event_on_one_release(event);
+    pthread_mutex_unlock(&event->mutex.mutex);
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_event_trywait()
+ */
+PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)
+{
+    pj_status_t status;
+
+    pthread_mutex_lock(&event->mutex.mutex);
+    status = event->state != EV_STATE_OFF ? PJ_SUCCESS : -1;
+    if (status==PJ_SUCCESS) {
+	event_on_one_release(event);
+    }
+    pthread_mutex_unlock(&event->mutex.mutex);
+
+    return status;
+}
+
+/*
+ * pj_event_set()
+ */
+PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)
+{
+    pthread_mutex_lock(&event->mutex.mutex);
+    event->threads_to_release = 1;
+    event->state = EV_STATE_SET;
+    if (event->auto_reset)
+	pthread_cond_signal(&event->cond);
+    else
+	pthread_cond_broadcast(&event->cond);
+    pthread_mutex_unlock(&event->mutex.mutex);
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_event_pulse()
+ */
+PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)
+{
+    pthread_mutex_lock(&event->mutex.mutex);
+    if (event->threads_waiting) {
+	event->threads_to_release = event->auto_reset ? 1 :
+					event->threads_waiting;
+	event->state = EV_STATE_PULSED;
+	if (event->threads_to_release==1)
+	    pthread_cond_signal(&event->cond);
+	else
+	    pthread_cond_broadcast(&event->cond);
+    }
+    pthread_mutex_unlock(&event->mutex.mutex);
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_event_reset()
+ */
+PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)
+{
+    pthread_mutex_lock(&event->mutex.mutex);
+    event->state = EV_STATE_OFF;
+    event->threads_to_release = 0;
+    pthread_mutex_unlock(&event->mutex.mutex);
+    return PJ_SUCCESS;
+}
+
+/*
+ * pj_event_destroy()
+ */
+PJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)
+{
+    pj_mutex_destroy(&event->mutex);
+    pthread_cond_destroy(&event->cond);
+    return PJ_SUCCESS;
+}
+
+#endif	/* PJ_HAS_EVENT_OBJ */
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
+/*
+ * Terminal
+ */
+
+/**
+ * Set terminal color.
+ */
+PJ_DEF(pj_status_t) pj_term_set_color(pj_color_t color)
+{
+    /* put bright prefix to ansi_color */
+    char ansi_color[12] = "\033[01;3";
+
+    if (color & PJ_TERM_COLOR_BRIGHT) {
+	color ^= PJ_TERM_COLOR_BRIGHT;
+    } else {
+	strcpy(ansi_color, "\033[00;3");
+    }
+
+    switch (color) {
+    case 0:
+	/* black color */
+	strcat(ansi_color, "0m");
+	break;
+    case PJ_TERM_COLOR_R:
+	/* red color */
+	strcat(ansi_color, "1m");
+	break;
+    case PJ_TERM_COLOR_G:
+	/* green color */
+	strcat(ansi_color, "2m");
+	break;
+    case PJ_TERM_COLOR_B:
+	/* blue color */
+	strcat(ansi_color, "4m");
+	break;
+    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_G:
+	/* yellow color */
+	strcat(ansi_color, "3m");
+	break;
+    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_B:
+	/* magenta color */
+	strcat(ansi_color, "5m");
+	break;
+    case PJ_TERM_COLOR_G | PJ_TERM_COLOR_B:
+	/* cyan color */
+	strcat(ansi_color, "6m");
+	break;
+    case PJ_TERM_COLOR_R | PJ_TERM_COLOR_G | PJ_TERM_COLOR_B:
+	/* white color */
+	strcat(ansi_color, "7m");
+	break;
+    default:
+	/* default console color */
+	strcpy(ansi_color, "\033[00m");
+	break;
+    }
+
+    fputs(ansi_color, stdout);
+
+    return PJ_SUCCESS;
+}
+
+/**
+ * Get current terminal foreground color.
+ */
+PJ_DEF(pj_color_t) pj_term_get_color(void)
+{
+    return 0;
+}
+
+#endif	/* PJ_TERM_HAS_COLOR */
+
+#if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0
+/*
+ * pj_run_app()
+ */
+PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+                       unsigned flags)
+{
+    return (*main_func)(argc, argv);
+}
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/c0/c03d15fba78b2609ec859b84a121be2bda692f35.svn-base b/jni/pjproject-android/.svn/pristine/c0/c03d15fba78b2609ec859b84a121be2bda692f35.svn-base
new file mode 100644
index 0000000..6cfd5a3
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c03d15fba78b2609ec859b84a121be2bda692f35.svn-base
@@ -0,0 +1,176 @@
+/* Copyright (C) 2007 Jean-Marc Valin
+      
+   File: buffer.c
+   This is a very simple ring buffer implementation. It is not thread-safe
+   so you need to do your own locking.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "os_support.h"
+#include "arch.h"
+#include <speex/speex_buffer.h>
+
+struct SpeexBuffer_ {
+   char *data;
+   int   size;
+   int   read_ptr;
+   int   write_ptr;
+   int   available;
+};
+
+EXPORT SpeexBuffer *speex_buffer_init(int size)
+{
+   SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer));
+   st->data = speex_alloc(size);
+   st->size = size;
+   st->read_ptr = 0;
+   st->write_ptr = 0;
+   st->available = 0;
+   return st;
+}
+
+EXPORT void speex_buffer_destroy(SpeexBuffer *st)
+{
+   speex_free(st->data);
+   speex_free(st);
+}
+
+EXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len)
+{
+   int end;
+   int end1;
+   char *data = _data;
+   if (len > st->size)
+   {
+      data += len-st->size;
+      len = st->size;
+   }
+   end = st->write_ptr + len;
+   end1 = end;
+   if (end1 > st->size)
+      end1 = st->size;
+   SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr);
+   if (end > st->size)
+   {
+      end -= st->size;
+      SPEEX_COPY(st->data, data+end1 - st->write_ptr, end);
+   }
+   st->available += len;
+   if (st->available > st->size)
+   {
+      st->available = st->size;
+      st->read_ptr = st->write_ptr;
+   }
+   st->write_ptr += len;
+   if (st->write_ptr > st->size)
+      st->write_ptr -= st->size;
+   return len;
+}
+
+EXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len)
+{
+   /* This is almost the same as for speex_buffer_write() but using 
+   SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */
+   int end;
+   int end1;
+   if (len > st->size)
+   {
+      len = st->size;
+   }
+   end = st->write_ptr + len;
+   end1 = end;
+   if (end1 > st->size)
+      end1 = st->size;
+   SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr);
+   if (end > st->size)
+   {
+      end -= st->size;
+      SPEEX_MEMSET(st->data, 0, end);
+   }
+   st->available += len;
+   if (st->available > st->size)
+   {
+      st->available = st->size;
+      st->read_ptr = st->write_ptr;
+   }
+   st->write_ptr += len;
+   if (st->write_ptr > st->size)
+      st->write_ptr -= st->size;
+   return len;
+}
+
+EXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len)
+{
+   int end, end1;
+   char *data = _data;
+   if (len > st->available)
+   {
+      SPEEX_MEMSET(data+st->available, 0, st->size-st->available);
+      len = st->available;
+   }
+   end = st->read_ptr + len;
+   end1 = end;
+   if (end1 > st->size)
+      end1 = st->size;
+   SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr);
+
+   if (end > st->size)
+   {
+      end -= st->size;
+      SPEEX_COPY(data+end1 - st->read_ptr, st->data, end);
+   }
+   st->available -= len;
+   st->read_ptr += len;
+   if (st->read_ptr > st->size)
+      st->read_ptr -= st->size;
+   return len;
+}
+
+EXPORT int speex_buffer_get_available(SpeexBuffer *st)
+{
+   return st->available;
+}
+
+EXPORT int speex_buffer_resize(SpeexBuffer *st, int len)
+{
+   int old_len = st->size;
+   if (len > old_len)
+   {
+      st->data = speex_realloc(st->data, len);
+      /* FIXME: move data/pointers properly for growing the buffer */
+   } else {
+      /* FIXME: move data/pointers properly for shrinking the buffer */
+      st->data = speex_realloc(st->data, len);
+   }
+   return len;
+}
diff --git a/jni/pjproject-android/.svn/pristine/c0/c04ab7fdfc2cc95f000a0d1e339e8d95c29a6d6e.svn-base b/jni/pjproject-android/.svn/pristine/c0/c04ab7fdfc2cc95f000a0d1e339e8d95c29a6d6e.svn-base
new file mode 100644
index 0000000..fa128b6
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c04ab7fdfc2cc95f000a0d1e339e8d95c29a6d6e.svn-base
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+test_param = TestParam(
+		"Callee=optional SRTP, caller=no SRTP",
+		[
+			InstanceParam("callee", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1"),
+			InstanceParam("caller", "--null-audio --max-calls=1")
+		]
+		)
diff --git a/jni/pjproject-android/.svn/pristine/c0/c058f799da1e9c6a98763be2ec3e1802b616c69e.svn-base b/jni/pjproject-android/.svn/pristine/c0/c058f799da1e9c6a98763be2ec3e1802b616c69e.svn-base
new file mode 100644
index 0000000..ae9cf83
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c058f799da1e9c6a98763be2ec3e1802b616c69e.svn-base
@@ -0,0 +1,112 @@
+/* Copyright (C) 2005 Analog Devices */
+/**
+   @author Jean-Marc Valin 
+   @file cb_search_bfin.h
+   @brief Fixed codebook functions (Blackfin version)
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK 
+void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
+{
+   int i;
+   for (i=0;i<shape_cb_size;i++)
+   {
+      __asm__ __volatile__ (
+         "P0 = %0;\n\t"
+         "LC0 = P0;\n\t"
+         "P1 = %1;\n\t"
+         "P2 = %2;\n\t"
+         "P3 = %3;\n\t"
+         "P0 = 1;\n\t"
+         "L0 = 0;\n\t"
+         "L1 = 0;\n\t"
+         "R2 = 0;\n\t"
+         "A1 = 0;\n\t"
+         "LOOP outter%= LC0;\n\t"
+         "LOOP_BEGIN outter%=;\n\t"
+            "A0 = 0;\n\t"
+            "P4 = P1;\n\t"
+            "I1 = P2;\n\t"
+            "R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
+            "LOOP inner%= LC1 = P0;\n\t"
+            "LOOP_BEGIN inner%=;\n\t"
+               "A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\n\t"
+            "LOOP_END inner%=;\n\t"
+            "R0 = A0;\n\t"
+            "R0 >>>= 13;\n\t"
+            "A1 += R0.L*R0.L (IS);\n\t"
+            "W[P3++] = R0;\n\t"
+            "P0 += 1;\n\t"
+            "P2 += 2;\n\t"
+         "LOOP_END outter%=;\n\t"
+         "P4 = %4;\n\t"
+         "R1 = A1;\n\t"
+         "[P4] = R1;\n\t"
+         :
+      : "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E)
+      : "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0", 
+        "L1", "A0", "A1", "memory"
+#if !(__GNUC__ == 3)
+         , "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */
+#endif
+      );
+      shape_cb += subvect_size;
+      resp += subvect_size;
+      E++;
+   }
+}
+
+#define OVERRIDE_TARGET_UPDATE
+static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
+{
+   if (!len)
+      return;
+   __asm__ __volatile__
+         (
+         "I0 = %0;\n\t"
+         "I1 = %1;\n\t"
+         "L0 = 0;\n\t"
+         "L1 = 0;\n\t"
+         "R2 = 4096;\n\t"
+         "LOOP tupdate%= LC0 = %3;\n\t"
+         "LOOP_BEGIN tupdate%=;\n\t"
+            "R0.L = W[I0] || R1.L = W[I1++];\n\t"
+            "R1 = (A1 = R1.L*%2.L) (IS);\n\t"
+            "R1 = R1 + R2;\n\t"
+            "R1 >>>= 13;\n\t"
+            "R0.L = R0.L - R1.L;\n\t"
+            "W[I0++] = R0.L;\n\t"
+         "LOOP_END tupdate%=;\n\t"
+   :
+   : "a" (t), "a" (r), "d" (g), "a" (len)
+   : "R0", "R1", "R2", "A1", "I0", "I1", "L0", "L1"
+         );
+}
diff --git a/jni/pjproject-android/.svn/pristine/c0/c0684132ddb0a58573e1fda83efd5d7c28838044.svn-base b/jni/pjproject-android/.svn/pristine/c0/c0684132ddb0a58573e1fda83efd5d7c28838044.svn-base
new file mode 100644
index 0000000..81985c0
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c0684132ddb0a58573e1fda83efd5d7c28838044.svn-base
@@ -0,0 +1,310 @@
+
+   /******************************************************************
+
+       iLBC Speech Coder ANSI-C Source Code
+
+       iLBC_test.c
+
+       Copyright (C) The Internet Society (2004).
+       All Rights Reserved.
+
+   ******************************************************************/
+
+   #include <math.h>
+   #include <stdlib.h>
+   #include <stdio.h>
+   #include <string.h>
+   #include "iLBC_define.h"
+   #include "iLBC_encode.h"
+   #include "iLBC_decode.h"
+
+   /* Runtime statistics */
+   #include <time.h>
+
+   #define ILBCNOOFWORDS_MAX   (NO_OF_BYTES_30MS/2)
+
+   /*----------------------------------------------------------------*
+    *  Encoder interface function
+
+
+
+
+
+    *---------------------------------------------------------------*/
+
+   short encode(   /* (o) Number of bytes encoded */
+       iLBC_Enc_Inst_t *iLBCenc_inst,
+                                   /* (i/o) Encoder instance */
+       short *encoded_data,    /* (o) The encoded bytes */
+       short *data                 /* (i) The signal block to encode*/
+   ){
+       float block[BLOCKL_MAX];
+       int k;
+
+       /* convert signal to float */
+
+       for (k=0; k<iLBCenc_inst->blockl; k++)
+           block[k] = (float)data[k];
+
+       /* do the actual encoding */
+
+       iLBC_encode((unsigned char *)encoded_data, block, iLBCenc_inst);
+
+
+       return (iLBCenc_inst->no_of_bytes);
+   }
+
+   /*----------------------------------------------------------------*
+    *  Decoder interface function
+    *---------------------------------------------------------------*/
+
+   short decode(       /* (o) Number of decoded samples */
+       iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) Decoder instance */
+       short *decoded_data,        /* (o) Decoded signal block*/
+       short *encoded_data,        /* (i) Encoded bytes */
+       short mode                       /* (i) 0=PL, 1=Normal */
+   ){
+       int k;
+       float decblock[BLOCKL_MAX], dtmp;
+
+       /* check if mode is valid */
+
+       if (mode<0 || mode>1) {
+           printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);}
+
+       /* do actual decoding of block */
+
+       iLBC_decode(decblock, (unsigned char *)encoded_data,
+           iLBCdec_inst, mode);
+
+       /* convert to short */
+
+
+
+
+
+       for (k=0; k<iLBCdec_inst->blockl; k++){
+           dtmp=decblock[k];
+
+           if (dtmp<MIN_SAMPLE)
+               dtmp=MIN_SAMPLE;
+           else if (dtmp>MAX_SAMPLE)
+               dtmp=MAX_SAMPLE;
+           decoded_data[k] = (short) dtmp;
+       }
+
+       return (iLBCdec_inst->blockl);
+   }
+
+   /*---------------------------------------------------------------*
+    *  Main program to test iLBC encoding and decoding
+    *
+    *  Usage:
+    *    exefile_name.exe <infile> <bytefile> <outfile> <channel>
+    *
+    *    <infile>   : Input file, speech for encoder (16-bit pcm file)
+    *    <bytefile> : Bit stream output from the encoder
+    *    <outfile>  : Output file, decoded speech (16-bit pcm file)
+    *    <channel>  : Bit error file, optional (16-bit)
+    *                     1 - Packet received correctly
+    *                     0 - Packet Lost
+    *
+    *--------------------------------------------------------------*/
+
+   int main(int argc, char* argv[])
+   {
+
+       /* Runtime statistics */
+
+       float starttime;
+       float runtime;
+       float outtime;
+
+       FILE *ifileid,*efileid,*ofileid, *cfileid;
+       short data[BLOCKL_MAX];
+       short encoded_data[ILBCNOOFWORDS_MAX], decoded_data[BLOCKL_MAX];
+       int len;
+       short pli, mode;
+       int blockcount = 0;
+       int packetlosscount = 0;
+
+       /* Create structs */
+       iLBC_Enc_Inst_t Enc_Inst;
+       iLBC_Dec_Inst_t Dec_Inst;
+
+
+
+
+
+       /* get arguments and open files */
+
+       if ((argc!=5) && (argc!=6)) {
+           fprintf(stderr,
+           "\n*-----------------------------------------------*\n");
+           fprintf(stderr,
+           "   %s <20,30> input encoded decoded (channel)\n\n",
+               argv[0]);
+           fprintf(stderr,
+           "   mode    : Frame size for the encoding/decoding\n");
+           fprintf(stderr,
+           "                 20 - 20 ms\n");
+           fprintf(stderr,
+           "                 30 - 30 ms\n");
+           fprintf(stderr,
+           "   input   : Speech for encoder (16-bit pcm file)\n");
+           fprintf(stderr,
+           "   encoded : Encoded bit stream\n");
+           fprintf(stderr,
+           "   decoded : Decoded speech (16-bit pcm file)\n");
+           fprintf(stderr,
+           "   channel : Packet loss pattern, optional (16-bit)\n");
+           fprintf(stderr,
+           "                  1 - Packet received correctly\n");
+           fprintf(stderr,
+           "                  0 - Packet Lost\n");
+           fprintf(stderr,
+           "*-----------------------------------------------*\n\n");
+           exit(1);
+       }
+       mode=atoi(argv[1]);
+       if (mode != 20 && mode != 30) {
+           fprintf(stderr,"Wrong mode %s, must be 20, or 30\n",
+               argv[1]);
+           exit(2);
+       }
+       if ( (ifileid=fopen(argv[2],"rb")) == NULL) {
+           fprintf(stderr,"Cannot open input file %s\n", argv[2]);
+           exit(2);}
+       if ( (efileid=fopen(argv[3],"wb")) == NULL) {
+           fprintf(stderr, "Cannot open encoded file %s\n",
+               argv[3]); exit(1);}
+       if ( (ofileid=fopen(argv[4],"wb")) == NULL) {
+           fprintf(stderr, "Cannot open decoded file %s\n",
+               argv[4]); exit(1);}
+       if (argc==6) {
+           if( (cfileid=fopen(argv[5],"rb")) == NULL) {
+               fprintf(stderr, "Cannot open channel file %s\n",
+
+
+
+
+
+                   argv[5]);
+               exit(1);
+           }
+       } else {
+           cfileid=NULL;
+       }
+
+       /* print info */
+
+       fprintf(stderr, "\n");
+       fprintf(stderr,
+           "*---------------------------------------------------*\n");
+       fprintf(stderr,
+           "*                                                   *\n");
+       fprintf(stderr,
+           "*      iLBC test program                            *\n");
+       fprintf(stderr,
+           "*                                                   *\n");
+       fprintf(stderr,
+           "*                                                   *\n");
+       fprintf(stderr,
+           "*---------------------------------------------------*\n");
+       fprintf(stderr,"\nMode           : %2d ms\n", mode);
+       fprintf(stderr,"Input file     : %s\n", argv[2]);
+       fprintf(stderr,"Encoded file   : %s\n", argv[3]);
+       fprintf(stderr,"Output file    : %s\n", argv[4]);
+       if (argc==6) {
+           fprintf(stderr,"Channel file   : %s\n", argv[5]);
+       }
+       fprintf(stderr,"\n");
+
+       /* Initialization */
+
+       initEncode(&Enc_Inst, mode);
+       initDecode(&Dec_Inst, mode, 1);
+
+       /* Runtime statistics */
+
+       starttime=clock()/(float)CLOCKS_PER_SEC;
+
+       /* loop over input blocks */
+
+       while (fread(data,sizeof(short),Enc_Inst.blockl,ifileid)==
+               (size_t)Enc_Inst.blockl) {
+
+           blockcount++;
+
+           /* encoding */
+
+
+
+
+
+           fprintf(stderr, "--- Encoding block %i --- ",blockcount);
+           len=encode(&Enc_Inst, encoded_data, data);
+           fprintf(stderr, "\r");
+
+           /* write byte file */
+
+           fwrite(encoded_data, sizeof(unsigned char), len, efileid);
+
+           /* get channel data if provided */
+           if (argc==6) {
+               if (fread(&pli, sizeof(short), 1, cfileid)) {
+                   if ((pli!=0)&&(pli!=1)) {
+                       fprintf(stderr, "Error in channel file\n");
+                       exit(0);
+                   }
+                   if (pli==0) {
+                       /* Packet loss -> remove info from frame */
+                       memset(encoded_data, 0,
+                           sizeof(short)*ILBCNOOFWORDS_MAX);
+                       packetlosscount++;
+                   }
+               } else {
+                   fprintf(stderr, "Error. Channel file too short\n");
+                   exit(0);
+               }
+           } else {
+               pli=1;
+           }
+
+           /* decoding */
+
+           fprintf(stderr, "--- Decoding block %i --- ",blockcount);
+
+           len=decode(&Dec_Inst, decoded_data, encoded_data, pli);
+           fprintf(stderr, "\r");
+
+           /* write output file */
+
+           fwrite(decoded_data,sizeof(short),len,ofileid);
+       }
+
+       /* Runtime statistics */
+
+       runtime = (float)(clock()/(float)CLOCKS_PER_SEC-starttime);
+       outtime = (float)((float)blockcount*(float)mode/1000.0);
+       printf("\n\nLength of speech file: %.1f s\n", outtime);
+       printf("Packet loss          : %.1f%%\n",
+           100.0*(float)packetlosscount/(float)blockcount);
+
+
+
+
+
+       printf("Time to run iLBC     :");
+       printf(" %.1f s (%.1f %% of realtime)\n\n", runtime,
+           (100*runtime/outtime));
+
+       /* close files */
+
+       fclose(ifileid);  fclose(efileid); fclose(ofileid);
+       if (argc==6) {
+           fclose(cfileid);
+       }
+       return(0);
+   }
+
diff --git a/jni/pjproject-android/.svn/pristine/c0/c0a5700d902be76ad8d726b2ffe9ffac0e2c760a.svn-base b/jni/pjproject-android/.svn/pristine/c0/c0a5700d902be76ad8d726b2ffe9ffac0e2c760a.svn-base
new file mode 100644
index 0000000..93be0a8
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c0a5700d902be76ad8d726b2ffe9ffac0e2c760a.svn-base
@@ -0,0 +1,587 @@
+/* $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 <pjsip.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+
+/* Options */
+static struct global_struct
+{
+    pj_caching_pool	 cp;
+    pjsip_endpoint	*endpt;
+    int			 port;
+    pj_pool_t		*pool;
+
+    pj_thread_t		*thread;
+    pj_bool_t		 quit_flag;
+
+    pj_bool_t		 record_route;
+
+    unsigned		 name_cnt;
+    pjsip_host_port	 name[16];
+} global;
+
+
+
+static void app_perror(const char *msg, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "%s: %s", msg, errmsg));
+}
+
+
+static void usage(void)
+{
+    puts("Options:\n"
+	 "\n"
+	 " -p, --port N       Set local listener port to N\n"
+	 " -R, --rr           Perform record routing\n"
+	 " -L, --log-level N  Set log level to N (default: 4)\n"
+	 " -h, --help         Show this help screen\n"
+	 );
+}
+
+
+static pj_status_t init_options(int argc, char *argv[])
+{
+    struct pj_getopt_option long_opt[] = {
+	{ "port",	1, 0, 'p'},
+	{ "rr",		0, 0, 'R'},
+	{ "log-level",	1, 0, 'L'},
+	{ "help",	0, 0, 'h'},
+	{ NULL,		0, 0, 0}
+    };
+    int c;
+    int opt_ind;
+
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc, argv, "p:L:Rh", long_opt, &opt_ind))!=-1) {
+	switch (c) {
+	case 'p':
+	    global.port = atoi(pj_optarg);
+	    printf("Port is set to %d\n", global.port);
+	    break;
+	
+	case 'R':
+	    global.record_route = PJ_TRUE;
+	    printf("Using record route mode\n");
+	    break;
+
+	case 'L':
+	    pj_log_set_level(atoi(pj_optarg));
+	    break;
+
+	case 'h':
+	    usage();
+	    return -1;
+
+	default:
+	    puts("Unknown option. Run with --help for help.");
+	    return -1;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * This is a very simple PJSIP module, whose sole purpose is to display
+ * incoming and outgoing messages to log. This module will have priority
+ * higher than transport layer, which means:
+ *
+ *  - incoming messages will come to this module first before reaching
+ *    transaction layer.
+ *
+ *  - outgoing messages will come to this module last, after the message
+ *    has been 'printed' to contiguous buffer by transport layer and
+ *    appropriate transport instance has been decided for this message.
+ *
+ */
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(5,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->tp_info.transport->type_name,
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 (int)rdata->msg_info.len,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(5,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.transport->type_name,
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 (int)(tdata->buf.cur - tdata->buf.start),
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module mod_msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-msg-logger", 14 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logging_on_rx_msg,			/* on_rx_request()	*/
+    &logging_on_rx_msg,			/* on_rx_response()	*/
+    &logging_on_tx_msg,			/* on_tx_request.	*/
+    &logging_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+
+static pj_status_t init_stack(void)
+{
+    pj_status_t status;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Then init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&global.cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create the endpoint: */
+    status = pjsip_endpt_create(&global.cp.factory, NULL, &global.endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Init transaction layer for stateful proxy only */
+#if STATEFUL
+    status = pjsip_tsx_layer_init_module(global.endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+#endif
+
+    /* Create listening transport */
+    {
+	pj_sockaddr_in addr;
+
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons((pj_uint16_t)global.port);
+
+	status = pjsip_udp_transport_start( global.endpt, &addr, 
+					    NULL, 1, NULL);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+
+    /* Create pool for the application */
+    global.pool = pj_pool_create(&global.cp.factory, "proxyapp", 
+				 4000, 4000, NULL);
+
+    /* Register the logger module */
+    pjsip_endpt_register_module(global.endpt, &mod_msg_logger);
+
+    return PJ_SUCCESS;
+}
+
+
+static pj_status_t init_proxy(void)
+{
+    pj_sockaddr pri_addr;
+    pj_sockaddr addr_list[16];
+    unsigned addr_cnt = PJ_ARRAY_SIZE(addr_list);
+    unsigned i;
+
+    /* List all names matching local endpoint.
+     * Note that PJLIB version 0.6 and newer has a function to
+     * enumerate local IP interface (pj_enum_ip_interface()), so
+     * by using it would be possible to list all IP interfaces in
+     * this host.
+     */
+
+    /* The first address is important since this would be the one
+     * to be added in Record-Route.
+     */
+    if (pj_gethostip(pj_AF_INET(), &pri_addr)==PJ_SUCCESS) {
+	pj_strdup2(global.pool, &global.name[global.name_cnt].host,
+		   pj_inet_ntoa(pri_addr.ipv4.sin_addr));
+	global.name[global.name_cnt].port = global.port;
+	global.name_cnt++;
+    }
+
+    /* Get the rest of IP interfaces */
+    if (pj_enum_ip_interface(pj_AF_INET(), &addr_cnt, addr_list) == PJ_SUCCESS) {
+	for (i=0; i<addr_cnt; ++i) {
+
+	    if (addr_list[i].ipv4.sin_addr.s_addr == pri_addr.ipv4.sin_addr.s_addr)
+		continue;
+
+	    pj_strdup2(global.pool, &global.name[global.name_cnt].host,
+		       pj_inet_ntoa(addr_list[i].ipv4.sin_addr));
+	    global.name[global.name_cnt].port = global.port;
+	    global.name_cnt++;
+	}
+    }
+
+    /* Add loopback address. */
+#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF
+    global.name[global.name_cnt].host = pj_str("127.0.0.1");
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+#endif
+
+    global.name[global.name_cnt].host = *pj_gethostname();
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+
+    global.name[global.name_cnt].host = pj_str("localhost");
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+
+    PJ_LOG(3,(THIS_FILE, "Proxy started, listening on port %d", global.port));
+    PJ_LOG(3,(THIS_FILE, "Local host aliases:"));
+    for (i=0; i<global.name_cnt; ++i) {
+	PJ_LOG(3,(THIS_FILE, " %.*s:%d", 
+		  (int)global.name[i].host.slen,
+		  global.name[i].host.ptr,
+		  global.name[i].port));
+    }
+
+    if (global.record_route) {
+	PJ_LOG(3,(THIS_FILE, "Using Record-Route mode"));
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+#if PJ_HAS_THREADS
+static int worker_thread(void *p)
+{
+    pj_time_val delay = {0, 10};
+
+    PJ_UNUSED_ARG(p);
+
+    while (!global.quit_flag) {
+	pjsip_endpt_handle_events(global.endpt, &delay);
+    }
+
+    return 0;
+}
+#endif
+
+
+/* Utility to determine if URI is local to this host. */
+static pj_bool_t is_uri_local(const pjsip_sip_uri *uri)
+{
+    unsigned i;
+    for (i=0; i<global.name_cnt; ++i) {
+	if ((uri->port == global.name[i].port ||
+	     (uri->port==0 && global.name[i].port==5060)) &&
+	    pj_stricmp(&uri->host, &global.name[i].host)==0)
+	{
+	    /* Match */
+	    return PJ_TRUE;
+	}
+    }
+
+    /* Doesn't match */
+    return PJ_FALSE;
+}
+
+
+/* Proxy utility to verify incoming requests.
+ * Return non-zero if verification failed.
+ */
+static pj_status_t proxy_verify_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t STR_PROXY_REQUIRE = {"Proxy-Require", 13};
+
+    /* RFC 3261 Section 16.3 Request Validation */
+
+    /* Before an element can proxy a request, it MUST verify the message's
+     * validity.  A valid message must pass the following checks:
+     * 
+     * 1. Reasonable Syntax
+     * 2. URI scheme
+     * 3. Max-Forwards
+     * 4. (Optional) Loop Detection
+     * 5. Proxy-Require
+     * 6. Proxy-Authorization
+     */
+
+    /* 1. Reasonable Syntax.
+     * This would have been checked by transport layer.
+     */
+
+    /* 2. URI scheme.
+     * We only want to support "sip:"/"sips:" URI scheme for this simple proxy.
+     */
+    if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.msg->line.req.uri) &&
+	!PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
+    {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_UNSUPPORTED_URI_SCHEME, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_UNSUPPORTED_URI_SCHEME);
+    }
+
+    /* 3. Max-Forwards.
+     * Send error if Max-Forwards is 1 or lower.
+     */
+    if (rdata->msg_info.max_fwd && rdata->msg_info.max_fwd->ivalue <= 1) {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_TOO_MANY_HOPS, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_TOO_MANY_HOPS);
+    }
+
+    /* 4. (Optional) Loop Detection.
+     * Nah, we don't do that with this simple proxy.
+     */
+
+    /* 5. Proxy-Require */
+    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_PROXY_REQUIRE, 
+				   NULL) != NULL) 
+    {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_BAD_EXTENSION, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EXTENSION);
+    }
+
+    /* 6. Proxy-Authorization.
+     * Nah, we don't require any authorization with this sample.
+     */
+
+    return PJ_SUCCESS;
+}
+
+
+/* Process route information in the reqeust */
+static pj_status_t proxy_process_routing(pjsip_tx_data *tdata)
+{
+    pjsip_sip_uri *target;
+    pjsip_route_hdr *hroute;
+
+    /* RFC 3261 Section 16.4 Route Information Preprocessing */
+
+    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+
+    /* The proxy MUST inspect the Request-URI of the request.  If the
+     * Request-URI of the request contains a value this proxy previously
+     * placed into a Record-Route header field (see Section 16.6 item 4),
+     * the proxy MUST replace the Request-URI in the request with the last
+     * value from the Route header field, and remove that value from the
+     * Route header field.  The proxy MUST then proceed as if it received
+     * this modified request.
+     */
+    if (is_uri_local(target)) {
+	pjsip_route_hdr *r;
+	pjsip_sip_uri *uri;
+
+	/* Find the first Route header */
+	r = hroute = (pjsip_route_hdr*)
+		     pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+	if (r == NULL) {
+	    /* No Route header. This request is destined for this proxy. */
+	    return PJ_SUCCESS;
+	}
+
+	/* Find the last Route header */
+	while ( (r=(pjsip_route_hdr*)pjsip_msg_find_hdr(tdata->msg, 
+						        PJSIP_H_ROUTE, 
+							r->next)) != NULL )
+	{
+	    hroute = r;
+	}
+
+	/* If the last Route header doesn't have ";lr" parameter, then
+	 * this is a strict-routed request indeed, and we follow the steps
+	 * in processing strict-route requests above.
+	 *
+	 * But if it does contain ";lr" parameter, skip the strict-route
+	 * processing.
+	 */
+	uri = (pjsip_sip_uri*)
+	      pjsip_uri_get_uri(&hroute->name_addr);
+	if (uri->lr_param == 0) {
+	    /* Yes this is strict route, so:
+	     * - replace req URI with the URI in Route header,
+	     * - remove the Route header,
+	     * - proceed as if it received this modified request. 
+	    */
+	    tdata->msg->line.req.uri = hroute->name_addr.uri;
+	    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+	    pj_list_erase(hroute);
+	}
+    }
+
+    /* If the Request-URI contains a maddr parameter, the proxy MUST check
+     * to see if its value is in the set of addresses or domains the proxy
+     * is configured to be responsible for.  If the Request-URI has a maddr
+     * parameter with a value the proxy is responsible for, and the request
+     * was received using the port and transport indicated (explicitly or by
+     * default) in the Request-URI, the proxy MUST strip the maddr and any
+     * non-default port or transport parameter and continue processing as if
+     * those values had not been present in the request.
+     */
+    if (target->maddr_param.slen != 0) {
+	pjsip_sip_uri maddr_uri;
+
+	maddr_uri.host = target->maddr_param;
+	maddr_uri.port = global.port;
+
+	if (is_uri_local(&maddr_uri)) {
+	    target->maddr_param.slen = 0;
+	    target->port = 0;
+	    target->transport_param.slen = 0;
+	}
+    }
+
+    /* If the first value in the Route header field indicates this proxy,
+     * the proxy MUST remove that value from the request.
+     */
+    hroute = (pjsip_route_hdr*) 
+	      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+    if (hroute && is_uri_local((pjsip_sip_uri*)hroute->name_addr.uri)) {
+	pj_list_erase(hroute);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/* Postprocess the request before forwarding it */
+static void proxy_postprocess(pjsip_tx_data *tdata)
+{
+    /* Optionally record-route */
+    if (global.record_route) {
+	char uribuf[128];
+	pj_str_t uri;
+	const pj_str_t H_RR = { "Record-Route", 12 };
+	pjsip_generic_string_hdr *rr;
+
+	pj_ansi_snprintf(uribuf, sizeof(uribuf), "<sip:%.*s:%d;lr>",
+			 (int)global.name[0].host.slen,
+			 global.name[0].host.ptr,
+			 global.name[0].port);
+	uri = pj_str(uribuf);
+	rr = pjsip_generic_string_hdr_create(tdata->pool,
+					     &H_RR, &uri);
+	pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)rr);
+    }
+}
+
+
+/* Calculate new target for the request */
+static pj_status_t proxy_calculate_target(pjsip_rx_data *rdata,
+					  pjsip_tx_data *tdata)
+{
+    pjsip_sip_uri *target;
+
+    /* RFC 3261 Section 16.5 Determining Request Targets */
+
+    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+
+    /* If the Request-URI of the request contains an maddr parameter, the
+     * Request-URI MUST be placed into the target set as the only target
+     * URI, and the proxy MUST proceed to Section 16.6.
+     */
+    if (target->maddr_param.slen) {
+	proxy_postprocess(tdata);
+	return PJ_SUCCESS;
+    }
+
+
+    /* If the domain of the Request-URI indicates a domain this element is
+     * not responsible for, the Request-URI MUST be placed into the target
+     * set as the only target, and the element MUST proceed to the task of
+     * Request Forwarding (Section 16.6).
+     */
+    if (!is_uri_local(target)) {
+	proxy_postprocess(tdata);
+	return PJ_SUCCESS;
+    }
+
+    /* If the target set for the request has not been predetermined as
+     * described above, this implies that the element is responsible for the
+     * domain in the Request-URI, and the element MAY use whatever mechanism
+     * it desires to determine where to send the request. 
+     */
+
+    /* We're not interested to receive request destined to us, so
+     * respond with 404/Not Found (only if request is not ACK!).
+     */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	pjsip_endpt_respond_stateless(global.endpt, rdata,
+				      PJSIP_SC_NOT_FOUND, NULL,
+				      NULL, NULL);
+    }
+
+    /* Delete the request since we're not forwarding it */
+    pjsip_tx_data_dec_ref(tdata);
+
+    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_FOUND);
+}
+
+
+/* Destroy stack */
+static void destroy_stack(void)
+{
+    pjsip_endpt_destroy(global.endpt);
+    pj_pool_release(global.pool);
+    pj_caching_pool_destroy(&global.cp);
+
+    pj_shutdown();
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/c0/c0d071c727381f84cfd788bebdba1be9168686f4.svn-base b/jni/pjproject-android/.svn/pristine/c0/c0d071c727381f84cfd788bebdba1be9168686f4.svn-base
new file mode 100644
index 0000000..d7a68cd
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c0d071c727381f84cfd788bebdba1be9168686f4.svn-base
@@ -0,0 +1,170 @@
+/* $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 <pj/file_io.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <stdio.h>
+#include <errno.h>
+
+PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,
+                                  const char *pathname, 
+                                  unsigned flags,
+                                  pj_oshandle_t *fd)
+{
+    char mode[8];
+    char *p = mode;
+
+    PJ_ASSERT_RETURN(pathname && fd, PJ_EINVAL);
+    PJ_UNUSED_ARG(pool);
+
+    if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {
+        if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) {
+            *p++ = 'a';
+            if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY)
+                *p++ = '+';
+        } else {
+            /* This is invalid.
+             * Can not specify PJ_O_RDONLY with PJ_O_APPEND! 
+             */
+        }
+    } else {
+        if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) {
+            *p++ = 'r';
+            if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY)
+                *p++ = '+';
+        } else {
+            *p++ = 'w';
+        }
+    }
+
+    if (p==mode)
+        return PJ_EINVAL;
+
+    *p++ = 'b';
+    *p++ = '\0';
+
+    *fd = fopen(pathname, mode);
+    if (*fd == NULL)
+        return PJ_RETURN_OS_ERROR(errno);
+    
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_file_close(pj_oshandle_t fd)
+{
+    PJ_ASSERT_RETURN(fd, PJ_EINVAL);
+    if (fclose((FILE*)fd) != 0)
+        return PJ_RETURN_OS_ERROR(errno);
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_file_write( pj_oshandle_t fd,
+                                   const void *data,
+                                   pj_ssize_t *size)
+{
+    size_t written;
+
+    clearerr((FILE*)fd);
+    written = fwrite(data, 1, *size, (FILE*)fd);
+    if (ferror((FILE*)fd)) {
+        *size = -1;
+        return PJ_RETURN_OS_ERROR(errno);
+    }
+
+    *size = written;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_file_read( pj_oshandle_t fd,
+                                  void *data,
+                                  pj_ssize_t *size)
+{
+    size_t bytes;
+
+    clearerr((FILE*)fd);
+    bytes = fread(data, 1, *size, (FILE*)fd);
+    if (ferror((FILE*)fd)) {
+        *size = -1;
+        return PJ_RETURN_OS_ERROR(errno);
+    }
+
+    *size = bytes;
+    return PJ_SUCCESS;
+}
+
+/*
+PJ_DEF(pj_bool_t) pj_file_eof(pj_oshandle_t fd, enum pj_file_access access)
+{
+    PJ_UNUSED_ARG(access);
+    return feof((FILE*)fd) ? PJ_TRUE : 0;
+}
+*/
+
+PJ_DEF(pj_status_t) pj_file_setpos( pj_oshandle_t fd,
+                                    pj_off_t offset,
+                                    enum pj_file_seek_type whence)
+{
+    int mode;
+
+    switch (whence) {
+    case PJ_SEEK_SET:
+        mode = SEEK_SET; break;
+    case PJ_SEEK_CUR:
+        mode = SEEK_CUR; break;
+    case PJ_SEEK_END:
+        mode = SEEK_END; break;
+    default:
+        pj_assert(!"Invalid whence in file_setpos");
+        return PJ_EINVAL;
+    }
+
+    if (fseek((FILE*)fd, (long)offset, mode) != 0)
+        return PJ_RETURN_OS_ERROR(errno);
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_file_getpos( pj_oshandle_t fd,
+                                    pj_off_t *pos)
+{
+    long offset;
+
+    offset = ftell((FILE*)fd);
+    if (offset == -1) {
+        *pos = -1;
+        return PJ_RETURN_OS_ERROR(errno);
+    }
+
+    *pos = offset;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_file_flush(pj_oshandle_t fd)
+{
+    int rc;
+
+    rc = fflush((FILE*)fd);
+    if (rc == EOF) {
+	return PJ_RETURN_OS_ERROR(errno);
+    }
+
+    return PJ_SUCCESS;
+}
diff --git a/jni/pjproject-android/.svn/pristine/c0/c0dd8052eb7d05dc0c0a892e15b459d2bd64433e.svn-base b/jni/pjproject-android/.svn/pristine/c0/c0dd8052eb7d05dc0c0a892e15b459d2bd64433e.svn-base
new file mode 100644
index 0000000..2b64c30
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c0/c0dd8052eb7d05dc0c0a892e15b459d2bd64433e.svn-base
@@ -0,0 +1,12 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Simple call
+test_param = TestParam(
+		"tel: URI in From",
+		[
+			InstanceParam("callee", "--null-audio --max-calls=1 --id tel:+111"),
+			InstanceParam("caller", "--null-audio --max-calls=1")
+		]
+		)