* #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/c8/c8e50eadcbf6176950210349e5a9338d3d66ee0d.svn-base b/jni/pjproject-android/.svn/pristine/c8/c8e50eadcbf6176950210349e5a9338d3d66ee0d.svn-base
new file mode 100644
index 0000000..ab22c5e
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/c8/c8e50eadcbf6176950210349e5a9338d3d66ee0d.svn-base
@@ -0,0 +1,772 @@
+/* $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"
+#include <pjsip.h>
+#include <pjlib.h>
+
+#define THIS_FILE   "transport_test.c"
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Generic testing for transport, to make sure that basic
+ * attributes have been initialized properly.
+ */
+int generic_transport_test(pjsip_transport *tp)
+{
+    PJ_LOG(3,(THIS_FILE, "  structure test..."));
+
+    /* Check that local address name is valid. */
+    {
+	struct pj_in_addr addr;
+
+	/* Note: inet_aton() returns non-zero if addr is valid! */
+	if (pj_inet_aton(&tp->local_name.host, &addr) != 0) {
+	    if (addr.s_addr==PJ_INADDR_ANY || addr.s_addr==PJ_INADDR_NONE) {
+		PJ_LOG(3,(THIS_FILE, "   Error: invalid address name"));
+		return -420;
+	    }
+	} else {
+	    /* It's okay. local_name.host may be a hostname instead of
+	     * IP address.
+	     */
+	}
+    }
+
+    /* Check that port is valid. */
+    if (tp->local_name.port <= 0) {
+	return -430;
+    }
+
+    /* Check length of address (for now we only check against sockaddr_in). */
+    if (tp->addr_len != sizeof(pj_sockaddr_in))
+	return -440;
+
+    /* Check type. */
+    if (tp->key.type == PJSIP_TRANSPORT_UNSPECIFIED)
+	return -450;
+
+    /* That's it. */
+    return PJ_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/* 
+ * Send/receive test.
+ *
+ * This test sends a request to loopback address; as soon as request is 
+ * received, response will be sent, and time is recorded.
+ *
+ * The main purpose is to test that the basic transport functionalities works,
+ * before we continue with more complicated tests.
+ */
+#define FROM_HDR    "Bob <sip:bob@example.com>"
+#define CONTACT_HDR "Bob <sip:bob@127.0.0.1>"
+#define CALL_ID_HDR "SendRecv-Test"
+#define CSEQ_VALUE  100
+#define BODY	    "Hello World!"
+
+static pj_bool_t my_on_rx_request(pjsip_rx_data *rdata);
+static pj_bool_t my_on_rx_response(pjsip_rx_data *rdata);
+
+/* Flag to indicate message has been received
+ * (or failed to send)
+ */
+#define NO_STATUS   -2
+static int send_status = NO_STATUS;
+static int recv_status = NO_STATUS;
+static pj_timestamp my_send_time, my_recv_time;
+
+/* Module to receive messages for this test. */
+static pjsip_module my_module = 
+{
+    NULL, NULL,				/* prev and next	*/
+    { "Transport-Test", 14},		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TSX_LAYER-1,	/* Priority		*/
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &my_on_rx_request,			/* on_rx_request()	*/
+    &my_on_rx_response,			/* on_rx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+};
+
+
+static pj_bool_t my_on_rx_request(pjsip_rx_data *rdata)
+{
+    /* Check that this is our request. */
+    if (pj_strcmp2(&rdata->msg_info.cid->id, CALL_ID_HDR) == 0) {
+	/* It is! */
+	/* Send response. */
+	pjsip_tx_data *tdata;
+	pjsip_response_addr res_addr;
+	pj_status_t status;
+
+	status = pjsip_endpt_create_response( endpt, rdata, 200, NULL, &tdata);
+	if (status != PJ_SUCCESS) {
+	    recv_status = status;
+	    return PJ_TRUE;
+	}
+	status = pjsip_get_response_addr( tdata->pool, rdata, &res_addr);
+	if (status != PJ_SUCCESS) {
+	    recv_status = status;
+	    pjsip_tx_data_dec_ref(tdata);
+	    return PJ_TRUE;
+	}
+	status = pjsip_endpt_send_response( endpt, &res_addr, tdata, NULL, NULL);
+	if (status != PJ_SUCCESS) {
+	    recv_status = status;
+	    pjsip_tx_data_dec_ref(tdata);
+	    return PJ_TRUE;
+	}
+	return PJ_TRUE;
+    }
+    
+    /* Not ours. */
+    return PJ_FALSE;
+}
+
+static pj_bool_t my_on_rx_response(pjsip_rx_data *rdata)
+{
+    if (pj_strcmp2(&rdata->msg_info.cid->id, CALL_ID_HDR) == 0) {
+	pj_get_timestamp(&my_recv_time);
+	recv_status = PJ_SUCCESS;
+	return PJ_TRUE;
+    }
+    return PJ_FALSE;
+}
+
+/* Transport callback. */
+static void send_msg_callback(pjsip_send_state *stateless_data,
+			      pj_ssize_t sent, pj_bool_t *cont)
+{
+    PJ_UNUSED_ARG(stateless_data);
+
+    if (sent < 1) {
+	/* Obtain the error code. */
+	send_status = (int)-sent;
+    } else {
+	send_status = PJ_SUCCESS;
+    }
+
+    /* Don't want to continue. */
+    *cont = PJ_FALSE;
+}
+
+
+/* Test that we receive loopback message. */
+int transport_send_recv_test( pjsip_transport_type_e tp_type,
+			      pjsip_transport *ref_tp,
+			      char *target_url,
+			      int *p_usec_rtt)
+{
+    pj_bool_t msg_log_enabled;
+    pj_status_t status;
+    pj_str_t target, from, to, contact, call_id, body;
+    pjsip_method method;
+    pjsip_tx_data *tdata;
+    pj_time_val timeout;
+
+    PJ_UNUSED_ARG(tp_type);
+    PJ_UNUSED_ARG(ref_tp);
+
+    PJ_LOG(3,(THIS_FILE, "  single message round-trip test..."));
+
+    /* Register out test module to receive the message (if necessary). */
+    if (my_module.id == -1) {
+	status = pjsip_endpt_register_module( endpt, &my_module );
+	if (status != PJ_SUCCESS) {
+	    app_perror("   error: unable to register module", status);
+	    return -500;
+	}
+    }
+
+    /* Disable message logging. */
+    msg_log_enabled = msg_logger_set_enabled(0);
+
+    /* Create a request message. */
+    target = pj_str(target_url);
+    from = pj_str(FROM_HDR);
+    to = pj_str(target_url);
+    contact = pj_str(CONTACT_HDR);
+    call_id = pj_str(CALL_ID_HDR);
+    body = pj_str(BODY);
+
+    pjsip_method_set(&method, PJSIP_OPTIONS_METHOD);
+    status = pjsip_endpt_create_request( endpt, &method, &target, &from, &to,
+					 &contact, &call_id, CSEQ_VALUE, 
+					 &body, &tdata );
+    if (status != PJ_SUCCESS) {
+	app_perror("   error: unable to create request", status);
+	return -510;
+    }
+
+    /* Reset statuses */
+    send_status = recv_status = NO_STATUS;
+
+    /* Start time. */
+    pj_get_timestamp(&my_send_time);
+
+    /* Send the message (statelessly). */
+    PJ_LOG(5,(THIS_FILE, "Sending request to %.*s", 
+			 (int)target.slen, target.ptr));
+    status = pjsip_endpt_send_request_stateless( endpt, tdata, NULL,
+					         &send_msg_callback);
+    if (status != PJ_SUCCESS) {
+	/* Immediate error! */
+	pjsip_tx_data_dec_ref(tdata);
+	send_status = status;
+    }
+
+    /* Set the timeout (2 seconds from now) */
+    pj_gettimeofday(&timeout);
+    timeout.sec += 2;
+
+    /* Loop handling events until we get status */
+    do {
+	pj_time_val now;
+	pj_time_val poll_interval = { 0, 10 };
+
+	pj_gettimeofday(&now);
+	if (PJ_TIME_VAL_GTE(now, timeout)) {
+	    PJ_LOG(3,(THIS_FILE, "   error: timeout in send/recv test"));
+	    status = -540;
+	    goto on_return;
+	}
+
+	if (send_status!=NO_STATUS && send_status!=PJ_SUCCESS) {
+	    app_perror("   error sending message", send_status);
+	    status = -550;
+	    goto on_return;
+	}
+
+	if (recv_status!=NO_STATUS && recv_status!=PJ_SUCCESS) {
+	    app_perror("   error receiving message", recv_status);
+	    status = -560;
+	    goto on_return;
+	}
+
+	if (send_status!=NO_STATUS && recv_status!=NO_STATUS) {
+	    /* Success! */
+	    break;
+	}
+
+	pjsip_endpt_handle_events(endpt, &poll_interval);
+
+    } while (1);
+
+    if (status == PJ_SUCCESS) {
+	unsigned usec_rt;
+	usec_rt = pj_elapsed_usec(&my_send_time, &my_recv_time);
+
+	PJ_LOG(3,(THIS_FILE, "    round-trip = %d usec", usec_rt));
+
+	*p_usec_rtt = usec_rt;
+    }
+
+    /* Restore message logging. */
+    msg_logger_set_enabled(msg_log_enabled);
+
+    status = PJ_SUCCESS;
+
+on_return:
+    return status;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/* 
+ * Multithreaded round-trip test
+ *
+ * This test will spawn multiple threads, each of them send a request. As soon
+ * as request is received, response will be sent, and time is recorded.
+ *
+ * The main purpose of this test is to ensure there's no crash when multiple
+ * threads are sending/receiving messages.
+ *
+ */
+static pj_bool_t rt_on_rx_request(pjsip_rx_data *rdata);
+static pj_bool_t rt_on_rx_response(pjsip_rx_data *rdata);
+
+static pjsip_module rt_module = 
+{
+    NULL, NULL,				/* prev and next	*/
+    { "Transport-RT-Test", 17},		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TSX_LAYER-1,	/* Priority		*/
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &rt_on_rx_request,			/* on_rx_request()	*/
+    &rt_on_rx_response,			/* on_rx_response()	*/
+    NULL,				/* tsx_handler()	*/
+};
+
+static struct
+{
+    pj_thread_t *thread;
+    pj_timestamp send_time;
+    pj_timestamp total_rt_time;
+    int sent_request_count, recv_response_count;
+    pj_str_t call_id;
+    pj_timer_entry timeout_timer;
+    pj_timer_entry tx_timer;
+    pj_mutex_t *mutex;
+} rt_test_data[16];
+
+static char	 rt_target_uri[64];
+static pj_bool_t rt_stop;
+static pj_str_t  rt_call_id;
+
+static pj_bool_t rt_on_rx_request(pjsip_rx_data *rdata)
+{
+    if (!pj_strncmp(&rdata->msg_info.cid->id, &rt_call_id, rt_call_id.slen)) {
+	pjsip_tx_data *tdata;
+	pjsip_response_addr res_addr;
+	pj_status_t status;
+
+	status = pjsip_endpt_create_response( endpt, rdata, 200, NULL, &tdata);
+	if (status != PJ_SUCCESS) {
+	    app_perror("    error creating response", status);
+	    return PJ_TRUE;
+	}
+	status = pjsip_get_response_addr( tdata->pool, rdata, &res_addr);
+	if (status != PJ_SUCCESS) {
+	    app_perror("    error in get response address", status);
+	    pjsip_tx_data_dec_ref(tdata);
+	    return PJ_TRUE;
+	}
+	status = pjsip_endpt_send_response( endpt, &res_addr, tdata, NULL, NULL);
+	if (status != PJ_SUCCESS) {
+	    app_perror("    error sending response", status);
+	    pjsip_tx_data_dec_ref(tdata);
+	    return PJ_TRUE;
+	}
+	return PJ_TRUE;
+	
+    }
+    return PJ_FALSE;
+}
+
+static pj_status_t rt_send_request(int thread_id)
+{
+    pj_status_t status;
+    pj_str_t target, from, to, contact, call_id;
+    pjsip_tx_data *tdata;
+    pj_time_val timeout_delay;
+
+    pj_mutex_lock(rt_test_data[thread_id].mutex);
+
+    /* Create a request message. */
+    target = pj_str(rt_target_uri);
+    from = pj_str(FROM_HDR);
+    to = pj_str(rt_target_uri);
+    contact = pj_str(CONTACT_HDR);
+    call_id = rt_test_data[thread_id].call_id;
+
+    status = pjsip_endpt_create_request( endpt, &pjsip_options_method, 
+					 &target, &from, &to,
+					 &contact, &call_id, -1, 
+					 NULL, &tdata );
+    if (status != PJ_SUCCESS) {
+	app_perror("    error: unable to create request", status);
+	pj_mutex_unlock(rt_test_data[thread_id].mutex);
+	return -610;
+    }
+
+    /* Start time. */
+    pj_get_timestamp(&rt_test_data[thread_id].send_time);
+
+    /* Send the message (statelessly). */
+    status = pjsip_endpt_send_request_stateless( endpt, tdata, NULL, NULL);
+    if (status != PJ_SUCCESS) {
+	/* Immediate error! */
+	app_perror("    error: send request", status);
+	pjsip_tx_data_dec_ref(tdata);
+	pj_mutex_unlock(rt_test_data[thread_id].mutex);
+	return -620;
+    }
+
+    /* Update counter. */
+    rt_test_data[thread_id].sent_request_count++;
+
+    /* Set timeout timer. */
+    if (rt_test_data[thread_id].timeout_timer.user_data != NULL) {
+	pjsip_endpt_cancel_timer(endpt, &rt_test_data[thread_id].timeout_timer);
+    }
+    timeout_delay.sec = 100; timeout_delay.msec = 0;
+    rt_test_data[thread_id].timeout_timer.user_data = (void*)(pj_ssize_t)1;
+    pjsip_endpt_schedule_timer(endpt, &rt_test_data[thread_id].timeout_timer,
+			       &timeout_delay);
+
+    pj_mutex_unlock(rt_test_data[thread_id].mutex);
+    return PJ_SUCCESS;
+}
+
+static pj_bool_t rt_on_rx_response(pjsip_rx_data *rdata)
+{
+    if (!pj_strncmp(&rdata->msg_info.cid->id, &rt_call_id, rt_call_id.slen)) {
+	char *pos = pj_strchr(&rdata->msg_info.cid->id, '/')+1;
+	int thread_id = (*pos - '0');
+	pj_timestamp recv_time;
+
+	pj_mutex_lock(rt_test_data[thread_id].mutex);
+
+	/* Stop timer. */
+	pjsip_endpt_cancel_timer(endpt, &rt_test_data[thread_id].timeout_timer);
+
+	/* Update counter and end-time. */
+	rt_test_data[thread_id].recv_response_count++;
+	pj_get_timestamp(&recv_time);
+
+	pj_sub_timestamp(&recv_time, &rt_test_data[thread_id].send_time);
+	pj_add_timestamp(&rt_test_data[thread_id].total_rt_time, &recv_time);
+
+	if (!rt_stop) {
+	    pj_time_val tx_delay = { 0, 0 };
+	    pj_assert(rt_test_data[thread_id].tx_timer.user_data == NULL);
+	    rt_test_data[thread_id].tx_timer.user_data = (void*)(pj_ssize_t)1;
+	    pjsip_endpt_schedule_timer(endpt, &rt_test_data[thread_id].tx_timer,
+				       &tx_delay);
+	}
+
+	pj_mutex_unlock(rt_test_data[thread_id].mutex);
+
+	return PJ_TRUE;
+    }
+    return PJ_FALSE;
+}
+
+static void rt_timeout_timer( pj_timer_heap_t *timer_heap,
+			      struct pj_timer_entry *entry )
+{
+    pj_mutex_lock(rt_test_data[entry->id].mutex);
+
+    PJ_UNUSED_ARG(timer_heap);
+    PJ_LOG(3,(THIS_FILE, "    timeout waiting for response"));
+    rt_test_data[entry->id].timeout_timer.user_data = NULL;
+    
+    if (rt_test_data[entry->id].tx_timer.user_data == NULL) {
+	pj_time_val delay = { 0, 0 };
+	rt_test_data[entry->id].tx_timer.user_data = (void*)(pj_ssize_t)1;
+	pjsip_endpt_schedule_timer(endpt, &rt_test_data[entry->id].tx_timer,
+				   &delay);
+    }
+
+    pj_mutex_unlock(rt_test_data[entry->id].mutex);
+}
+
+static void rt_tx_timer( pj_timer_heap_t *timer_heap,
+			 struct pj_timer_entry *entry )
+{
+    pj_mutex_lock(rt_test_data[entry->id].mutex);
+
+    PJ_UNUSED_ARG(timer_heap);
+    pj_assert(rt_test_data[entry->id].tx_timer.user_data != NULL);
+    rt_test_data[entry->id].tx_timer.user_data = NULL;
+    rt_send_request(entry->id);
+
+    pj_mutex_unlock(rt_test_data[entry->id].mutex);
+}
+
+
+static int rt_worker_thread(void *arg)
+{
+    int i;
+    pj_time_val poll_delay = { 0, 10 };
+
+    PJ_UNUSED_ARG(arg);
+
+    /* Sleep to allow main threads to run. */
+    pj_thread_sleep(10);
+
+    while (!rt_stop) {
+	pjsip_endpt_handle_events(endpt, &poll_delay);
+    }
+
+    /* Exhaust responses. */
+    for (i=0; i<100; ++i)
+	pjsip_endpt_handle_events(endpt, &poll_delay);
+
+    return 0;
+}
+
+int transport_rt_test( pjsip_transport_type_e tp_type,
+		       pjsip_transport *ref_tp,
+		       char *target_url,
+		       int *lost)
+{
+    enum { THREADS = 4, INTERVAL = 10 };
+    int i;
+    pj_status_t status;
+    pj_pool_t *pool;
+    pj_bool_t logger_enabled;
+
+    pj_timestamp zero_time, total_time;
+    unsigned usec_rt;
+    unsigned total_sent;
+    unsigned total_recv;
+
+    PJ_UNUSED_ARG(tp_type);
+    PJ_UNUSED_ARG(ref_tp);
+
+    PJ_LOG(3,(THIS_FILE, "  multithreaded round-trip test (%d threads)...",
+		  THREADS));
+    PJ_LOG(3,(THIS_FILE, "    this will take approx %d seconds, please wait..",
+		INTERVAL));
+
+    /* Make sure msg logger is disabled. */
+    logger_enabled = msg_logger_set_enabled(0);
+
+    /* Register module (if not yet registered) */
+    if (rt_module.id == -1) {
+	status = pjsip_endpt_register_module( endpt, &rt_module );
+	if (status != PJ_SUCCESS) {
+	    app_perror("   error: unable to register module", status);
+	    return -600;
+	}
+    }
+
+    /* Create pool for this test. */
+    pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
+    if (!pool)
+	return -610;
+
+    /* Initialize static test data. */
+    pj_ansi_strcpy(rt_target_uri, target_url);
+    rt_call_id = pj_str("RT-Call-Id/");
+    rt_stop = PJ_FALSE;
+
+    /* Initialize thread data. */
+    for (i=0; i<THREADS; ++i) {
+	char buf[1];
+	pj_str_t str_id;
+	
+	pj_strset(&str_id, buf, 1);
+	pj_bzero(&rt_test_data[i], sizeof(rt_test_data[i]));
+
+	/* Init timer entry */
+	rt_test_data[i].tx_timer.id = i;
+	rt_test_data[i].tx_timer.cb = &rt_tx_timer;
+	rt_test_data[i].timeout_timer.id = i;
+	rt_test_data[i].timeout_timer.cb = &rt_timeout_timer;
+
+	/* Generate Call-ID for each thread. */
+	rt_test_data[i].call_id.ptr = (char*) pj_pool_alloc(pool, rt_call_id.slen+1);
+	pj_strcpy(&rt_test_data[i].call_id, &rt_call_id);
+	buf[0] = '0' + (char)i;
+	pj_strcat(&rt_test_data[i].call_id, &str_id);
+
+	/* Init mutex. */
+	status = pj_mutex_create_recursive(pool, "rt", &rt_test_data[i].mutex);
+	if (status != PJ_SUCCESS) {
+	    app_perror("   error: unable to create mutex", status);
+	    return -615;
+	}
+
+	/* Create thread, suspended. */
+	status = pj_thread_create(pool, "rttest%p", &rt_worker_thread, 
+				  (void*)(pj_ssize_t)i, 0,
+				  PJ_THREAD_SUSPENDED, &rt_test_data[i].thread);
+	if (status != PJ_SUCCESS) {
+	    app_perror("   error: unable to create thread", status);
+	    return -620;
+	}
+    }
+
+    /* Start threads! */
+    for (i=0; i<THREADS; ++i) {
+	pj_time_val delay = {0,0};
+	pj_thread_resume(rt_test_data[i].thread);
+
+	/* Schedule first message transmissions. */
+	rt_test_data[i].tx_timer.user_data = (void*)(pj_ssize_t)1;
+	pjsip_endpt_schedule_timer(endpt, &rt_test_data[i].tx_timer, &delay);
+    }
+
+    /* Sleep for some time. */
+    pj_thread_sleep(INTERVAL * 1000);
+
+    /* Signal thread to stop. */
+    rt_stop = PJ_TRUE;
+
+    /* Wait threads to complete. */
+    for (i=0; i<THREADS; ++i) {
+	pj_thread_join(rt_test_data[i].thread);
+	pj_thread_destroy(rt_test_data[i].thread);
+    }
+
+    /* Destroy rt_test_data */
+    for (i=0; i<THREADS; ++i) {
+	pj_mutex_destroy(rt_test_data[i].mutex);
+	pjsip_endpt_cancel_timer(endpt, &rt_test_data[i].timeout_timer);
+    }
+
+    /* Gather statistics. */
+    pj_bzero(&total_time, sizeof(total_time));
+    pj_bzero(&zero_time, sizeof(zero_time));
+    usec_rt = total_sent = total_recv = 0;
+    for (i=0; i<THREADS; ++i) {
+	total_sent += rt_test_data[i].sent_request_count;
+	total_recv +=  rt_test_data[i].recv_response_count;
+	pj_add_timestamp(&total_time, &rt_test_data[i].total_rt_time);
+    }
+
+    /* Display statistics. */
+    if (total_recv)
+	total_time.u64 = total_time.u64/total_recv;
+    else
+	total_time.u64 = 0;
+    usec_rt = pj_elapsed_usec(&zero_time, &total_time);
+    PJ_LOG(3,(THIS_FILE, "    done."));
+    PJ_LOG(3,(THIS_FILE, "    total %d messages sent", total_sent));
+    PJ_LOG(3,(THIS_FILE, "    average round-trip=%d usec", usec_rt));
+
+    pjsip_endpt_release_pool(endpt, pool);
+
+    *lost = total_sent-total_recv;
+
+    /* Flush events. */
+    flush_events(500);
+
+    /* Restore msg logger. */
+    msg_logger_set_enabled(logger_enabled);
+
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Transport load testing
+ */
+static pj_bool_t load_on_rx_request(pjsip_rx_data *rdata);
+
+static struct mod_load_test
+{
+    pjsip_module    mod;
+    pj_int32_t	    next_seq;
+    pj_bool_t	    err;
+} mod_load = 
+{
+    {
+    NULL, NULL,				/* prev and next	*/
+    { "mod-load-test", 13},		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TSX_LAYER-1,	/* Priority		*/
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &load_on_rx_request,		/* on_rx_request()	*/
+    NULL,				/* on_rx_response()	*/
+    NULL,				/* tsx_handler()	*/
+    }
+};
+
+
+static pj_bool_t load_on_rx_request(pjsip_rx_data *rdata)
+{
+    if (rdata->msg_info.cseq->cseq != mod_load.next_seq) {
+	PJ_LOG(1,("THIS_FILE", "    err: expecting cseq %u, got %u", 
+		  mod_load.next_seq, rdata->msg_info.cseq->cseq));
+	mod_load.err = PJ_TRUE;
+	mod_load.next_seq = rdata->msg_info.cseq->cseq + 1;
+    } else 
+	mod_load.next_seq++;
+    return PJ_TRUE;
+}
+
+int transport_load_test(char *target_url)
+{
+    enum { COUNT = 2000 };
+    unsigned i;
+    pj_status_t status = PJ_SUCCESS;
+
+    /* exhaust packets */
+    do {
+	pj_time_val delay = {1, 0};
+	i = 0;
+	pjsip_endpt_handle_events2(endpt, &delay, &i);
+    } while (i != 0);
+
+    PJ_LOG(3,(THIS_FILE, "  transport load test..."));
+
+    if (mod_load.mod.id == -1) {
+	status = pjsip_endpt_register_module( endpt, &mod_load.mod);
+	if (status != PJ_SUCCESS) {
+	    app_perror("error registering module", status);
+	    return -1;
+	}
+    }
+    mod_load.err = PJ_FALSE;
+    mod_load.next_seq = 0;
+
+    for (i=0; i<COUNT && !mod_load.err; ++i) {
+	pj_str_t target, from, call_id;
+	pjsip_tx_data *tdata;
+
+	target = pj_str(target_url);
+	from = pj_str("<sip:user@host>");
+	call_id = pj_str("thecallid");
+	status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, 
+					    &target, &from, 
+					    &target, &from, &call_id, 
+					    i, NULL, &tdata );
+	if (status != PJ_SUCCESS) {
+	    app_perror("error creating request", status);
+	    goto on_return;
+	}
+
+	status = pjsip_endpt_send_request_stateless(endpt, tdata, NULL, NULL);
+	if (status != PJ_SUCCESS) {
+	    app_perror("error sending request", status);
+	    goto on_return;
+	}
+    }
+
+    do {
+	pj_time_val delay = {1, 0};
+	i = 0;
+	pjsip_endpt_handle_events2(endpt, &delay, &i);
+    } while (i != 0);
+
+    if (mod_load.next_seq != COUNT) {
+	PJ_LOG(1,("THIS_FILE", "    err: expecting %u msg, got only %u", 
+		  COUNT, mod_load.next_seq));
+	status = -2;
+	goto on_return;
+    }
+
+on_return:
+    if (mod_load.mod.id != -1) {
+	pjsip_endpt_unregister_module( endpt, &mod_load.mod);
+	mod_load.mod.id = -1;
+    }
+    if (status != PJ_SUCCESS || mod_load.err) {
+	return -2;
+    }
+    PJ_LOG(3,(THIS_FILE, "   success"));
+    return 0;
+}
+
+