* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/19/191cf8126582eedbdd2bb04467cbeb4027c7c97c.svn-base b/jni/pjproject-android/.svn/pristine/19/191cf8126582eedbdd2bb04467cbeb4027c7c97c.svn-base
new file mode 100644
index 0000000..dacc2f8
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/19/191cf8126582eedbdd2bb04467cbeb4027c7c97c.svn-base
@@ -0,0 +1,58 @@
+/* $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/sip_config.h>
+
+/* pjsip configuration instance, initialized with default values */
+pjsip_cfg_t pjsip_sip_cfg_var =
+{
+    /* Global settings */
+    {
+       PJSIP_ALLOW_PORT_IN_FROMTO_HDR,
+       PJSIP_ACCEPT_REPLACE_IN_EARLY_STATE,
+       0,
+       0,
+       PJSIP_DONT_SWITCH_TO_TCP,
+       PJSIP_FOLLOW_EARLY_MEDIA_FORK,
+       PJSIP_REQ_HAS_VIA_ALIAS
+    },
+
+    /* Transaction settings */
+    {
+       PJSIP_MAX_TSX_COUNT,
+       PJSIP_T1_TIMEOUT,
+       PJSIP_T2_TIMEOUT,
+       PJSIP_T4_TIMEOUT,
+       PJSIP_TD_TIMEOUT
+    },
+
+    /* Client registration client */
+    {
+	PJSIP_REGISTER_CLIENT_CHECK_CONTACT
+    }
+};
+
+
+#ifdef PJ_DLL
+PJ_DEF(pjsip_cfg_t*) pjsip_cfg(void)
+{
+    return &pjsip_sip_cfg_var;
+}
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/19/197269a90d4821f98f74d82b225a796bdc49d0ff.svn-base b/jni/pjproject-android/.svn/pristine/19/197269a90d4821f98f74d82b225a796bdc49d0ff.svn-base
new file mode 100644
index 0000000..57a468c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/19/197269a90d4821f98f74d82b225a796bdc49d0ff.svn-base
@@ -0,0 +1,972 @@
+/* $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 "test.h"
+
+/**
+ * \page page_pjlib_ioqueue_tcp_test Test: I/O Queue (TCP)
+ *
+ * This file provides implementation to test the
+ * functionality of the I/O queue when TCP socket is used.
+ *
+ *
+ * This file is <b>pjlib-test/ioq_tcp.c</b>
+ *
+ * \include pjlib-test/ioq_tcp.c
+ */
+
+
+#if INCLUDE_TCP_IOQUEUE_TEST
+
+#include <pjlib.h>
+
+#if PJ_HAS_TCP
+
+#define THIS_FILE	    "test_tcp"
+#define NON_EXISTANT_PORT   50123
+#define LOOP		    100
+#define BUF_MIN_SIZE	    32
+#define BUF_MAX_SIZE	    2048
+#define SOCK_INACTIVE_MIN   (4-2)
+#define SOCK_INACTIVE_MAX   (PJ_IOQUEUE_MAX_HANDLES - 2)
+#define POOL_SIZE	    (2*BUF_MAX_SIZE + SOCK_INACTIVE_MAX*128 + 2048)
+
+static pj_ssize_t	     callback_read_size,
+                             callback_write_size,
+                             callback_accept_status,
+                             callback_connect_status;
+static unsigned		     callback_call_count;
+static pj_ioqueue_key_t     *callback_read_key,
+                            *callback_write_key,
+                            *callback_accept_key,
+                            *callback_connect_key;
+static pj_ioqueue_op_key_t  *callback_read_op,
+                            *callback_write_op,
+                            *callback_accept_op;
+
+static void on_ioqueue_read(pj_ioqueue_key_t *key, 
+                            pj_ioqueue_op_key_t *op_key,
+                            pj_ssize_t bytes_read)
+{
+    callback_read_key = key;
+    callback_read_op = op_key;
+    callback_read_size = bytes_read;
+    callback_call_count++;
+}
+
+static void on_ioqueue_write(pj_ioqueue_key_t *key, 
+                             pj_ioqueue_op_key_t *op_key,
+                             pj_ssize_t bytes_written)
+{
+    callback_write_key = key;
+    callback_write_op = op_key;
+    callback_write_size = bytes_written;
+    callback_call_count++;
+}
+
+static void on_ioqueue_accept(pj_ioqueue_key_t *key, 
+                              pj_ioqueue_op_key_t *op_key,
+                              pj_sock_t sock, 
+                              int status)
+{
+    if (sock == PJ_INVALID_SOCKET) {
+
+	if (status != PJ_SUCCESS) {
+	    /* Ignore. Could be blocking error */
+	    app_perror(".....warning: received error in on_ioqueue_accept() callback",
+		       status);
+	} else {
+	    callback_accept_status = -61;
+	    PJ_LOG(3,("", "..... on_ioqueue_accept() callback was given "
+			  "invalid socket and status is %d", status));
+	}
+    } else {
+        pj_sockaddr addr;
+        int client_addr_len;
+
+        client_addr_len = sizeof(addr);
+        status = pj_sock_getsockname(sock, &addr, &client_addr_len);
+        if (status != PJ_SUCCESS) {
+            app_perror("...ERROR in pj_sock_getsockname()", status);
+        }
+
+	callback_accept_key = key;
+	callback_accept_op = op_key;
+	callback_accept_status = status;
+	callback_call_count++;
+    }
+}
+
+static void on_ioqueue_connect(pj_ioqueue_key_t *key, int status)
+{
+    callback_connect_key = key;
+    callback_connect_status = status;
+    callback_call_count++;
+}
+
+static pj_ioqueue_callback test_cb = 
+{
+    &on_ioqueue_read,
+    &on_ioqueue_write,
+    &on_ioqueue_accept,
+    &on_ioqueue_connect,
+};
+
+static int send_recv_test(pj_ioqueue_t *ioque,
+			  pj_ioqueue_key_t *skey,
+			  pj_ioqueue_key_t *ckey,
+			  void *send_buf,
+			  void *recv_buf,
+			  pj_ssize_t bufsize,
+			  pj_timestamp *t_elapsed)
+{
+    pj_status_t status;
+    pj_ssize_t bytes;
+    pj_time_val timeout;
+    pj_timestamp t1, t2;
+    int pending_op = 0;
+    pj_ioqueue_op_key_t read_op, write_op;
+
+    // Start reading on the server side.
+    bytes = bufsize;
+    status = pj_ioqueue_recv(skey, &read_op, recv_buf, &bytes, 0);
+    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
+        app_perror("...pj_ioqueue_recv error", status);
+	return -100;
+    }
+    
+    if (status == PJ_EPENDING)
+        ++pending_op;
+    else {
+        /* Does not expect to return error or immediate data. */
+        return -115;
+    }
+
+    // Randomize send buffer.
+    pj_create_random_string((char*)send_buf, bufsize);
+
+    // Starts send on the client side.
+    bytes = bufsize;
+    status = pj_ioqueue_send(ckey, &write_op, send_buf, &bytes, 0);
+    if (status != PJ_SUCCESS && bytes != PJ_EPENDING) {
+	return -120;
+    }
+    if (status == PJ_EPENDING) {
+	++pending_op;
+    }
+
+    // Begin time.
+    pj_get_timestamp(&t1);
+
+    // Reset indicators
+    callback_read_size = callback_write_size = 0;
+    callback_read_key = callback_write_key = NULL;
+    callback_read_op = callback_write_op = NULL;
+
+    // Poll the queue until we've got completion event in the server side.
+    status = 0;
+    while (pending_op > 0) {
+        timeout.sec = 1; timeout.msec = 0;
+#ifdef PJ_SYMBIAN
+	PJ_UNUSED_ARG(ioque);
+	status = pj_symbianos_poll(-1, 1000);
+#else
+	status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+	if (status > 0) {
+            if (callback_read_size) {
+                if (callback_read_size != bufsize)
+                    return -160;
+                if (callback_read_key != skey)
+                    return -161;
+                if (callback_read_op != &read_op)
+                    return -162;
+            }
+            if (callback_write_size) {
+                if (callback_write_key != ckey)
+                    return -163;
+                if (callback_write_op != &write_op)
+                    return -164;
+            }
+	    pending_op -= status;
+	}
+        if (status == 0) {
+            PJ_LOG(3,("", "...error: timed out"));
+        }
+	if (status < 0) {
+	    return -170;
+	}
+    }
+
+    // Pending op is zero.
+    // Subsequent poll should yield zero too.
+    timeout.sec = timeout.msec = 0;
+#ifdef PJ_SYMBIAN
+    status = pj_symbianos_poll(-1, 1);
+#else
+    status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+    if (status != 0)
+        return -173;
+
+    // End time.
+    pj_get_timestamp(&t2);
+    t_elapsed->u32.lo += (t2.u32.lo - t1.u32.lo);
+
+    // Compare recv buffer with send buffer.
+    if (pj_memcmp(send_buf, recv_buf, bufsize) != 0) {
+	return -180;
+    }
+
+    // Success
+    return 0;
+}
+
+
+/*
+ * Compliance test for success scenario.
+ */
+static int compliance_test_0(pj_bool_t allow_concur)
+{
+    pj_sock_t ssock=-1, csock0=-1, csock1=-1;
+    pj_sockaddr_in addr, client_addr, rmt_addr;
+    int client_addr_len;
+    pj_pool_t *pool = NULL;
+    char *send_buf, *recv_buf;
+    pj_ioqueue_t *ioque = NULL;
+    pj_ioqueue_key_t *skey=NULL, *ckey0=NULL, *ckey1=NULL;
+    pj_ioqueue_op_key_t accept_op;
+    int bufsize = BUF_MIN_SIZE;
+    int status = -1;
+    int pending_op = 0;
+    pj_timestamp t_elapsed;
+    pj_str_t s;
+    pj_status_t rc;
+
+    // Create pool.
+    pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
+
+    // Allocate buffers for send and receive.
+    send_buf = (char*)pj_pool_alloc(pool, bufsize);
+    recv_buf = (char*)pj_pool_alloc(pool, bufsize);
+
+    // Create server socket and client socket for connecting
+    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &ssock);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...error creating socket", rc);
+        status=-1; goto on_error;
+    }
+
+    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &csock1);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...error creating socket", rc);
+	status=-1; goto on_error;
+    }
+
+    // Bind server socket.
+    pj_sockaddr_in_init(&addr, 0, 0);
+    if ((rc=pj_sock_bind(ssock, &addr, sizeof(addr))) != 0 ) {
+        app_perror("...bind error", rc);
+	status=-10; goto on_error;
+    }
+
+    // Get server address.
+    client_addr_len = sizeof(addr);
+    rc = pj_sock_getsockname(ssock, &addr, &client_addr_len);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_sock_getsockname()", rc);
+	status=-15; goto on_error;
+    }
+    addr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
+
+    // Create I/O Queue.
+    rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_create()", rc);
+	status=-20; goto on_error;
+    }
+
+    // Concurrency
+    rc = pj_ioqueue_set_default_concurrency(ioque, allow_concur);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_set_default_concurrency()", rc);
+	status=-21; goto on_error;
+    }
+
+    // Register server socket and client socket.
+    rc = pj_ioqueue_register_sock(pool, ioque, ssock, NULL, &test_cb, &skey);
+    if (rc == PJ_SUCCESS)
+        rc = pj_ioqueue_register_sock(pool, ioque, csock1, NULL, &test_cb, 
+                                      &ckey1);
+    else
+        ckey1 = NULL;
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_register_sock()", rc);
+	status=-23; goto on_error;
+    }
+
+    // Server socket listen().
+    if (pj_sock_listen(ssock, 5)) {
+        app_perror("...ERROR in pj_sock_listen()", rc);
+	status=-25; goto on_error;
+    }
+
+    // Server socket accept()
+    client_addr_len = sizeof(pj_sockaddr_in);
+    status = pj_ioqueue_accept(skey, &accept_op, &csock0, 
+                               &client_addr, &rmt_addr, &client_addr_len);
+    if (status != PJ_EPENDING) {
+        app_perror("...ERROR in pj_ioqueue_accept()", rc);
+	status=-30; goto on_error;
+    }
+    if (status==PJ_EPENDING) {
+	++pending_op;
+    }
+
+    // Client socket connect()
+    status = pj_ioqueue_connect(ckey1, &addr, sizeof(addr));
+    if (status!=PJ_SUCCESS && status != PJ_EPENDING) {
+        app_perror("...ERROR in pj_ioqueue_connect()", rc);
+	status=-40; goto on_error;
+    }
+    if (status==PJ_EPENDING) {
+	++pending_op;
+    }
+
+    // Poll until connected
+    callback_read_size = callback_write_size = 0;
+    callback_accept_status = callback_connect_status = -2;
+    callback_call_count = 0;
+
+    callback_read_key = callback_write_key = 
+        callback_accept_key = callback_connect_key = NULL;
+    callback_accept_op = callback_read_op = callback_write_op = NULL;
+
+    while (pending_op) {
+	pj_time_val timeout = {1, 0};
+
+#ifdef PJ_SYMBIAN
+	callback_call_count = 0;
+	pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+	status = callback_call_count;
+#else
+	status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+	if (status > 0) {
+            if (callback_accept_status != -2) {
+                if (callback_accept_status != 0) {
+                    status=-41; goto on_error;
+                }
+                if (callback_accept_key != skey) {
+                    status=-42; goto on_error;
+                }
+                if (callback_accept_op != &accept_op) {
+                    status=-43; goto on_error;
+                }
+                callback_accept_status = -2;
+            }
+
+            if (callback_connect_status != -2) {
+                if (callback_connect_status != 0) {
+                    status=-50; goto on_error;
+                }
+                if (callback_connect_key != ckey1) {
+                    status=-51; goto on_error;
+                }
+                callback_connect_status = -2;
+            }
+
+	    if (status > pending_op) {
+		PJ_LOG(3,(THIS_FILE,
+			  "...error: pj_ioqueue_poll() returned %d "
+			  "(only expecting %d)",
+			  status, pending_op));
+		return -52;
+	    }
+	    pending_op -= status;
+
+	    if (pending_op == 0) {
+		status = 0;
+	    }
+	}
+    }
+
+    // There's no pending operation.
+    // When we poll the ioqueue, there must not be events.
+    if (pending_op == 0) {
+        pj_time_val timeout = {1, 0};
+#ifdef PJ_SYMBIAN
+	status = pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+#else
+        status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+        if (status != 0) {
+            status=-60; goto on_error;
+        }
+    }
+
+    // Check accepted socket.
+    if (csock0 == PJ_INVALID_SOCKET) {
+	status = -69;
+        app_perror("...accept() error", pj_get_os_error());
+	goto on_error;
+    }
+
+    // Register newly accepted socket.
+    rc = pj_ioqueue_register_sock(pool, ioque, csock0, NULL, 
+                                  &test_cb, &ckey0);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_register_sock", rc);
+	status = -70;
+	goto on_error;
+    }
+
+    // Test send and receive.
+    t_elapsed.u32.lo = 0;
+    status = send_recv_test(ioque, ckey0, ckey1, send_buf, 
+                            recv_buf, bufsize, &t_elapsed);
+    if (status != 0) {
+	goto on_error;
+    }
+
+    // Success
+    status = 0;
+
+on_error:
+    if (skey != NULL)
+    	pj_ioqueue_unregister(skey);
+    else if (ssock != PJ_INVALID_SOCKET)
+	pj_sock_close(ssock);
+    
+    if (ckey1 != NULL)
+    	pj_ioqueue_unregister(ckey1);
+    else if (csock1 != PJ_INVALID_SOCKET)
+	pj_sock_close(csock1);
+    
+    if (ckey0 != NULL)
+    	pj_ioqueue_unregister(ckey0);
+    else if (csock0 != PJ_INVALID_SOCKET)
+	pj_sock_close(csock0);
+    
+    if (ioque != NULL)
+	pj_ioqueue_destroy(ioque);
+    pj_pool_release(pool);
+    return status;
+
+}
+
+/*
+ * Compliance test for failed scenario.
+ * In this case, the client connects to a non-existant service.
+ */
+static int compliance_test_1(pj_bool_t allow_concur)
+{
+    pj_sock_t csock1=PJ_INVALID_SOCKET;
+    pj_sockaddr_in addr;
+    pj_pool_t *pool = NULL;
+    pj_ioqueue_t *ioque = NULL;
+    pj_ioqueue_key_t *ckey1 = NULL;
+    int status = -1;
+    int pending_op = 0;
+    pj_str_t s;
+    pj_status_t rc;
+
+    // Create pool.
+    pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
+
+    // Create I/O Queue.
+    rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque);
+    if (!ioque) {
+	status=-20; goto on_error;
+    }
+
+    // Concurrency
+    rc = pj_ioqueue_set_default_concurrency(ioque, allow_concur);
+    if (rc != PJ_SUCCESS) {
+	status=-21; goto on_error;
+    }
+
+    // Create client socket
+    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &csock1);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_sock_socket()", rc);
+	status=-1; goto on_error;
+    }
+
+    // Register client socket.
+    rc = pj_ioqueue_register_sock(pool, ioque, csock1, NULL, 
+                                  &test_cb, &ckey1);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_register_sock()", rc);
+	status=-23; goto on_error;
+    }
+
+    // Initialize remote address.
+    pj_sockaddr_in_init(&addr, pj_cstr(&s, "127.0.0.1"), NON_EXISTANT_PORT);
+
+    // Client socket connect()
+    status = pj_ioqueue_connect(ckey1, &addr, sizeof(addr));
+    if (status==PJ_SUCCESS) {
+	// unexpectedly success!
+	status = -30;
+	goto on_error;
+    }
+    if (status != PJ_EPENDING) {
+	// success
+    } else {
+	++pending_op;
+    }
+
+    callback_connect_status = -2;
+    callback_connect_key = NULL;
+
+    // Poll until we've got result
+    while (pending_op) {
+	pj_time_val timeout = {1, 0};
+
+#ifdef PJ_SYMBIAN
+	callback_call_count = 0;
+	pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+	status = callback_call_count;
+#else
+	status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+	if (status > 0) {
+            if (callback_connect_key==ckey1) {
+		if (callback_connect_status == 0) {
+		    // unexpectedly connected!
+		    status = -50;
+		    goto on_error;
+		}
+	    }
+
+	    if (status > pending_op) {
+		PJ_LOG(3,(THIS_FILE,
+			  "...error: pj_ioqueue_poll() returned %d "
+			  "(only expecting %d)",
+			  status, pending_op));
+		return -552;
+	    }
+
+	    pending_op -= status;
+	    if (pending_op == 0) {
+		status = 0;
+	    }
+	}
+    }
+
+    // There's no pending operation.
+    // When we poll the ioqueue, there must not be events.
+    if (pending_op == 0) {
+        pj_time_val timeout = {1, 0};
+#ifdef PJ_SYMBIAN
+	status = pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+#else
+        status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+        if (status != 0) {
+            status=-60; goto on_error;
+        }
+    }
+
+    // Success
+    status = 0;
+
+on_error:
+    if (ckey1 != NULL)
+    	pj_ioqueue_unregister(ckey1);
+    else if (csock1 != PJ_INVALID_SOCKET)
+	pj_sock_close(csock1);
+    
+    if (ioque != NULL)
+	pj_ioqueue_destroy(ioque);
+    pj_pool_release(pool);
+    return status;
+}
+
+
+/*
+ * Repeated connect/accept on the same listener socket.
+ */
+static int compliance_test_2(pj_bool_t allow_concur)
+{
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+    enum { MAX_PAIR = 1, TEST_LOOP = 2 };
+#else
+    enum { MAX_PAIR = 4, TEST_LOOP = 2 };
+#endif
+
+    struct listener
+    {
+	pj_sock_t	     sock;
+	pj_ioqueue_key_t    *key;
+	pj_sockaddr_in	     addr;
+	int		     addr_len;
+    } listener;
+
+    struct server
+    {
+	pj_sock_t	     sock;
+	pj_ioqueue_key_t    *key;
+	pj_sockaddr_in	     local_addr;
+	pj_sockaddr_in	     rem_addr;
+	int		     rem_addr_len;
+	pj_ioqueue_op_key_t  accept_op;
+    } server[MAX_PAIR];
+
+    struct client
+    {
+	pj_sock_t	     sock;
+	pj_ioqueue_key_t    *key;
+    } client[MAX_PAIR];
+
+    pj_pool_t *pool = NULL;
+    char *send_buf, *recv_buf;
+    pj_ioqueue_t *ioque = NULL;
+    int i, bufsize = BUF_MIN_SIZE;
+    int status;
+    int test_loop, pending_op = 0;
+    pj_timestamp t_elapsed;
+    pj_str_t s;
+    pj_status_t rc;
+
+    listener.sock = PJ_INVALID_SOCKET;
+    listener.key = NULL;
+    
+    for (i=0; i<MAX_PAIR; ++i) {
+    	server[i].sock = PJ_INVALID_SOCKET;
+    	server[i].key = NULL;
+    }
+    
+    for (i=0; i<MAX_PAIR; ++i) {
+    	client[i].sock = PJ_INVALID_SOCKET;
+    	client[i].key = NULL;	
+    }
+    
+    // Create pool.
+    pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
+
+
+    // Create I/O Queue.
+    rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_create()", rc);
+	return -10;
+    }
+
+
+    // Concurrency
+    rc = pj_ioqueue_set_default_concurrency(ioque, allow_concur);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_ioqueue_set_default_concurrency()", rc);
+	return -11;
+    }
+
+    // Allocate buffers for send and receive.
+    send_buf = (char*)pj_pool_alloc(pool, bufsize);
+    recv_buf = (char*)pj_pool_alloc(pool, bufsize);
+
+    // Create listener socket
+    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &listener.sock);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...error creating socket", rc);
+        status=-20; goto on_error;
+    }
+
+    // Bind listener socket.
+    pj_sockaddr_in_init(&listener.addr, 0, 0);
+    if ((rc=pj_sock_bind(listener.sock, &listener.addr, sizeof(listener.addr))) != 0 ) {
+        app_perror("...bind error", rc);
+	status=-30; goto on_error;
+    }
+
+    // Get listener address.
+    listener.addr_len = sizeof(listener.addr);
+    rc = pj_sock_getsockname(listener.sock, &listener.addr, &listener.addr_len);
+    if (rc != PJ_SUCCESS) {
+        app_perror("...ERROR in pj_sock_getsockname()", rc);
+	status=-40; goto on_error;
+    }
+    listener.addr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
+
+
+    // Register listener socket.
+    rc = pj_ioqueue_register_sock(pool, ioque, listener.sock, NULL, &test_cb, 
+				  &listener.key);
+    if (rc != PJ_SUCCESS) {
+	app_perror("...ERROR", rc);
+	status=-50; goto on_error;
+    }
+
+
+    // Listener socket listen().
+    if (pj_sock_listen(listener.sock, 5)) {
+        app_perror("...ERROR in pj_sock_listen()", rc);
+	status=-60; goto on_error;
+    }
+
+
+    for (test_loop=0; test_loop < TEST_LOOP; ++test_loop) {
+	// Client connect and server accept.
+	for (i=0; i<MAX_PAIR; ++i) {
+	    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &client[i].sock);
+	    if (rc != PJ_SUCCESS) {
+		app_perror("...error creating socket", rc);
+		status=-70; goto on_error;
+	    }
+
+	    rc = pj_ioqueue_register_sock(pool, ioque, client[i].sock, NULL, 
+					  &test_cb, &client[i].key);
+	    if (rc != PJ_SUCCESS) {
+		app_perror("...error ", rc);
+		status=-80; goto on_error;
+	    }
+
+	    // Server socket accept()
+	    pj_ioqueue_op_key_init(&server[i].accept_op, 
+				   sizeof(server[i].accept_op));
+	    server[i].rem_addr_len = sizeof(pj_sockaddr_in);
+	    status = pj_ioqueue_accept(listener.key, &server[i].accept_op, 
+				       &server[i].sock, &server[i].local_addr, 
+				       &server[i].rem_addr, 
+				       &server[i].rem_addr_len);
+	    if (status!=PJ_SUCCESS && status != PJ_EPENDING) {
+		app_perror("...ERROR in pj_ioqueue_accept()", rc);
+		status=-90; goto on_error;
+	    }
+	    if (status==PJ_EPENDING) {
+		++pending_op;
+	    }
+
+
+	    // Client socket connect()
+	    status = pj_ioqueue_connect(client[i].key, &listener.addr, 
+					sizeof(listener.addr));
+	    if (status!=PJ_SUCCESS && status != PJ_EPENDING) {
+		app_perror("...ERROR in pj_ioqueue_connect()", rc);
+		status=-100; goto on_error;
+	    }
+	    if (status==PJ_EPENDING) {
+		++pending_op;
+	    }
+
+	    // Poll until connection of this pair established
+	    while (pending_op) {
+		pj_time_val timeout = {1, 0};
+
+#ifdef PJ_SYMBIAN
+		status = pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+#else
+		status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+		if (status > 0) {
+		    if (status > pending_op) {
+			PJ_LOG(3,(THIS_FILE,
+				  "...error: pj_ioqueue_poll() returned %d "
+				  "(only expecting %d)",
+				  status, pending_op));
+			return -110;
+		    }
+		    pending_op -= status;
+
+		    if (pending_op == 0) {
+			status = 0;
+		    }
+		}
+	    }
+	}
+
+	// There's no pending operation.
+	// When we poll the ioqueue, there must not be events.
+	if (pending_op == 0) {
+	    pj_time_val timeout = {1, 0};
+#ifdef PJ_SYMBIAN
+	    status = pj_symbianos_poll(-1, PJ_TIME_VAL_MSEC(timeout));
+#else
+	    status = pj_ioqueue_poll(ioque, &timeout);
+#endif
+	    if (status != 0) {
+		status=-120; goto on_error;
+	    }
+	}
+
+	for (i=0; i<MAX_PAIR; ++i) {
+	    // Check server socket.
+	    if (server[i].sock == PJ_INVALID_SOCKET) {
+		status = -130;
+		app_perror("...accept() error", pj_get_os_error());
+		goto on_error;
+	    }
+
+	    // Check addresses
+	    if (server[i].local_addr.sin_family != pj_AF_INET() ||
+		server[i].local_addr.sin_addr.s_addr == 0 ||
+		server[i].local_addr.sin_port == 0)
+	    {
+		app_perror("...ERROR address not set", rc);
+		status = -140;
+		goto on_error;
+	    }
+
+	    if (server[i].rem_addr.sin_family != pj_AF_INET() ||
+		server[i].rem_addr.sin_addr.s_addr == 0 ||
+		server[i].rem_addr.sin_port == 0)
+	    {
+		app_perror("...ERROR address not set", rc);
+		status = -150;
+		goto on_error;
+	    }
+
+
+	    // Register newly accepted socket.
+	    rc = pj_ioqueue_register_sock(pool, ioque, server[i].sock, NULL,
+					  &test_cb, &server[i].key);
+	    if (rc != PJ_SUCCESS) {
+		app_perror("...ERROR in pj_ioqueue_register_sock", rc);
+		status = -160;
+		goto on_error;
+	    }
+
+	    // Test send and receive.
+	    t_elapsed.u32.lo = 0;
+	    status = send_recv_test(ioque, server[i].key, client[i].key, 
+				    send_buf, recv_buf, bufsize, &t_elapsed);
+	    if (status != 0) {
+		goto on_error;
+	    }
+	}
+
+	// Success
+	status = 0;
+
+	for (i=0; i<MAX_PAIR; ++i) {
+	    if (server[i].key != NULL) {
+		pj_ioqueue_unregister(server[i].key);
+		server[i].key = NULL;
+		server[i].sock = PJ_INVALID_SOCKET;
+	    } else if (server[i].sock != PJ_INVALID_SOCKET) {
+		pj_sock_close(server[i].sock);
+		server[i].sock = PJ_INVALID_SOCKET;
+	    }
+
+	    if (client[i].key != NULL) {
+		pj_ioqueue_unregister(client[i].key);
+		client[i].key = NULL;
+		client[i].sock = PJ_INVALID_SOCKET;
+	    } else if (client[i].sock != PJ_INVALID_SOCKET) {
+		pj_sock_close(client[i].sock);
+		client[i].sock = PJ_INVALID_SOCKET;
+	    }
+	}
+    }
+
+    status = 0;
+
+on_error:
+    for (i=0; i<MAX_PAIR; ++i) {
+	if (server[i].key != NULL) {
+	    pj_ioqueue_unregister(server[i].key);
+	    server[i].key = NULL;
+	    server[i].sock = PJ_INVALID_SOCKET;
+	} else if (server[i].sock != PJ_INVALID_SOCKET) {
+	    pj_sock_close(server[i].sock);
+	    server[i].sock = PJ_INVALID_SOCKET;
+	}
+
+	if (client[i].key != NULL) {
+	    pj_ioqueue_unregister(client[i].key);
+	    client[i].key = NULL;
+	    server[i].sock = PJ_INVALID_SOCKET;
+	} else if (client[i].sock != PJ_INVALID_SOCKET) {
+	    pj_sock_close(client[i].sock);
+	    client[i].sock = PJ_INVALID_SOCKET;
+	}
+    }
+
+    if (listener.key) {
+	pj_ioqueue_unregister(listener.key);
+	listener.key = NULL;
+    } else if (listener.sock != PJ_INVALID_SOCKET) {
+	pj_sock_close(listener.sock);
+	listener.sock = PJ_INVALID_SOCKET;
+    }
+
+    if (ioque != NULL)
+	pj_ioqueue_destroy(ioque);
+    pj_pool_release(pool);
+    return status;
+
+}
+
+
+static int tcp_ioqueue_test_impl(pj_bool_t allow_concur)
+{
+    int status;
+
+    PJ_LOG(3,(THIS_FILE, "..testing with concurency=%d", allow_concur));
+
+    PJ_LOG(3, (THIS_FILE, "..%s compliance test 0 (success scenario)",
+	       pj_ioqueue_name()));
+    if ((status=compliance_test_0(allow_concur)) != 0) {
+	PJ_LOG(1, (THIS_FILE, "....FAILED (status=%d)\n", status));
+	return status;
+    }
+    PJ_LOG(3, (THIS_FILE, "..%s compliance test 1 (failed scenario)",
+               pj_ioqueue_name()));
+    if ((status=compliance_test_1(allow_concur)) != 0) {
+	PJ_LOG(1, (THIS_FILE, "....FAILED (status=%d)\n", status));
+	return status;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "..%s compliance test 2 (repeated accept)",
+               pj_ioqueue_name()));
+    if ((status=compliance_test_2(allow_concur)) != 0) {
+	PJ_LOG(1, (THIS_FILE, "....FAILED (status=%d)\n", status));
+	return status;
+    }
+
+    return 0;
+}
+
+int tcp_ioqueue_test()
+{
+    int rc;
+
+    rc = tcp_ioqueue_test_impl(PJ_TRUE);
+    if (rc != 0)
+	return rc;
+
+    rc = tcp_ioqueue_test_impl(PJ_FALSE);
+    if (rc != 0)
+	return rc;
+
+    return 0;
+}
+
+#endif	/* PJ_HAS_TCP */
+
+
+#else
+/* To prevent warning about "translation unit is empty"
+ * when this test is disabled. 
+ */
+int dummy_uiq_tcp;
+#endif	/* INCLUDE_TCP_IOQUEUE_TEST */
+
+
diff --git a/jni/pjproject-android/.svn/pristine/19/19a765a0abbcb654a13c04a11f6fe8c737656862.svn-base b/jni/pjproject-android/.svn/pristine/19/19a765a0abbcb654a13c04a11f6fe8c737656862.svn-base
new file mode 100644
index 0000000..d0549f5
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/19/19a765a0abbcb654a13c04a11f6fe8c737656862.svn-base
@@ -0,0 +1,130 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJMEDIA_CODEC_TYPES_H__
+#define __PJMEDIA_CODEC_TYPES_H__
+
+/**
+ * @file types.h
+ * @brief PJMEDIA-CODEC types and constants
+ */
+
+#include <pjmedia-codec/config.h>
+#include <pjmedia/codec.h>
+
+/**
+ * @defgroup pjmedia_codec_types PJMEDIA-CODEC Types and Constants
+ * @ingroup PJMEDIA_CODEC
+ * @brief Constants used by PJMEDIA-CODEC
+ * @{
+ */
+
+
+
+/**
+ * These are the dynamic payload types that are used by audio codecs in
+ * this library. Also see the header file <pjmedia/codec.h> for list
+ * of static payload types.
+ */
+enum pjmedia_audio_pt
+{
+    /* According to IANA specifications, dynamic payload types are to be in
+     * the range 96-127 (inclusive). This enum is structured to place the
+     * values of the payload types specified below into that range.
+     *
+     * PJMEDIA_RTP_PT_DYNAMIC is defined in <pjmedia/codec.h>. It is defined
+     * to be 96.
+     *
+     * PJMEDIA_RTP_PT_TELEPHONE_EVENTS is defined in <pjmedia/config.h>.
+     * The default value is 96.
+     */
+#if PJMEDIA_RTP_PT_TELEPHONE_EVENTS
+    PJMEDIA_RTP_PT_START = PJMEDIA_RTP_PT_TELEPHONE_EVENTS,
+#else
+    PJMEDIA_RTP_PT_START = (PJMEDIA_RTP_PT_DYNAMIC-1),
+#endif
+
+    PJMEDIA_RTP_PT_SPEEX_NB,			/**< Speex narrowband/8KHz  */
+    PJMEDIA_RTP_PT_SPEEX_WB,			/**< Speex wideband/16KHz   */
+    PJMEDIA_RTP_PT_SPEEX_UWB,			/**< Speex 32KHz	    */
+    PJMEDIA_RTP_PT_SILK_NB,			/**< SILK narrowband/8KHz   */
+    PJMEDIA_RTP_PT_SILK_MB,			/**< SILK mediumband/12KHz  */
+    PJMEDIA_RTP_PT_SILK_WB,			/**< SILK wideband/16KHz    */
+    PJMEDIA_RTP_PT_SILK_SWB,			/**< SILK 24KHz		    */
+    PJMEDIA_RTP_PT_ILBC,			/**< iLBC (13.3/15.2Kbps)   */
+    PJMEDIA_RTP_PT_AMR,				/**< AMR (4.75 - 12.2Kbps)  */
+    PJMEDIA_RTP_PT_AMRWB,			/**< AMRWB (6.6 - 23.85Kbps)*/
+    PJMEDIA_RTP_PT_AMRWBE,			/**< AMRWBE		    */
+    PJMEDIA_RTP_PT_G726_16,			/**< G726 @ 16Kbps	    */
+    PJMEDIA_RTP_PT_G726_24,			/**< G726 @ 24Kbps	    */
+    PJMEDIA_RTP_PT_G726_32,			/**< G726 @ 32Kbps	    */
+    PJMEDIA_RTP_PT_G726_40,			/**< G726 @ 40Kbps	    */
+    PJMEDIA_RTP_PT_G722_1_16,			/**< G722.1 (16Kbps)	    */
+    PJMEDIA_RTP_PT_G722_1_24,			/**< G722.1 (24Kbps)	    */
+    PJMEDIA_RTP_PT_G722_1_32,			/**< G722.1 (32Kbps)	    */
+    PJMEDIA_RTP_PT_G7221C_24,			/**< G722.1 Annex C (24Kbps)*/
+    PJMEDIA_RTP_PT_G7221C_32,			/**< G722.1 Annex C (32Kbps)*/
+    PJMEDIA_RTP_PT_G7221C_48,			/**< G722.1 Annex C (48Kbps)*/
+    PJMEDIA_RTP_PT_G7221_RSV1,			/**< G722.1 reserve	    */
+    PJMEDIA_RTP_PT_G7221_RSV2,			/**< G722.1 reserve	    */
+    PJMEDIA_RTP_PT_L16_8KHZ_MONO,		/**< L16 @ 8KHz, mono	    */
+    PJMEDIA_RTP_PT_L16_8KHZ_STEREO,		/**< L16 @ 8KHz, stereo     */
+    //PJMEDIA_RTP_PT_L16_11KHZ_MONO,		/**< L16 @ 11KHz, mono	    */
+    //PJMEDIA_RTP_PT_L16_11KHZ_STEREO,		/**< L16 @ 11KHz, stereo    */
+    PJMEDIA_RTP_PT_L16_16KHZ_MONO,		/**< L16 @ 16KHz, mono	    */
+    PJMEDIA_RTP_PT_L16_16KHZ_STEREO,		/**< L16 @ 16KHz, stereo    */
+    //PJMEDIA_RTP_PT_L16_22KHZ_MONO,		/**< L16 @ 22KHz, mono	    */
+    //PJMEDIA_RTP_PT_L16_22KHZ_STEREO,		/**< L16 @ 22KHz, stereo    */
+    //PJMEDIA_RTP_PT_L16_32KHZ_MONO,		/**< L16 @ 32KHz, mono	    */
+    //PJMEDIA_RTP_PT_L16_32KHZ_STEREO,		/**< L16 @ 32KHz, stereo    */
+    //PJMEDIA_RTP_PT_L16_48KHZ_MONO,		/**< L16 @ 48KHz, mono	    */
+    //PJMEDIA_RTP_PT_L16_48KHZ_STEREO,		/**< L16 @ 48KHz, stereo    */
+
+    /* Caution!
+     * Ensure the value of the last pt above is <= 127.
+     */
+};
+
+/**
+ * These are the dynamic payload types that are used by video codecs in
+ * this library.
+ */
+enum pjmedia_video_pt
+{
+     /* Video payload types */
+     PJMEDIA_RTP_PT_VID_START = (PJMEDIA_RTP_PT_DYNAMIC-1),
+     PJMEDIA_RTP_PT_H263P,
+     PJMEDIA_RTP_PT_H264,
+     PJMEDIA_RTP_PT_H264_RSV1,
+     PJMEDIA_RTP_PT_H264_RSV2,
+     PJMEDIA_RTP_PT_H264_RSV3,
+     PJMEDIA_RTP_PT_H264_RSV4,
+
+     /* Caution!
+      * Ensure the value of the last pt above is <= 127.
+      */
+};
+
+
+/**
+ * @}
+ */
+
+
+#endif	/* __PJMEDIA_CODEC_TYPES_H__ */
diff --git a/jni/pjproject-android/.svn/pristine/19/19a89ccef7dc6e4af7a1eb9b95adb0f913ca7117.svn-base b/jni/pjproject-android/.svn/pristine/19/19a89ccef7dc6e4af7a1eb9b95adb0f913ca7117.svn-base
new file mode 100644
index 0000000..585b861
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/19/19a89ccef7dc6e4af7a1eb9b95adb0f913ca7117.svn-base
@@ -0,0 +1,115 @@
+/* Copyright (C) 2004 Jean-Marc Valin */
+/**
+   @file vq_arm4.h
+   @brief ARM4-optimized vq routine
+*/
+/*
+   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_VQ_NBEST
+void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j;
+   for (i=0;i<entries;i+=4)
+   {
+#if 1
+      spx_word32_t dist1, dist2, dist3, dist4;
+      int dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
+      __asm__ __volatile__ (
+            "mov %0, #0 \n\t"
+            "mov %1, #0 \n\t"
+            "mov %2, #0 \n\t"
+            "mov %3, #0 \n\t"
+            "mov %10, %4 \n\t"
+            "add %4, %4, %4\n\t"
+            ".vqloop%=:\n\t"
+            "ldrsh %7, [%5], #2 \n\t"
+            "ldrsh %8, [%6] \n\t"
+            "mov %9, %6 \n\t"
+            "mla %0, %7, %8, %0 \n\t"
+            "ldrsh %8, [%9, %4]! \n\t"
+            "mla %1, %7, %8, %1 \n\t"
+            "ldrsh %8, [%9, %4]!\n\t"
+            "mla %2, %7, %8, %2 \n\t"
+            "ldrsh %8, [%9, %4]! \n\t"
+            "mla %3, %7, %8, %3 \n\t"
+            "subs %10, %10, #1 \n\t"
+            "add %6, %6, #2 \n\t"
+            "bne .vqloop%="
+         : "=r" (dist1), "=r" (dist2), "=r" (dist3), "=r" (dist4),
+      "=r" (dead1), "=r" (dead2), "=r" (codebook), "=r" (dead4),
+      "=r" (dead5), "=r" (dead6), "=r" (dead7)
+         : "4" (len), "5" (in), "6" (codebook)
+         : "cc");
+#else
+dist1=dist2=dist3=dist4=0;
+   /*   spx_word32_t dist1=0;
+      spx_word32_t dist2=0;
+      spx_word32_t dist3=0;
+      spx_word32_t dist4=0;*/
+      for (j=0;j<2;j++)
+      {
+         const spx_word16_t *code = codebook;
+         dist1 = MAC16_16(dist1,in[j],*code);
+         code += len;
+         dist2 = MAC16_16(dist2,in[j],*code);
+         code += len;
+         dist3 = MAC16_16(dist3,in[j],*code);
+         code += len;
+         dist4 = MAC16_16(dist4,in[j],*code);
+         codebook++;
+      }
+#endif
+      dist1=SUB32(SHR(*E++,1),dist1);
+      if (dist1<*best_dist || i==0)
+      {
+         *best_dist=dist1;
+         *nbest=i;
+      }
+      dist2=SUB32(SHR(*E++,1),dist2);
+      if (dist2<*best_dist)
+      {
+         *best_dist=dist2;
+         *nbest=i+1;
+      }
+      dist3=SUB32(SHR(*E++,1),dist3);
+      if (dist3<*best_dist)
+      {
+         *best_dist=dist3;
+         *nbest=i+2;
+      }
+      dist4=SUB32(SHR(*E++,1),dist4);
+      if (dist4<*best_dist)
+      {
+         *best_dist=dist4;
+         *nbest=i+3;
+      }
+      codebook += 3*len;
+   }
+}
diff --git a/jni/pjproject-android/.svn/pristine/19/19bd89d60b61d409f8c974934870b9812736a5d0.svn-base b/jni/pjproject-android/.svn/pristine/19/19bd89d60b61d409f8c974934870b9812736a5d0.svn-base
new file mode 100644
index 0000000..0f32283
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/19/19bd89d60b61d409f8c974934870b9812736a5d0.svn-base
@@ -0,0 +1,952 @@
+/* $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/activesock.h>
+#include <pj/compat/socket.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/sock.h>
+#include <pj/string.h>
+
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+#   include <CFNetwork/CFNetwork.h>
+
+    static pj_bool_t ios_bg_support = PJ_TRUE;
+#endif
+
+#define PJ_ACTIVESOCK_MAX_LOOP	    50
+
+
+enum read_type
+{
+    TYPE_NONE,
+    TYPE_RECV,
+    TYPE_RECV_FROM
+};
+
+enum shutdown_dir
+{
+    SHUT_NONE = 0,
+    SHUT_RX = 1,
+    SHUT_TX = 2
+};
+
+struct read_op
+{
+    pj_ioqueue_op_key_t	 op_key;
+    pj_uint8_t		*pkt;
+    unsigned		 max_size;
+    pj_size_t		 size;
+    pj_sockaddr		 src_addr;
+    int			 src_addr_len;
+};
+
+struct accept_op
+{
+    pj_ioqueue_op_key_t	 op_key;
+    pj_sock_t		 new_sock;
+    pj_sockaddr		 rem_addr;
+    int			 rem_addr_len;
+};
+
+struct send_data
+{
+    pj_uint8_t		*data;
+    pj_ssize_t		 len;
+    pj_ssize_t		 sent;
+    unsigned		 flags;
+};
+
+struct pj_activesock_t
+{
+    pj_ioqueue_key_t	*key;
+    pj_bool_t		 stream_oriented;
+    pj_bool_t		 whole_data;
+    pj_ioqueue_t	*ioqueue;
+    void		*user_data;
+    unsigned		 async_count;
+    unsigned	 	 shutdown;
+    unsigned		 max_loop;
+    pj_activesock_cb	 cb;
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+    int			 bg_setting;
+    pj_sock_t		 sock;
+    CFReadStreamRef	 readStream;
+#endif
+    
+    unsigned		 err_counter;
+    pj_status_t		 last_err;
+
+    struct send_data	 send_data;
+
+    struct read_op	*read_op;
+    pj_uint32_t		 read_flags;
+    enum read_type	 read_type;
+
+    struct accept_op	*accept_op;
+};
+
+
+static void ioqueue_on_read_complete(pj_ioqueue_key_t *key, 
+				     pj_ioqueue_op_key_t *op_key, 
+				     pj_ssize_t bytes_read);
+static void ioqueue_on_write_complete(pj_ioqueue_key_t *key, 
+				      pj_ioqueue_op_key_t *op_key,
+				      pj_ssize_t bytes_sent);
+#if PJ_HAS_TCP
+static void ioqueue_on_accept_complete(pj_ioqueue_key_t *key, 
+				       pj_ioqueue_op_key_t *op_key,
+				       pj_sock_t sock, 
+				       pj_status_t status);
+static void ioqueue_on_connect_complete(pj_ioqueue_key_t *key, 
+					pj_status_t status);
+#endif
+
+PJ_DEF(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg)
+{
+    pj_bzero(cfg, sizeof(*cfg));
+    cfg->async_cnt = 1;
+    cfg->concurrency = -1;
+    cfg->whole_data = PJ_TRUE;
+}
+
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+static void activesock_destroy_iphone_os_stream(pj_activesock_t *asock)
+{
+    if (asock->readStream) {
+	CFReadStreamClose(asock->readStream);
+	CFRelease(asock->readStream);
+	asock->readStream = NULL;
+    }
+}
+
+static void activesock_create_iphone_os_stream(pj_activesock_t *asock)
+{
+    if (ios_bg_support && asock->bg_setting && asock->stream_oriented) {
+	activesock_destroy_iphone_os_stream(asock);
+
+	CFStreamCreatePairWithSocket(kCFAllocatorDefault, asock->sock,
+				     &asock->readStream, NULL);
+
+	if (!asock->readStream ||
+	    CFReadStreamSetProperty(asock->readStream,
+				    kCFStreamNetworkServiceType,
+				    kCFStreamNetworkServiceTypeVoIP)
+	    != TRUE ||
+	    CFReadStreamOpen(asock->readStream) != TRUE)
+	{
+	    PJ_LOG(2,("", "Failed to configure TCP transport for VoIP "
+		      "usage. Background mode will not be supported."));
+	    
+	    activesock_destroy_iphone_os_stream(asock);
+	}
+    }
+}
+
+
+PJ_DEF(void) pj_activesock_set_iphone_os_bg(pj_activesock_t *asock,
+					    int val)
+{
+    asock->bg_setting = val;
+    if (asock->bg_setting)
+	activesock_create_iphone_os_stream(asock);
+    else
+	activesock_destroy_iphone_os_stream(asock);
+}
+
+PJ_DEF(void) pj_activesock_enable_iphone_os_bg(pj_bool_t val)
+{
+    ios_bg_support = val;
+}
+#endif
+
+PJ_DEF(pj_status_t) pj_activesock_create( pj_pool_t *pool,
+					  pj_sock_t sock,
+					  int sock_type,
+					  const pj_activesock_cfg *opt,
+					  pj_ioqueue_t *ioqueue,
+					  const pj_activesock_cb *cb,
+					  void *user_data,
+					  pj_activesock_t **p_asock)
+{
+    pj_activesock_t *asock;
+    pj_ioqueue_callback ioq_cb;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(pool && ioqueue && cb && p_asock, PJ_EINVAL);
+    PJ_ASSERT_RETURN(sock!=0 && sock!=PJ_INVALID_SOCKET, PJ_EINVAL);
+    PJ_ASSERT_RETURN(sock_type==pj_SOCK_STREAM() ||
+		     sock_type==pj_SOCK_DGRAM(), PJ_EINVAL);
+    PJ_ASSERT_RETURN(!opt || opt->async_cnt >= 1, PJ_EINVAL);
+
+    asock = PJ_POOL_ZALLOC_T(pool, pj_activesock_t);
+    asock->ioqueue = ioqueue;
+    asock->stream_oriented = (sock_type == pj_SOCK_STREAM());
+    asock->async_count = (opt? opt->async_cnt : 1);
+    asock->whole_data = (opt? opt->whole_data : 1);
+    asock->max_loop = PJ_ACTIVESOCK_MAX_LOOP;
+    asock->user_data = user_data;
+    pj_memcpy(&asock->cb, cb, sizeof(*cb));
+
+    pj_bzero(&ioq_cb, sizeof(ioq_cb));
+    ioq_cb.on_read_complete = &ioqueue_on_read_complete;
+    ioq_cb.on_write_complete = &ioqueue_on_write_complete;
+#if PJ_HAS_TCP
+    ioq_cb.on_connect_complete = &ioqueue_on_connect_complete;
+    ioq_cb.on_accept_complete = &ioqueue_on_accept_complete;
+#endif
+
+    status = pj_ioqueue_register_sock2(pool, ioqueue, sock,
+                                       (opt? opt->grp_lock : NULL),
+                                       asock, &ioq_cb, &asock->key);
+    if (status != PJ_SUCCESS) {
+	pj_activesock_close(asock);
+	return status;
+    }
+    
+    if (asock->whole_data) {
+	/* Must disable concurrency otherwise there is a race condition */
+	pj_ioqueue_set_concurrency(asock->key, 0);
+    } else if (opt && opt->concurrency >= 0) {
+	pj_ioqueue_set_concurrency(asock->key, opt->concurrency);
+    }
+
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+    asock->sock = sock;
+    asock->bg_setting = PJ_ACTIVESOCK_TCP_IPHONE_OS_BG;
+#endif
+
+    *p_asock = asock;
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_create_udp( pj_pool_t *pool,
+					      const pj_sockaddr *addr,
+					      const pj_activesock_cfg *opt,
+					      pj_ioqueue_t *ioqueue,
+					      const pj_activesock_cb *cb,
+					      void *user_data,
+					      pj_activesock_t **p_asock,
+					      pj_sockaddr *bound_addr)
+{
+    pj_sock_t sock_fd;
+    pj_sockaddr default_addr;
+    pj_status_t status;
+
+    if (addr == NULL) {
+	pj_sockaddr_init(pj_AF_INET(), &default_addr, NULL, 0);
+	addr = &default_addr;
+    }
+
+    status = pj_sock_socket(addr->addr.sa_family, pj_SOCK_DGRAM(), 0, 
+			    &sock_fd);
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+
+    status = pj_sock_bind(sock_fd, addr, pj_sockaddr_get_len(addr));
+    if (status != PJ_SUCCESS) {
+	pj_sock_close(sock_fd);
+	return status;
+    }
+
+    status = pj_activesock_create(pool, sock_fd, pj_SOCK_DGRAM(), opt,
+				  ioqueue, cb, user_data, p_asock);
+    if (status != PJ_SUCCESS) {
+	pj_sock_close(sock_fd);
+	return status;
+    }
+
+    if (bound_addr) {
+	int addr_len = sizeof(*bound_addr);
+	status = pj_sock_getsockname(sock_fd, bound_addr, &addr_len);
+	if (status != PJ_SUCCESS) {
+	    pj_activesock_close(*p_asock);
+	    return status;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_activesock_close(pj_activesock_t *asock)
+{
+    PJ_ASSERT_RETURN(asock, PJ_EINVAL);
+    asock->shutdown = SHUT_RX | SHUT_TX;
+    if (asock->key) {
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+	activesock_destroy_iphone_os_stream(asock);
+#endif	
+	
+	pj_ioqueue_unregister(asock->key);
+	asock->key = NULL;
+    }
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_set_user_data( pj_activesock_t *asock,
+						 void *user_data)
+{
+    PJ_ASSERT_RETURN(asock, PJ_EINVAL);
+    asock->user_data = user_data;
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(void*) pj_activesock_get_user_data(pj_activesock_t *asock)
+{
+    PJ_ASSERT_RETURN(asock, NULL);
+    return asock->user_data;
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,
+					     pj_pool_t *pool,
+					     unsigned buff_size,
+					     pj_uint32_t flags)
+{
+    void **readbuf;
+    unsigned i;
+
+    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);
+
+    readbuf = (void**) pj_pool_calloc(pool, asock->async_count, 
+				      sizeof(void*));
+
+    for (i=0; i<asock->async_count; ++i) {
+	readbuf[i] = pj_pool_alloc(pool, buff_size);
+    }
+
+    return pj_activesock_start_read2(asock, pool, buff_size, readbuf, flags);
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_start_read2( pj_activesock_t *asock,
+					       pj_pool_t *pool,
+					       unsigned buff_size,
+					       void *readbuf[],
+					       pj_uint32_t flags)
+{
+    unsigned i;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);
+    PJ_ASSERT_RETURN(asock->read_type == TYPE_NONE, PJ_EINVALIDOP);
+    PJ_ASSERT_RETURN(asock->read_op == NULL, PJ_EINVALIDOP);
+
+    asock->read_op = (struct read_op*)
+		     pj_pool_calloc(pool, asock->async_count, 
+				    sizeof(struct read_op));
+    asock->read_type = TYPE_RECV;
+    asock->read_flags = flags;
+
+    for (i=0; i<asock->async_count; ++i) {
+	struct read_op *r = &asock->read_op[i];
+	pj_ssize_t size_to_read;
+
+	r->pkt = (pj_uint8_t*)readbuf[i];
+	size_to_read = r->max_size = buff_size;
+
+	status = pj_ioqueue_recv(asock->key, &r->op_key, r->pkt, &size_to_read,
+				 PJ_IOQUEUE_ALWAYS_ASYNC | flags);
+	PJ_ASSERT_RETURN(status != PJ_SUCCESS, PJ_EBUG);
+
+	if (status != PJ_EPENDING)
+	    return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,
+						 pj_pool_t *pool,
+						 unsigned buff_size,
+						 pj_uint32_t flags)
+{
+    void **readbuf;
+    unsigned i;
+
+    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);
+
+    readbuf = (void**) pj_pool_calloc(pool, asock->async_count, 
+				      sizeof(void*));
+
+    for (i=0; i<asock->async_count; ++i) {
+	readbuf[i] = pj_pool_alloc(pool, buff_size);
+    }
+
+    return pj_activesock_start_recvfrom2(asock, pool, buff_size, 
+					 readbuf, flags);
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_start_recvfrom2( pj_activesock_t *asock,
+						   pj_pool_t *pool,
+						   unsigned buff_size,
+						   void *readbuf[],
+						   pj_uint32_t flags)
+{
+    unsigned i;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL);
+    PJ_ASSERT_RETURN(asock->read_type == TYPE_NONE, PJ_EINVALIDOP);
+
+    asock->read_op = (struct read_op*)
+		     pj_pool_calloc(pool, asock->async_count, 
+				    sizeof(struct read_op));
+    asock->read_type = TYPE_RECV_FROM;
+    asock->read_flags = flags;
+
+    for (i=0; i<asock->async_count; ++i) {
+	struct read_op *r = &asock->read_op[i];
+	pj_ssize_t size_to_read;
+
+	r->pkt = (pj_uint8_t*) readbuf[i];
+	size_to_read = r->max_size = buff_size;
+	r->src_addr_len = sizeof(r->src_addr);
+
+	status = pj_ioqueue_recvfrom(asock->key, &r->op_key, r->pkt,
+				     &size_to_read, 
+				     PJ_IOQUEUE_ALWAYS_ASYNC | flags,
+				     &r->src_addr, &r->src_addr_len);
+	PJ_ASSERT_RETURN(status != PJ_SUCCESS, PJ_EBUG);
+
+	if (status != PJ_EPENDING)
+	    return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+static void ioqueue_on_read_complete(pj_ioqueue_key_t *key, 
+				     pj_ioqueue_op_key_t *op_key, 
+				     pj_ssize_t bytes_read)
+{
+    pj_activesock_t *asock;
+    struct read_op *r = (struct read_op*)op_key;
+    unsigned loop = 0;
+    pj_status_t status;
+
+    asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);
+
+    /* Ignore if we've been shutdown */
+    if (asock->shutdown & SHUT_RX)
+	return;
+
+    do {
+	unsigned flags;
+
+	if (bytes_read > 0) {
+	    /*
+	     * We've got new data.
+	     */
+	    pj_size_t remainder;
+	    pj_bool_t ret;
+
+	    /* Append this new data to existing data. If socket is stream 
+	     * oriented, user might have left some data in the buffer. 
+	     * Otherwise if socket is datagram there will be nothing in 
+	     * existing packet hence the packet will contain only the new
+	     * packet.
+	     */
+	    r->size += bytes_read;
+
+	    /* Set default remainder to zero */
+	    remainder = 0;
+
+	    /* And return value to TRUE */
+	    ret = PJ_TRUE;
+
+	    /* Notify callback */
+	    if (asock->read_type == TYPE_RECV && asock->cb.on_data_read) {
+		ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
+						PJ_SUCCESS, &remainder);
+	    } else if (asock->read_type == TYPE_RECV_FROM && 
+		       asock->cb.on_data_recvfrom) 
+	    {
+		ret = (*asock->cb.on_data_recvfrom)(asock, r->pkt, r->size,
+						    &r->src_addr, 
+						    r->src_addr_len,
+						    PJ_SUCCESS);
+	    }
+
+	    /* If callback returns false, we have been destroyed! */
+	    if (!ret)
+		return;
+
+	    /* Only stream oriented socket may leave data in the packet */
+	    if (asock->stream_oriented) {
+		r->size = remainder;
+	    } else {
+		r->size = 0;
+	    }
+
+	} else if (bytes_read <= 0 &&
+		   -bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) &&
+		   -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && 
+		   (asock->stream_oriented ||
+		    -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET))) 
+	{
+	    pj_size_t remainder;
+	    pj_bool_t ret;
+
+	    if (bytes_read == 0) {
+		/* For stream/connection oriented socket, this means the 
+		 * connection has been closed. For datagram sockets, it means
+		 * we've received datagram with zero length.
+		 */
+		if (asock->stream_oriented)
+		    status = PJ_EEOF;
+		else
+		    status = PJ_SUCCESS;
+	    } else {
+		/* This means we've got an error. If this is stream/connection
+		 * oriented, it means connection has been closed. For datagram
+		 * sockets, it means we've got some error (e.g. EWOULDBLOCK).
+		 */
+		status = (pj_status_t)-bytes_read;
+	    }
+
+	    /* Set default remainder to zero */
+	    remainder = 0;
+
+	    /* And return value to TRUE */
+	    ret = PJ_TRUE;
+
+	    /* Notify callback */
+	    if (asock->read_type == TYPE_RECV && asock->cb.on_data_read) {
+		/* For connection oriented socket, we still need to report 
+		 * the remainder data (if any) to the user to let user do 
+		 * processing with the remainder data before it closes the
+		 * connection.
+		 * If there is no remainder data, set the packet to NULL.
+		 */
+
+		/* Shouldn't set the packet to NULL, as there may be active 
+		 * socket user, such as SSL socket, that needs to have access
+		 * to the read buffer packet.
+		 */
+		//ret = (*asock->cb.on_data_read)(asock, (r->size? r->pkt:NULL),
+		//				r->size, status, &remainder);
+		ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
+						status, &remainder);
+
+	    } else if (asock->read_type == TYPE_RECV_FROM && 
+		       asock->cb.on_data_recvfrom) 
+	    {
+		/* This would always be datagram oriented hence there's 
+		 * nothing in the packet. We can't be sure if there will be
+		 * anything useful in the source_addr, so just put NULL
+		 * there too.
+		 */
+		/* In some scenarios, status may be PJ_SUCCESS. The upper 
+		 * layer application may not expect the callback to be called
+		 * with successful status and NULL data, so lets not call the
+		 * callback if the status is PJ_SUCCESS.
+		 */
+		if (status != PJ_SUCCESS ) {
+		    ret = (*asock->cb.on_data_recvfrom)(asock, NULL, 0,
+							NULL, 0, status);
+		}
+	    }
+
+	    /* If callback returns false, we have been destroyed! */
+	    if (!ret)
+		return;
+
+	    /* Also stop further read if we've been shutdown */
+	    if (asock->shutdown & SHUT_RX)
+		return;
+
+	    /* Only stream oriented socket may leave data in the packet */
+	    if (asock->stream_oriented) {
+		r->size = remainder;
+	    } else {
+		r->size = 0;
+	    }
+	}
+
+	/* Read next data. We limit ourselves to processing max_loop immediate
+	 * data, so when the loop counter has exceeded this value, force the
+	 * read()/recvfrom() to return pending operation to allow the program
+	 * to do other jobs.
+	 */
+	bytes_read = r->max_size - r->size;
+	flags = asock->read_flags;
+	if (++loop >= asock->max_loop)
+	    flags |= PJ_IOQUEUE_ALWAYS_ASYNC;
+
+	if (asock->read_type == TYPE_RECV) {
+	    status = pj_ioqueue_recv(key, op_key, r->pkt + r->size, 
+				     &bytes_read, flags);
+	} else {
+	    r->src_addr_len = sizeof(r->src_addr);
+	    status = pj_ioqueue_recvfrom(key, op_key, r->pkt + r->size,
+				         &bytes_read, flags,
+					 &r->src_addr, &r->src_addr_len);
+	}
+
+	if (status == PJ_SUCCESS) {
+	    /* Immediate data */
+	    ;
+	} else if (status != PJ_EPENDING && status != PJ_ECANCELLED) {
+	    /* Error */
+	    bytes_read = -status;
+	} else {
+	    break;
+	}
+    } while (1);
+
+}
+
+
+static pj_status_t send_remaining(pj_activesock_t *asock, 
+				  pj_ioqueue_op_key_t *send_key)
+{
+    struct send_data *sd = (struct send_data*)send_key->activesock_data;
+    pj_status_t status;
+
+    do {
+	pj_ssize_t size;
+
+	size = sd->len - sd->sent;
+	status = pj_ioqueue_send(asock->key, send_key, 
+				 sd->data+sd->sent, &size, sd->flags);
+	if (status != PJ_SUCCESS) {
+	    /* Pending or error */
+	    break;
+	}
+
+	sd->sent += size;
+	if (sd->sent == sd->len) {
+	    /* The whole data has been sent. */
+	    return PJ_SUCCESS;
+	}
+
+    } while (sd->sent < sd->len);
+
+    return status;
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_send( pj_activesock_t *asock,
+					pj_ioqueue_op_key_t *send_key,
+					const void *data,
+					pj_ssize_t *size,
+					unsigned flags)
+{
+    PJ_ASSERT_RETURN(asock && send_key && data && size, PJ_EINVAL);
+
+    if (asock->shutdown & SHUT_TX)
+	return PJ_EINVALIDOP;
+
+    send_key->activesock_data = NULL;
+
+    if (asock->whole_data) {
+	pj_ssize_t whole;
+	pj_status_t status;
+
+	whole = *size;
+
+	status = pj_ioqueue_send(asock->key, send_key, data, size, flags);
+	if (status != PJ_SUCCESS) {
+	    /* Pending or error */
+	    return status;
+	}
+
+	if (*size == whole) {
+	    /* The whole data has been sent. */
+	    return PJ_SUCCESS;
+	}
+
+	/* Data was partially sent */
+	asock->send_data.data = (pj_uint8_t*)data;
+	asock->send_data.len = whole;
+	asock->send_data.sent = *size;
+	asock->send_data.flags = flags;
+	send_key->activesock_data = &asock->send_data;
+
+	/* Try again */
+	status = send_remaining(asock, send_key);
+	if (status == PJ_SUCCESS) {
+	    *size = whole;
+	}
+	return status;
+
+    } else {
+	return pj_ioqueue_send(asock->key, send_key, data, size, flags);
+    }
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_sendto( pj_activesock_t *asock,
+					  pj_ioqueue_op_key_t *send_key,
+					  const void *data,
+					  pj_ssize_t *size,
+					  unsigned flags,
+					  const pj_sockaddr_t *addr,
+					  int addr_len)
+{
+    PJ_ASSERT_RETURN(asock && send_key && data && size && addr && addr_len, 
+		     PJ_EINVAL);
+
+    if (asock->shutdown & SHUT_TX)
+	return PJ_EINVALIDOP;
+
+    return pj_ioqueue_sendto(asock->key, send_key, data, size, flags,
+			     addr, addr_len);
+}
+
+
+static void ioqueue_on_write_complete(pj_ioqueue_key_t *key, 
+				      pj_ioqueue_op_key_t *op_key,
+				      pj_ssize_t bytes_sent)
+{
+    pj_activesock_t *asock;
+
+    asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);
+
+    /* Ignore if we've been shutdown. This may cause data to be partially
+     * sent even when 'wholedata' was requested if the OS only sent partial
+     * buffer.
+     */
+    if (asock->shutdown & SHUT_TX)
+	return;
+
+    if (bytes_sent > 0 && op_key->activesock_data) {
+	/* whole_data is requested. Make sure we send all the data */
+	struct send_data *sd = (struct send_data*)op_key->activesock_data;
+
+	sd->sent += bytes_sent;
+	if (sd->sent == sd->len) {
+	    /* all has been sent */
+	    bytes_sent = sd->sent;
+	    op_key->activesock_data = NULL;
+	} else {
+	    /* send remaining data */
+	    pj_status_t status;
+
+	    status = send_remaining(asock, op_key);
+	    if (status == PJ_EPENDING)
+		return;
+	    else if (status == PJ_SUCCESS)
+		bytes_sent = sd->sent;
+	    else
+		bytes_sent = -status;
+
+	    op_key->activesock_data = NULL;
+	}
+    } 
+
+    if (asock->cb.on_data_sent) {
+	pj_bool_t ret;
+
+	ret = (*asock->cb.on_data_sent)(asock, op_key, bytes_sent);
+
+	/* If callback returns false, we have been destroyed! */
+	if (!ret)
+	    return;
+    }
+}
+
+#if PJ_HAS_TCP
+PJ_DEF(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,
+					       pj_pool_t *pool)
+{
+    unsigned i;
+
+    PJ_ASSERT_RETURN(asock, PJ_EINVAL);
+    PJ_ASSERT_RETURN(asock->accept_op==NULL, PJ_EINVALIDOP);
+
+    /* Ignore if we've been shutdown */
+    if (asock->shutdown)
+	return PJ_EINVALIDOP;
+
+    asock->accept_op = (struct accept_op*)
+		       pj_pool_calloc(pool, asock->async_count,
+				      sizeof(struct accept_op));
+    for (i=0; i<asock->async_count; ++i) {
+	struct accept_op *a = &asock->accept_op[i];
+	pj_status_t status;
+
+	do {
+	    a->new_sock = PJ_INVALID_SOCKET;
+	    a->rem_addr_len = sizeof(a->rem_addr);
+
+	    status = pj_ioqueue_accept(asock->key, &a->op_key, &a->new_sock,
+				       NULL, &a->rem_addr, &a->rem_addr_len);
+	    if (status == PJ_SUCCESS) {
+		/* We've got immediate connection. Not sure if it's a good
+		 * idea to call the callback now (probably application will
+		 * not be prepared to process it), so lets just silently
+		 * close the socket.
+		 */
+		pj_sock_close(a->new_sock);
+	    }
+	} while (status == PJ_SUCCESS);
+
+	if (status != PJ_EPENDING) {
+	    return status;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+static void ioqueue_on_accept_complete(pj_ioqueue_key_t *key, 
+				       pj_ioqueue_op_key_t *op_key,
+				       pj_sock_t new_sock, 
+				       pj_status_t status)
+{
+    pj_activesock_t *asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);
+    struct accept_op *accept_op = (struct accept_op*) op_key;
+
+    PJ_UNUSED_ARG(new_sock);
+
+    /* Ignore if we've been shutdown */
+    if (asock->shutdown)
+	return;
+
+    do {
+	if (status == asock->last_err && status != PJ_SUCCESS) {
+	    asock->err_counter++;
+	    if (asock->err_counter >= PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR) {
+		PJ_LOG(3, ("", "Received %d consecutive errors: %d for the accept()"
+			       " operation, stopping further ioqueue accepts.",
+			       asock->err_counter, asock->last_err));
+		
+		if ((status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) && 
+		    (asock->cb.on_accept_complete2)) 
+		{
+		    (*asock->cb.on_accept_complete2)(asock, 
+						     accept_op->new_sock,
+						     &accept_op->rem_addr,
+						     accept_op->rem_addr_len,
+						     PJ_ESOCKETSTOP);
+		}
+		return;
+	    }
+	} else {
+	    asock->err_counter = 0;
+	    asock->last_err = status;
+	}
+
+	if (status==PJ_SUCCESS && (asock->cb.on_accept_complete2 || 
+				   asock->cb.on_accept_complete)) {
+	    pj_bool_t ret;
+
+	    /* Notify callback */
+	    if (asock->cb.on_accept_complete2) {
+		ret = (*asock->cb.on_accept_complete2)(asock, 
+						       accept_op->new_sock,
+						       &accept_op->rem_addr,
+						       accept_op->rem_addr_len,
+						       status);
+	    } else {
+		ret = (*asock->cb.on_accept_complete)(asock, 
+						      accept_op->new_sock,
+						      &accept_op->rem_addr,
+						      accept_op->rem_addr_len);	    
+	    }
+
+	    /* If callback returns false, we have been destroyed! */
+	    if (!ret)
+		return;
+
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+	    activesock_create_iphone_os_stream(asock);
+#endif
+	} else if (status==PJ_SUCCESS) {
+	    /* Application doesn't handle the new socket, we need to 
+	     * close it to avoid resource leak.
+	     */
+	    pj_sock_close(accept_op->new_sock);
+	}
+
+	/* Don't start another accept() if we've been shutdown */
+	if (asock->shutdown)
+	    return;
+
+	/* Prepare next accept() */
+	accept_op->new_sock = PJ_INVALID_SOCKET;
+	accept_op->rem_addr_len = sizeof(accept_op->rem_addr);
+
+	status = pj_ioqueue_accept(asock->key, op_key, &accept_op->new_sock,
+				   NULL, &accept_op->rem_addr, 
+				   &accept_op->rem_addr_len);
+
+    } while (status != PJ_EPENDING && status != PJ_ECANCELLED);
+}
+
+
+PJ_DEF(pj_status_t) pj_activesock_start_connect( pj_activesock_t *asock,
+						 pj_pool_t *pool,
+						 const pj_sockaddr_t *remaddr,
+						 int addr_len)
+{
+    PJ_UNUSED_ARG(pool);
+
+    if (asock->shutdown)
+	return PJ_EINVALIDOP;
+
+    return pj_ioqueue_connect(asock->key, remaddr, addr_len);
+}
+
+static void ioqueue_on_connect_complete(pj_ioqueue_key_t *key, 
+					pj_status_t status)
+{
+    pj_activesock_t *asock = (pj_activesock_t*) pj_ioqueue_get_user_data(key);
+
+    /* Ignore if we've been shutdown */
+    if (asock->shutdown)
+	return;
+
+    if (asock->cb.on_connect_complete) {
+	pj_bool_t ret;
+
+	ret = (*asock->cb.on_connect_complete)(asock, status);
+
+	if (!ret) {
+	    /* We've been destroyed */
+	    return;
+	}
+	
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+	activesock_create_iphone_os_stream(asock);
+#endif
+	
+    }
+}
+#endif	/* PJ_HAS_TCP */
+