/* $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;
}


