/* $Id$ */
/* 
 * Copyright (C) 2003-2006 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 
 */


/**
 * \page page_pjsip_perf_c Samples: SIP Performance Benchmark
 *
 * <b>pjsip-perf</b> is a complete program to measure the
 * performance of PJSIP or other SIP endpoints. It consists of two
 * parts:
 *  - the server, to respond incoming requests, and
 *  - the client, who actively submits requests and measure the
 *     performance of the server.
 *
 * Both server and client part can run simultaneously, to measure the
 * performance when both endpoints are co-located in a single program.
 * 
 * The server accepts both INVITE and non-INVITE requests.
 * The server exports several different types of URL, which would
 * control how the request would be handled by the server:
 *  - URL with "0" as the user part will be handled statelessly.
 *    It should not be used with INVITE method.
 *  - URL with "1" as the user part will be handled statefully.
 *    If the request is an INVITE request, INVITE transaction will
 *    be created and 200/OK response will be sent, along with a valid
 *    SDP body. However, the SDP is just a static text body, and
 *    is not a proper SDP generated by PJMEDIA.
 *  - URL with "2" as the user part is only meaningful for INVITE
 *    requests, as it would be handled <b>call-statefully</b> by the
 *    server. For this URL, the server also would generate SDP dynamically
 *    and perform a proper SDP negotiation for the incoming call.
 *    Also for every call, server will limit the call duration to
 *    10 seconds, on which the call will be terminated if the client
 *    doesn't hangup the call.
 *    
 *
 *
 * This file is pjsip-apps/src/samples/pjsip-perf.c
 *
 * \includelineno pjsip-perf.c
 */

/* Include all headers. */
#include <pjsip.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#include <pjsip_ua.h>
#include <pjsip_simple.h>
#include <pjlib-util.h>
#include <pjlib.h>
#include <stdio.h>

#if defined(PJ_WIN32) && PJ_WIN32!=0
#  include <windows.h>
#endif

#define THIS_FILE	    "pjsip-perf.c"
#define DEFAULT_COUNT	    (PJSIP_MAX_TSX_COUNT/2>10000?10000:PJSIP_MAX_TSX_COUNT/2)
#define JOB_WINDOW	    1000
#define TERMINATE_TSX(x,c)


#ifndef CACHING_POOL_SIZE
#   define CACHING_POOL_SIZE   (256*1024*1024)
#endif


/* Static message body for INVITE, when stateful processing is
 * invoked (instead of call-stateful, where SDP is generated
 * dynamically.
 */
static pj_str_t dummy_sdp_str = 
{
    "v=0\r\n"
    "o=- 3360842071 3360842071 IN IP4 192.168.0.68\r\n"
    "s=pjmedia\r\n"
    "c=IN IP4 192.168.0.68\r\n"
    "t=0 0\r\n"
    "m=audio 4000 RTP/AVP 103 102 3 0 8 101\r\n"
    "a=rtcp:4001 IN IP4 192.168.0.68\r\n"
    "a=rtpmap:103 speex/16000\r\n"
    "a=rtpmap:102 speex/8000\r\n"
    "a=rtpmap:3 GSM/8000\r\n"
    "a=rtpmap:0 PCMU/8000\r\n"
    "a=rtpmap:8 PCMA/8000\r\n"
    "a=sendrecv\r\n"
    "a=rtpmap:101 telephone-event/8000\r\n"
    "a=fmtp:101 0-15\r\n",
    0
};

static pj_str_t mime_application = { "application", 11};
static pj_str_t mime_sdp = {"sdp", 3};


struct srv_state
{
    unsigned	    stateless_cnt;
    unsigned	    stateful_cnt;
    unsigned	    call_cnt;
};


struct app
{
    pj_caching_pool	 cp;
    pj_pool_t		*pool;
    pj_bool_t		 use_tcp;
    pj_str_t		 local_addr;
    int			 local_port;
    pjsip_endpoint	*sip_endpt;
    pjmedia_endpt	*med_endpt;
    pj_str_t		 local_uri;
    pj_str_t		 local_contact;
    unsigned		 skinfo_cnt;
    pjmedia_sock_info	 skinfo[8];

    pj_bool_t		 thread_quit;
    unsigned		 thread_count;
    pj_thread_t		*thread[16];

    pj_bool_t		 real_sdp;
    pjmedia_sdp_session *dummy_sdp;

    int			 log_level;

    struct {
	pjsip_method	     method;
	pj_str_t	     dst_uri;
	pj_bool_t	     stateless;
	unsigned	     timeout;
	unsigned	     job_count,
			     job_submitted, 
			     job_finished,
			     job_window;
	unsigned	     stat_max_window;
	pj_time_val	     first_request;
	pj_time_val	     requests_sent;
	pj_time_val	     last_completion;
	unsigned	     total_responses;
	unsigned	     response_codes[800];
    } client;

    struct {
	struct srv_state prev_state;
	struct srv_state cur_state;
    } server;


} app;

struct call
{
    pjsip_inv_session	*inv;
    pj_timer_entry	 timer;
};


static void app_perror(const char *sender, const char *title, 
		       pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];

    pj_strerror(status, errmsg, sizeof(errmsg));
    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
}


/**************************************************************************
 * STATELESS SERVER
 */
static pj_bool_t mod_stateless_on_rx_request(pjsip_rx_data *rdata);

/* Module to handle incoming requests statelessly.
 */
static pjsip_module mod_stateless_server =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-stateless-server", 20 }, /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    &mod_stateless_on_rx_request,   /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


static pj_bool_t mod_stateless_on_rx_request(pjsip_rx_data *rdata)
{
    const pj_str_t stateless_user = { "0", 1 };
    pjsip_uri *uri;
    pjsip_sip_uri *sip_uri;

    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);

    /* Only want to receive SIP scheme */
    if (!PJSIP_URI_SCHEME_IS_SIP(uri))
	return PJ_FALSE;

    sip_uri = (pjsip_sip_uri*) uri;

    /* Check for matching user part */
    if (pj_strcmp(&sip_uri->user, &stateless_user)!=0)
	return PJ_FALSE;

    /*
     * Yes, this is for us.
     */

    /* Ignore ACK request */
    if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD)
	return PJ_TRUE;

    /*
     * Respond statelessly with 200/OK.
     */
    pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 200, NULL,
				  NULL, NULL);
    app.server.cur_state.stateless_cnt++;
    return PJ_TRUE;
}


/**************************************************************************
 * STATEFUL SERVER
 */
static pj_bool_t mod_stateful_on_rx_request(pjsip_rx_data *rdata);

/* Module to handle incoming requests statefully.
 */
static pjsip_module mod_stateful_server =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-stateful-server", 19 },  /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    &mod_stateful_on_rx_request,   /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


static pj_bool_t mod_stateful_on_rx_request(pjsip_rx_data *rdata)
{
    const pj_str_t stateful_user = { "1", 1 };
    pjsip_uri *uri;
    pjsip_sip_uri *sip_uri;

    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);

    /* Only want to receive SIP scheme */
    if (!PJSIP_URI_SCHEME_IS_SIP(uri))
	return PJ_FALSE;

    sip_uri = (pjsip_sip_uri*) uri;

    /* Check for matching user part */
    if (pj_strcmp(&sip_uri->user, &stateful_user)!=0)
	return PJ_FALSE;

    /*
     * Yes, this is for us.
     * Respond statefully with 200/OK.
     */
    switch (rdata->msg_info.msg->line.req.method.id) {
    case PJSIP_INVITE_METHOD:
	{
	    pjsip_msg_body *body;

	    if (dummy_sdp_str.slen == 0)
		dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);

	    body = pjsip_msg_body_create(rdata->tp_info.pool, 
					 &mime_application, &mime_sdp, 
					 &dummy_sdp_str);
	    pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
				200, NULL, NULL, body, NULL);
	}
	break;
    case PJSIP_ACK_METHOD:
	return PJ_TRUE;
    default:
	pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
			    200, NULL, NULL, NULL, NULL);
	break;
    }

    app.server.cur_state.stateful_cnt++;
    return PJ_TRUE;
}


/**************************************************************************
 * CALL SERVER
 */
static pj_bool_t mod_call_on_rx_request(pjsip_rx_data *rdata);

/* Module to handle incoming requests callly.
 */
static pjsip_module mod_call_server =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-call-server", 15 },	    /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    &mod_call_on_rx_request,	    /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


static pj_bool_t mod_call_on_rx_request(pjsip_rx_data *rdata)
{
    const pj_str_t call_user = { "2", 1 };
    pjsip_uri *uri;
    pjsip_sip_uri *sip_uri;
    struct call *call;
    pjsip_dialog *dlg;
    pjmedia_sdp_session *sdp;
    pjsip_tx_data *tdata;
    pj_status_t status;

    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);

    /* Only want to receive SIP scheme */
    if (!PJSIP_URI_SCHEME_IS_SIP(uri))
	return PJ_FALSE;

    sip_uri = (pjsip_sip_uri*) uri;

    /* Only want to handle INVITE requests. */
    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
	return PJ_FALSE;
    }


    /* Check for matching user part. Incoming requests will be handled 
     * call-statefully if:
     *	- user part is "2", or
     *  - user part is not "0" nor "1" and method is INVITE.
     */
    if (pj_strcmp(&sip_uri->user, &call_user) == 0 ||
	sip_uri->user.slen != 1 ||
	(*sip_uri->user.ptr != '0' && *sip_uri->user.ptr != '1'))
    {
	/* Match */

    } else {
	return PJ_FALSE;
    }


    /* Verify that we can handle the request. */
    if (app.real_sdp) {
	unsigned options = 0;
	status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
					  app.sip_endpt, &tdata);
	if (status != PJ_SUCCESS) {

	    /*
	     * No we can't handle the incoming INVITE request.
	     */

	    if (tdata) {
		pjsip_response_addr res_addr;

		pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
		pjsip_endpt_send_response(app.sip_endpt, &res_addr, tdata, 
					  NULL, NULL);

	    } else {

		/* Respond with 500 (Internal Server Error) */
		pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, NULL,
					      NULL, NULL);
	    }

	    return PJ_TRUE;
	} 
    }

    /* Create UAS dialog */
    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
				   &app.local_contact, &dlg);
    if (status != PJ_SUCCESS) {
	const pj_str_t reason = pj_str("Unable to create dialog");
	pjsip_endpt_respond_stateless( app.sip_endpt, rdata, 
				       500, &reason,
				       NULL, NULL);
	return PJ_TRUE;
    }

    /* Alloc call structure. */
    call = pj_pool_zalloc(dlg->pool, sizeof(struct call));

    /* Create SDP from PJMEDIA */
    if (app.real_sdp) {
	status = pjmedia_endpt_create_sdp(app.med_endpt, rdata->tp_info.pool, 
					  app.skinfo_cnt, app.skinfo, 
					  &sdp);
    } else {
	sdp = app.dummy_sdp;
    }

    /* Create UAS invite session */
    status = pjsip_inv_create_uas( dlg, rdata, sdp, 0, &call->inv);
    if (status != PJ_SUCCESS) {
	pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
	pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
	return PJ_TRUE;
    }
    

    /* Create 200 response .*/
    status = pjsip_inv_initial_answer(call->inv, rdata, 200, 
				      NULL, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	status = pjsip_inv_initial_answer(call->inv, rdata, 
					  PJSIP_SC_NOT_ACCEPTABLE,
					  NULL, NULL, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_inv_send_msg(call->inv, tdata); 
	else
	    pjsip_inv_terminate(call->inv, 500, PJ_FALSE);
	return PJ_TRUE;
    }


    /* Send the 200 response. */  
    status = pjsip_inv_send_msg(call->inv, tdata); 
    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return PJ_TRUE);


    /* Done */
    app.server.cur_state.call_cnt++;

    return PJ_TRUE;
}



/**************************************************************************
 * Default handler when incoming request is not handled by any other
 * modules.
 */
static pj_bool_t mod_responder_on_rx_request(pjsip_rx_data *rdata);

/* Module to handle incoming requests statelessly.
 */
static pjsip_module mod_responder =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-responder", 13 },	    /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION+1, /* Priority		*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    &mod_responder_on_rx_request,   /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


static pj_bool_t mod_responder_on_rx_request(pjsip_rx_data *rdata)
{
    const pj_str_t reason = pj_str("Not expecting request at this URI");

    /*
     * Respond any requests (except ACK!) with 500.
     */
    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
	pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, &reason,
				      NULL, NULL);
    }

    return PJ_TRUE;
}



/*****************************************************************************
 * Below is a simple module to log all incoming and outgoing SIP messages
 */


/* Notification on incoming messages */
static pj_bool_t logger_on_rx_msg(pjsip_rx_data *rdata)
{
    PJ_LOG(3,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
			 "%.*s\n"
			 "--end msg--",
			 rdata->msg_info.len,
			 pjsip_rx_data_get_info(rdata),
			 rdata->tp_info.transport->type_name,
			 rdata->pkt_info.src_name,
			 rdata->pkt_info.src_port,
			 (int)rdata->msg_info.len,
			 rdata->msg_info.msg_buf));
    
    /* Always return false, otherwise messages will not get processed! */
    return PJ_FALSE;
}

/* Notification on outgoing messages */
static pj_status_t logger_on_tx_msg(pjsip_tx_data *tdata)
{
    
    /* Important note:
     *	tp_info field is only valid after outgoing messages has passed
     *	transport layer. So don't try to access tp_info when the module
     *	has lower priority than transport layer.
     */

    PJ_LOG(3,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
			 "%.*s\n"
			 "--end msg--",
			 (tdata->buf.cur - tdata->buf.start),
			 pjsip_tx_data_get_info(tdata),
			 tdata->tp_info.transport->type_name,
			 tdata->tp_info.dst_name,
			 tdata->tp_info.dst_port,
			 (int)(tdata->buf.cur - tdata->buf.start),
			 tdata->buf.start));

    /* Always return success, otherwise message will not get sent! */
    return PJ_SUCCESS;
}

/* The module instance. */
static pjsip_module msg_logger = 
{
    NULL, NULL,				/* prev, next.		*/
    { "mod-siprtp-log", 14 },		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    &logger_on_rx_msg,			/* on_rx_request()	*/
    &logger_on_rx_msg,			/* on_rx_response()	*/
    &logger_on_tx_msg,			/* on_tx_request.	*/
    &logger_on_tx_msg,			/* on_tx_response()	*/
    NULL,				/* on_tsx_state()	*/

};



/**************************************************************************
 * Test Client.
 */

static pj_bool_t mod_test_on_rx_response(pjsip_rx_data *rdata);

static void call_on_media_update( pjsip_inv_session *inv,
				  pj_status_t status);
static void call_on_state_changed( pjsip_inv_session *inv, 
				   pjsip_event *e);
static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);


/* Module to handle incoming requests callly.
 */
static pjsip_module mod_test =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-test", 8 },		    /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    NULL,			    /* on_rx_request()		*/
    &mod_test_on_rx_response,	    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


static void report_completion(int status_code)
{
    app.client.job_finished++;
    if (status_code >= 200 && status_code < 800)
	app.client.response_codes[status_code]++;
    app.client.total_responses++;
    pj_gettimeofday(&app.client.last_completion);
}


/* Handler when response is received. */
static pj_bool_t mod_test_on_rx_response(pjsip_rx_data *rdata)
{
    if (pjsip_rdata_get_tsx(rdata) == NULL) {
	report_completion(rdata->msg_info.msg->line.status.code);
    }

    return PJ_TRUE;
}


/*
 * Create app
 */
static pj_status_t create_app(void)
{
    pj_status_t status;

    status = pj_init();
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error initializing pjlib", status);
	return status;
    }

    /* init PJLIB-UTIL: */
    status = pjlib_util_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&app.cp, &pj_pool_factory_default_policy, 
			 CACHING_POOL_SIZE);

    /* Create application pool for misc. */
    app.pool = pj_pool_create(&app.cp.factory, "app", 1000, 1000, NULL);

    /* Create the endpoint: */
    status = pjsip_endpt_create(&app.cp.factory, pj_gethostname()->ptr, 
				&app.sip_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    return status;
}


/*
 * Init SIP stack
 */
static pj_status_t init_sip()
{
    pj_status_t status;

    /* Add UDP/TCP transport. */
    {
	pj_sockaddr_in addr;
	pjsip_host_port addrname;
	const char *transport_type;

	pj_bzero(&addr, sizeof(addr));
	addr.sin_family = PJ_AF_INET;
	addr.sin_addr.s_addr = 0;
	addr.sin_port = pj_htons((pj_uint16_t)app.local_port);

	if (app.local_addr.slen) {
	    addrname.host = app.local_addr;
	    addrname.port = 5060;
	} 
	if (app.local_port != 0)
	    addrname.port = app.local_port;

	if (app.use_tcp) {
	    pj_sockaddr_in local_addr;
	    pjsip_tpfactory *tpfactory;
	    
	    transport_type = "tcp";
	    pj_sockaddr_in_init(&local_addr, 0, (pj_uint16_t)app.local_port);
	    status = pjsip_tcp_transport_start(app.sip_endpt, &local_addr,
					       app.thread_count, &tpfactory);
	    if (status == PJ_SUCCESS) {
		app.local_addr = tpfactory->addr_name.host;
		app.local_port = tpfactory->addr_name.port;
	    }
	} else {
	    pjsip_transport *tp;

	    transport_type = "udp";
	    status = pjsip_udp_transport_start(app.sip_endpt, &addr, 
					       (app.local_addr.slen ? &addrname:NULL),
					       app.thread_count, &tp);
	    if (status == PJ_SUCCESS) {
		app.local_addr = tp->local_name.host;
		app.local_port = tp->local_name.port;
	    }

	}
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to start transport", status);
	    return status;
	}

	app.local_uri.ptr = pj_pool_alloc(app.pool, 128);
	app.local_uri.slen = pj_ansi_sprintf(app.local_uri.ptr, 
				    	     "<sip:pjsip-perf@%.*s:%d;transport=%s>",
					     (int)app.local_addr.slen,
					     app.local_addr.ptr,
					     app.local_port,
					     transport_type);

	app.local_contact = app.local_uri;
    }

    /* 
     * Init transaction layer.
     * This will create/initialize transaction hash tables etc.
     */
    status = pjsip_tsx_layer_init_module(app.sip_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /*  Initialize UA layer. */
    status = pjsip_ua_init_module( app.sip_endpt, NULL );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /*  Init invite session module. */
    {
	pjsip_inv_callback inv_cb;

	/* Init the callback for INVITE session: */
	pj_bzero(&inv_cb, sizeof(inv_cb));
	inv_cb.on_state_changed = &call_on_state_changed;
	inv_cb.on_new_session = &call_on_forked;
	inv_cb.on_media_update = &call_on_media_update;

	/* Initialize invite session module:  */
	status = pjsip_inv_usage_init(app.sip_endpt, &inv_cb);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* Register our module to receive incoming requests. */
    status = pjsip_endpt_register_module( app.sip_endpt, &mod_test);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    /* Register stateless server module */
    status = pjsip_endpt_register_module( app.sip_endpt, &mod_stateless_server);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Register default responder module */
    status = pjsip_endpt_register_module( app.sip_endpt, &mod_responder);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Register stateless server module */
    status = pjsip_endpt_register_module( app.sip_endpt, &mod_stateful_server);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    /* Register call server module */
    status = pjsip_endpt_register_module( app.sip_endpt, &mod_call_server);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    /* Done */
    return PJ_SUCCESS;
}


/*
 * Destroy SIP
 */
static void destroy_app()
{
    unsigned i;

    app.thread_quit = 1;
    for (i=0; i<app.thread_count; ++i) {
	if (app.thread[i]) {
	    pj_thread_join(app.thread[i]);
	    pj_thread_destroy(app.thread[i]);
	    app.thread[i] = NULL;
	}
    }

    if (app.sip_endpt) {
	pjsip_endpt_destroy(app.sip_endpt);
	app.sip_endpt = NULL;
    }

    if (app.pool) {
	pj_pool_release(app.pool);
	app.pool = NULL;
	PJ_LOG(3,(THIS_FILE, "Peak memory size: %uMB",
			     app.cp.peak_used_size / 1000000));
	pj_caching_pool_destroy(&app.cp);
    }
}


/*
 * Init media stack.
 */
static pj_status_t init_media()
{
    unsigned	i;
    pj_uint16_t	rtp_port;
    pj_status_t	status;


    /* Initialize media endpoint so that at least error subsystem is properly
     * initialized.
     */
    status = pjmedia_endpt_create(&app.cp.factory, 
				  pjsip_endpt_get_ioqueue(app.sip_endpt), 0, 
				  &app.med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    /* Must register all codecs to be supported */
    pjmedia_codec_g711_init(app.med_endpt);
    pjmedia_codec_gsm_init(app.med_endpt);
    pjmedia_codec_speex_init(app.med_endpt, PJMEDIA_SPEEX_NO_UWB, 3, 3);


    /* Init dummy socket addresses */
    app.skinfo_cnt = 0;
    for (i=0, rtp_port=4000; i<PJ_ARRAY_SIZE(app.skinfo); ++i, rtp_port+=2) {
	pjmedia_sock_info *skinfo;

	skinfo = &app.skinfo[i];
	
	pj_sockaddr_in_init(&skinfo->rtp_addr_name, &app.local_addr,
			    (pj_uint16_t)rtp_port);
	pj_sockaddr_in_init(&skinfo->rtp_addr_name, &app.local_addr,
			    (pj_uint16_t)(rtp_port+1));
	app.skinfo_cnt++;
    }

    /* Generate dummy SDP */
    dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
    status = pjmedia_sdp_parse(app.pool, dummy_sdp_str.ptr, dummy_sdp_str.slen, 
			       &app.dummy_sdp);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error parsing dummy SDP", status);
	return status;
    }


    /* Done */
    return PJ_SUCCESS;
}


/* This is notification from the call about media negotiation
 * status. This is called for client calls only.
 */
static void call_on_media_update( pjsip_inv_session *inv,
				  pj_status_t status)
{
    if (status != PJ_SUCCESS) {
	pjsip_tx_data *tdata;
	pj_status_t status;

	status = pjsip_inv_end_session(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE, 
				       NULL, &tdata);
	if (status == PJ_SUCCESS && tdata)
	    status = pjsip_inv_send_msg(inv, tdata);
    }
}


/* This is notification from the call when the call state has changed.
 * This is called for client calls only.
 */
static void call_on_state_changed( pjsip_inv_session *inv, 
				   pjsip_event *e)
{
    PJ_UNUSED_ARG(e);

    /* Bail out if the session has been counted before */
    if (inv->mod_data[mod_test.id] != NULL)
	return;

    /* Bail out if this is not an outgoing call */
    if (inv->role != PJSIP_UAC_ROLE)
	return;

    if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
	pjsip_tx_data *tdata;
	pj_status_t status;

	//report_completion(200);
	//inv->mod_data[mod_test.id] = (void*)1;

	status = pjsip_inv_end_session(inv, PJSIP_SC_OK, NULL, &tdata);
	if (status == PJ_SUCCESS && tdata)
	    status = pjsip_inv_send_msg(inv, tdata);

    } else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
	report_completion(inv->cause);
	inv->mod_data[mod_test.id] = (void*)1;
    }
}


/* Not implemented for now */
static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
{
    /* Do nothing */
    PJ_UNUSED_ARG(inv);
    PJ_UNUSED_ARG(e);
}


/*
 * Make outgoing call.
 */
static pj_status_t make_call(const pj_str_t *dst_uri)
{
    struct call *call;
    pjsip_dialog *dlg;
    pjmedia_sdp_session *sdp;
    pjsip_tx_data *tdata;
    pj_status_t status;


    /* Create UAC dialog */
    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
				   &app.local_uri,	/* local URI	    */
				   &app.local_contact,	/* local Contact    */
				   dst_uri,		/* remote URI	    */
				   dst_uri,		/* remote target    */
				   &dlg);		/* dialog	    */
    if (status != PJ_SUCCESS) {
	return status;
    }

    /* Create call */
    call = pj_pool_zalloc(dlg->pool, sizeof(struct call));

    /* Create SDP */
    if (app.real_sdp) {
	status = pjmedia_endpt_create_sdp(app.med_endpt, dlg->pool, 1, 
					  app.skinfo, &sdp);
	if (status != PJ_SUCCESS) {
	    pjsip_dlg_terminate(dlg);
	    return status;
	}
    } else
	sdp = app.dummy_sdp;

    /* Create the INVITE session. */
    status = pjsip_inv_create_uac( dlg, sdp, 0, &call->inv);
    if (status != PJ_SUCCESS) {
	pjsip_dlg_terminate(dlg);
	return status;
    }


    /* Create initial INVITE request.
     * This INVITE request will contain a perfectly good request and 
     * an SDP body as well.
     */
    status = pjsip_inv_invite(call->inv, &tdata);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    /* Send initial INVITE request. 
     * From now on, the invite session's state will be reported to us
     * via the invite session callbacks.
     */
    status = pjsip_inv_send_msg(call->inv, tdata);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);


    return PJ_SUCCESS;
}


/*
 * Verify that valid SIP url is given.
 */
static pj_status_t verify_sip_url(const char *c_url)
{
    pjsip_uri *p;
    pj_pool_t *pool;
    char *url;
    int len = (c_url ? pj_ansi_strlen(c_url) : 0);

    if (!len) return -1;

    pool = pj_pool_create(&app.cp.factory, "check%p", 1024, 0, NULL);
    if (!pool) return PJ_ENOMEM;

    url = pj_pool_alloc(pool, len+1);
    pj_ansi_strcpy(url, c_url);
    url[len] = '\0';

    p = pjsip_parse_uri(pool, url, len, 0);
    if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)
	p = NULL;

    pj_pool_release(pool);
    return p ? 0 : -1;
}


static void usage(void)
{
    printf(
	"Usage:\n"
	"   pjsip-perf [OPTIONS]        -- to start as server\n"
	"   pjsip-perf [OPTIONS] URL    -- to call server (possibly itself)\n"
	"\n"
	"where:\n"
	"   URL                     The SIP URL to be contacted.\n"
	"\n"
	"Client options:\n"
	"   --method=METHOD, -m     Set test method (set to INVITE for call benchmark)\n"
        "                           [default: OPTIONS]\n"
	"   --count=N, -n           Set total number of requests to initiate\n"
	"                           [default=%d]\n"
	"   --stateless, -s         Set to operate in stateless mode\n"
	"                           [default: stateful]\n"
	"   --timeout=SEC, -t       Set client timeout [default=60 sec]\n"
	"   --window=COUNT, -w      Set maximum outstanding job [default: %d]\n"
	"\n"
	"SDP options (client and server):\n"
	"   --real-sdp              Generate real SDP from pjmedia, and also perform\n"
	"                           proper SDP negotiation [default: dummy]\n"
	"\n"
	"Client and Server options:\n"
	"   --local-port=PORT, -p   Set local port [default: 5060]\n"
	"   --use-tcp, -T           Use TCP instead of UDP. Note that when started as\n"
	"                           client, you must add ;transport=tcp parameter to URL\n"
	"                           [default: no]\n"
	"   --thread-count=N        Set number of worker threads [default=1]\n"
	"\n"
	"Misc options:\n"
	"   --help, -h              Display this screen\n"
	"   --verbose, -v           Verbose logging (put more than once for even more)\n"
	"\n"
	"When started as server, pjsip-perf can be contacted on the following URIs:\n"
	"   - sip:0@server-addr     To handle requests statelessly.\n"
	"   - sip:1@server-addr     To handle requests statefully.\n"
	"   - sip:2@server-addr     To handle INVITE call.\n",
	DEFAULT_COUNT, JOB_WINDOW);
}


static int my_atoi(const char *s)
{
    pj_str_t ss = pj_str((char*)s);
    return pj_strtoul(&ss);
}


static pj_status_t init_options(int argc, char *argv[])
{
    enum { OPT_THREAD_COUNT = 1, OPT_REAL_SDP };
    struct pj_getopt_option long_options[] = {
	{ "local-port",	    1, 0, 'p' },
	{ "count",	    1, 0, 'c' },
	{ "thread-count",   1, 0, OPT_THREAD_COUNT },
	{ "method",	    1, 0, 'm' },
	{ "help",	    0, 0, 'h' },
	{ "stateless",	    0, 0, 's' },
	{ "timeout",	    1, 0, 't' },
	{ "real-sdp",	    0, 0, OPT_REAL_SDP },
	{ "verbose",        0, 0, 'v' },
	{ "use-tcp",	    0, 0, 'T' },
	{ "window",	    1, 0, 'w' },
	{ NULL, 0, 0, 0 },
    };
    int c;
    int option_index;

    /* Init default application configs */
    app.local_port = 5060;
    app.thread_count = 1;
    app.client.job_count = DEFAULT_COUNT;
    app.client.method = pjsip_options_method;
    app.client.job_window = c = JOB_WINDOW;
    app.client.timeout = 60;
    app.log_level = 3;


    /* Parse options */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "p:c:m:t:w:hsv", 
			    long_options, &option_index))!=-1) 
    {
	switch (c) {
	case 'p':
	    app.local_port = my_atoi(pj_optarg);
	    if (app.local_port < 0 || app.local_port > 65535) {
		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'c':
	    app.client.job_count = my_atoi(pj_optarg);
	    if (app.client.job_count < 0) {
		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
		return -1;
	    }
	    if (app.client.job_count > PJSIP_MAX_TSX_COUNT)
		PJ_LOG(3,(THIS_FILE, 
			  "Warning: --count value (%d) exceeds maximum "
			  "transaction count (%d)", app.client.job_count,
			  PJSIP_MAX_TSX_COUNT));
	    break;

	case OPT_THREAD_COUNT:
	    app.thread_count = my_atoi(pj_optarg);
	    if (app.thread_count < 1 || app.thread_count > 16) {
		PJ_LOG(3,(THIS_FILE, "Invalid --thread-count %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'm':
	    {
		pj_str_t temp = pj_str((char*)pj_optarg);
		pjsip_method_init_np(&app.client.method, &temp);
	    }
	    break;

	case 'h':
	    usage();
	    return -1;

	case 's':
	    app.client.stateless = PJ_TRUE;
	    break;

	case OPT_REAL_SDP:
	    app.real_sdp = 1;
	    break;

	case 'v':
	    app.log_level++;
	    break;

	case 't':
	    app.client.timeout = my_atoi(pj_optarg);
	    if (app.client.timeout < 0 || app.client.timeout > 600) {
		PJ_LOG(3,(THIS_FILE, "Invalid --timeout %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'w':
	    app.client.job_window = my_atoi(pj_optarg);
	    if (app.client.job_window <= 0) {
		PJ_LOG(3,(THIS_FILE, "Invalid --window %s", pj_optarg));
		return -1;
	    }
	    break;

	case 'T':
	    app.use_tcp = PJ_TRUE;
	    break;

	default:
	    PJ_LOG(1,(THIS_FILE, 
		      "Invalid argument. Use --help to see help"));
	    return -1;
	}
    }

    if (pj_optind != argc) {

	if (verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
	    PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
	    return -1;
	}
	app.client.dst_uri = pj_str(argv[pj_optind]);
	
	pj_optind++;

    }

    if (pj_optind != argc) {
	PJ_LOG(1,(THIS_FILE, "Error: unknown options %s", argv[pj_optind]));
	return -1;
    }

    return 0;
}


/* Send one stateless request */
static pj_status_t submit_stateless_job(void)
{
    pjsip_tx_data *tdata;
    pj_status_t status;

    status = pjsip_endpt_create_request(app.sip_endpt, &app.client.method, 
					&app.client.dst_uri, &app.local_uri,
					&app.client.dst_uri, &app.local_contact,
					NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error creating request", status);
	report_completion(701);
	return status;
    }

    status = pjsip_endpt_send_request_stateless(app.sip_endpt, tdata, NULL,
						NULL);
    if (status != PJ_SUCCESS) {
	pjsip_tx_data_dec_ref(tdata);
	app_perror(THIS_FILE, "Error sending stateless request", status);
	report_completion(701);
	return status;
    }

    return PJ_SUCCESS;
}


/* This callback is called when client transaction state has changed */
static void tsx_completion_cb(void *token, pjsip_event *event)
{
    pjsip_transaction *tsx;

    PJ_UNUSED_ARG(token);

    if (event->type != PJSIP_EVENT_TSX_STATE)
	return;

    tsx = event->body.tsx_state.tsx;

    if (tsx->mod_data[mod_test.id] != NULL) {
	/* This transaction has been calculated before */
	return;
    }

    if (tsx->state==PJSIP_TSX_STATE_TERMINATED) {
	report_completion(tsx->status_code);
	tsx->mod_data[mod_test.id] = (void*)1;
    }
    else if (tsx->method.id == PJSIP_INVITE_METHOD &&
	     tsx->state == PJSIP_TSX_STATE_CONFIRMED) {

	report_completion(tsx->status_code);
	tsx->mod_data[mod_test.id] = (void*)1;
	
    } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {

	report_completion(tsx->status_code);
	tsx->mod_data[mod_test.id] = (void*)1;

	TERMINATE_TSX(tsx, tsx->status_code);
    }
}


/* Send one stateful request */
static pj_status_t submit_job(void)
{
    pjsip_tx_data *tdata;
    pj_status_t status;

    status = pjsip_endpt_create_request(app.sip_endpt, &app.client.method, 
					&app.client.dst_uri, &app.local_uri,
					&app.client.dst_uri, &app.local_contact,
					NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error creating request", status);
	report_completion(701);
	return status;
    }

    status = pjsip_endpt_send_request(app.sip_endpt, tdata, -1, NULL, 
				      &tsx_completion_cb);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error sending stateful request", status);
	//should have been reported by tsx_completion_cb().
	//report_completion(701);
	pjsip_tx_data_dec_ref(tdata);
    }
    return status;
}


/* Client worker thread */
static int client_thread(void *arg)
{
    pj_time_val end_time, last_report, now;
    unsigned thread_index = (unsigned)(long)arg;
    unsigned cycle = 0, last_cycle = 0;

    pj_thread_sleep(100);

    pj_gettimeofday(&end_time);
    end_time.sec += app.client.timeout;

    pj_gettimeofday(&last_report);

    if (app.client.first_request.sec == 0) {
	pj_gettimeofday(&app.client.first_request);
    }

    /* Submit all jobs */
    while (app.client.job_submitted < app.client.job_count && !app.thread_quit){
	pj_time_val timeout = { 0, 1 };
	unsigned i;
	int outstanding;
	pj_status_t status;

	/* Calculate current outstanding job */
	outstanding = app.client.job_submitted - app.client.job_finished;

	/* Update stats on max outstanding jobs */
	if (outstanding > (int)app.client.stat_max_window)
	    app.client.stat_max_window = outstanding;

	/* Wait if there are more pending jobs than allowed in the
	 * window. But spawn a new job anyway if no events are happening
	 * after we wait for some time.
	 */
	for (i=0; outstanding > (int)app.client.job_window && i<1000; ++i) {
	    pj_time_val wait = { 0, 500 };
	    unsigned count = 0;

	    pjsip_endpt_handle_events2(app.sip_endpt, &wait, &count);
	    outstanding = app.client.job_submitted - app.client.job_finished;

	    if (count == 0)
		break;

	    ++cycle;
	}


	/* Submit one job */
	if (app.client.method.id == PJSIP_INVITE_METHOD) {
	    status = make_call(&app.client.dst_uri);
	} else if (app.client.stateless) {
	    status = submit_stateless_job();
	} else {
	    status = submit_job();
	}

	++app.client.job_submitted;
	++cycle;

	/* Handle event */
	pjsip_endpt_handle_events2(app.sip_endpt, &timeout, NULL);

	/* Check for time out, also print report */
	if (cycle - last_cycle >= 500) {
	    pj_gettimeofday(&now);
	    if (PJ_TIME_VAL_GTE(now, end_time)) {
		break;
	    }
	    last_cycle = cycle;

	    
	    if (thread_index == 0 && now.sec-last_report.sec >= 2) {
		printf("\r%d jobs started, %d completed...   ",
		       app.client.job_submitted, app.client.job_finished);
		fflush(stdout);
		last_report = now;
	    }
	}
    }

    if (app.client.requests_sent.sec == 0) {
	pj_gettimeofday(&app.client.requests_sent);
    }


    if (thread_index == 0) {
	printf("\r%d jobs started, %d completed%s\n",
	       app.client.job_submitted, app.client.job_finished,
	       (app.client.job_submitted!=app.client.job_finished ? 
		", waiting..." : ".") );
	fflush(stdout);
    }

    /* Wait until all jobs completes, or timed out */
    pj_gettimeofday(&now);
    while (PJ_TIME_VAL_LT(now, end_time) && 
	   app.client.job_finished < app.client.job_count && 
	   !app.thread_quit) 
    {
	pj_time_val timeout = { 0, 1 };
	unsigned i;

	for (i=0; i<1000; ++i) {
	    unsigned count;
	    count = 0;
	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
	    if (count == 0)
		break;
	}

	pj_gettimeofday(&now);
    }

    /* Wait couple of seconds to let jobs completes (e.g. ACKs to be sent)  */
    pj_gettimeofday(&now);
    end_time = now;
    end_time.sec += 2;
    while (PJ_TIME_VAL_LT(now, end_time)) 
    {
	pj_time_val timeout = { 0, 1 };
	unsigned i;

	for (i=0; i<1000; ++i) {
	    unsigned count;
	    count = 0;
	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
	    if (count == 0)
		break;
	}

	pj_gettimeofday(&now);
    }

    return 0;
}


static const char *good_number(char *buf, pj_int32_t val)
{
    if (val < 1000) {
	pj_ansi_sprintf(buf, "%d", val);
    } else if (val < 1000000) {
	pj_ansi_sprintf(buf, "%d.%dK", 
			val / 1000,
			(val % 1000) / 100);
    } else {
	pj_ansi_sprintf(buf, "%d.%02dM", 
			val / 1000000,
			(val % 1000000) / 10000);
    }

    return buf;
}


static int server_thread(void *arg)
{
    pj_time_val timeout = { 0, 1 };
    unsigned thread_index = (unsigned)(long)arg;
    pj_time_val last_report, next_report;

    pj_gettimeofday(&last_report);
    next_report = last_report;
    next_report.sec++;

    while (!app.thread_quit) {
	pj_time_val now;
	unsigned i;

	for (i=0; i<100; ++i) {
	    unsigned count = 0;
	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
	    if (count == 0)
		break;
	}

	if (thread_index == 0) {
	    pj_gettimeofday(&now);

	    if (PJ_TIME_VAL_GTE(now, next_report)) {
		pj_time_val tmp;
		unsigned msec;
		unsigned stateless, stateful, call;
		char str_stateless[32], str_stateful[32], str_call[32];

		tmp = now;
		PJ_TIME_VAL_SUB(tmp, last_report);
		msec = PJ_TIME_VAL_MSEC(tmp);

		last_report = now;
		next_report = last_report;
		next_report.sec++;

		stateless = app.server.cur_state.stateless_cnt - app.server.prev_state.stateless_cnt;
		stateful = app.server.cur_state.stateful_cnt - app.server.prev_state.stateful_cnt;
		call = app.server.cur_state.call_cnt - app.server.prev_state.call_cnt;

		good_number(str_stateless, app.server.cur_state.stateless_cnt);
		good_number(str_stateful, app.server.cur_state.stateful_cnt);
		good_number(str_call, app.server.cur_state.call_cnt);

		printf("Total(rate): stateless:%s (%d/s), statefull:%s (%d/s), call:%s (%d/s)       \r",
		       str_stateless, stateless*1000/msec,
		       str_stateful, stateful*1000/msec,
		       str_call, call*1000/msec);
		fflush(stdout);

		app.server.prev_state = app.server.cur_state;
	    }
	}
    }

    return 0;
}

static void write_report(const char *msg)
{
    puts(msg);

#if defined(PJ_WIN32) && PJ_WIN32!=0
    OutputDebugString(msg);
    OutputDebugString("\n");
#endif
}


int main(int argc, char *argv[])
{
    static char report[1024];

    printf("PJSIP Performance Measurement Tool v%s\n"
           "(c)2006 pjsip.org\n\n",
	   PJ_VERSION);

    if (create_app() != 0)
	return 1;

    if (init_options(argc, argv) != 0)
	return 1;

    if (init_sip() != 0)
	return 1;

    if (init_media() != 0)
	return 1;

    pj_log_set_level(app.log_level);

    if (app.log_level > 4) {
	pjsip_endpt_register_module(app.sip_endpt, &msg_logger);
    }


    /* Misc infos */
    if (app.client.dst_uri.slen != 0) {
	if (app.client.method.id == PJSIP_INVITE_METHOD) {
	    if (app.client.stateless) {
		PJ_LOG(3,(THIS_FILE, 
			  "Info: --stateless option makes no sense for INVITE,"
			  " ignored."));
	    }
	}

    }



    if (app.client.dst_uri.slen) {
	/* Client mode */
	pj_status_t status;
	char test_type[64];
	unsigned msec_req, msec_res;
	unsigned i;

	/* Get the job name */
	if (app.client.method.id == PJSIP_INVITE_METHOD) {
	    pj_ansi_strcpy(test_type, "INVITE calls");
	} else if (app.client.stateless) {
	    pj_ansi_sprintf(test_type, "stateless %.*s requests",
			    (int)app.client.method.name.slen,
			    app.client.method.name.ptr);
	} else {
	    pj_ansi_sprintf(test_type, "stateful %.*s requests",
			    (int)app.client.method.name.slen,
			    app.client.method.name.ptr);
	}
	

	printf("Sending %d %s to '%.*s' with %d maximum outstanding jobs, please wait..\n", 
		  app.client.job_count, test_type,
		  (int)app.client.dst_uri.slen, app.client.dst_uri.ptr,
		  app.client.job_window);

	for (i=0; i<app.thread_count; ++i) {
	    status = pj_thread_create(app.pool, NULL, &client_thread, 
				      (void*)(long)i, 0, 0, &app.thread[i]);
	    if (status != PJ_SUCCESS) {
		app_perror(THIS_FILE, "Unable to create thread", status);
		return 1;
	    }
	}

	for (i=0; i<app.thread_count; ++i) {
	    pj_thread_join(app.thread[i]);
	    app.thread[i] = NULL;
	}

	if (app.client.last_completion.sec) {
	    pj_time_val duration;
	    duration = app.client.last_completion;
	    PJ_TIME_VAL_SUB(duration, app.client.first_request);
	    msec_res = PJ_TIME_VAL_MSEC(duration);
	} else {
	    msec_res = app.client.timeout * 1000;
	}

	if (msec_res == 0) msec_res = 1;

	if (app.client.requests_sent.sec) {
	    pj_time_val duration;
	    duration = app.client.requests_sent;
	    PJ_TIME_VAL_SUB(duration, app.client.first_request);
	    msec_req = PJ_TIME_VAL_MSEC(duration);
	} else {
	    msec_req = app.client.timeout * 1000;
	}

	if (msec_req == 0) msec_req = 1;

	if (app.client.job_submitted < app.client.job_count)
	    puts("\ntimed-out!\n");
	else
	    puts("\ndone.\n");

	pj_ansi_snprintf(
	    report, sizeof(report),
	    "Total %d %s sent in %d ms at rate of %d/sec\n"
	    "Total %d responses receieved in %d ms at rate of %d/sec:",
	    app.client.job_submitted, test_type, msec_req, 
	    app.client.job_submitted * 1000 / msec_req,
	    app.client.total_responses, msec_res,
	    app.client.total_responses*1000/msec_res);
	write_report(report);

	/* Print detailed response code received */
	pj_ansi_sprintf(report, "\nDetailed responses received:");
	write_report(report);

	for (i=0; i<PJ_ARRAY_SIZE(app.client.response_codes); ++i) {
	    const pj_str_t *reason;

	    if (app.client.response_codes[i] == 0)
		continue;

	    reason = pjsip_get_status_text(i);
	    pj_ansi_snprintf( report, sizeof(report),
			      " - %d responses:  %7d     (%.*s)",
			      i, app.client.response_codes[i],
			      (int)reason->slen, reason->ptr);
	    write_report(report);
	}

	/* Total responses and rate */
	pj_ansi_snprintf( report, sizeof(report),
	    "                    ------\n"
	    " TOTAL responses:  %7d (rate=%d/sec)\n",
	    app.client.total_responses, 
	    app.client.total_responses*1000/msec_res);

	write_report(report);

	pj_ansi_sprintf(report, "Maximum outstanding job: %d", 
			app.client.stat_max_window);
	write_report(report);


    } else {
	/* Server mode */
	char s[10];
	pj_status_t status;
	unsigned i;

	puts("pjsip-perf started in server-mode");

	printf("Receiving requests on the following URIs:\n"
	       "  sip:0@%.*s:%d%s    for stateless handling\n"
	       "  sip:1@%.*s:%d%s    for stateful handling\n"
	       "  sip:2@%.*s:%d%s    for call handling\n",
	       (int)app.local_addr.slen,
	       app.local_addr.ptr,
	       app.local_port,
	       (app.use_tcp ? ";transport=tcp" : ""),
	       (int)app.local_addr.slen,
	       app.local_addr.ptr,
	       app.local_port,
	       (app.use_tcp ? ";transport=tcp" : ""),
	       (int)app.local_addr.slen,
	       app.local_addr.ptr,
	       app.local_port,
	       (app.use_tcp ? ";transport=tcp" : ""));
	printf("INVITE with non-matching user part will be handled call-statefully\n");

	for (i=0; i<app.thread_count; ++i) {
	    status = pj_thread_create(app.pool, NULL, &server_thread, 
				      (void*)(long)i, 0, 0, &app.thread[i]);
	    if (status != PJ_SUCCESS) {
		app_perror(THIS_FILE, "Unable to create thread", status);
		return 1;
	    }
	}

	puts("\nPress <ENTER> to quit\n");
	fflush(stdout);
	fgets(s, sizeof(s), stdin);

	app.thread_quit = PJ_TRUE;
	for (i=0; i<app.thread_count; ++i) {
	    pj_thread_join(app.thread[i]);
	    app.thread[i] = NULL;
	}

	puts("");
    }


    destroy_app();

    return 0;
}

