/* $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	    DEFAULT_COUNT
#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;
    pj_bool_t		 verbose;

    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	     last_completion;
	unsigned	     total_responses;
	unsigned	     status_class[7];
    } 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;

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

    /* Only want to handle INVITE requests (for now). */
    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
	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;
}




/*****************************************************************************
 * 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(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
			 "%.*s\n"
			 "--end msg--",
			 rdata->msg_info.len,
			 pjsip_rx_data_get_info(rdata),
			 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(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
			 "%.*s\n"
			 "--end msg--",
			 (tdata->buf.cur - tdata->buf.start),
			 pjsip_tx_data_get_info(tdata),
			 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++;
    app.client.status_class[status_code/100]++;
    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 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 URL to be contacted\n"
	"\n"
	"and OPTIONS are:\n"
	"   --count=N, -n           Set number of requests to initiate\n"
	"                           (client only, default=%d)\n"
	"   --method=METHOD, -m     Set the test method (default: OPTIONS)\n"
	"   --local-port=PORT, -p   Set local port [default: 5060]\n"
	"   --use-tcp, -T           Use TCP instead of UDP (default: no)\n"
	"   --thread-count=N        Set number of worker threads (default=1)\n"
	"   --stateless, -s         Set client to operate in stateless mode\n"
	"                           (default: stateful)\n"
	"   --window=COUNT, -w      Set maximum outstanding job in client (default: %d)\n"
	"   --real-sdp              Generate real SDP from pjmedia, and also perform\n"
	"                           proper SDP negotiation (default: dummy)\n"
	"   --timeout=SEC, -t       Set client timeout (default=60 sec)\n"
	"   --help, -h              Display this screen\n"
	"   --verbose, -v           Display verbose logging\n"
	"\n"
	"When started as server, pjsip-perf can be contacted on the following URIs:\n"
	"   - sip:0@server-addr     To handle requests statelessly (non-INVITE only)\n"
	"   - sip:1@server-addr     To handle requests statefully (INVITE and non-INVITE)\n"
	"   - sip:2@server-addr     To handle INVITE call (INVITE only)\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;


    /* 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.verbose = PJ_TRUE;
	    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)
{
    unsigned last_timeout_check = 0;
    pj_time_val end_time, now;

    PJ_UNUSED_ARG(arg);

    pj_thread_sleep(100);

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

    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, 0 };
	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.
	 */
	for (i=0; outstanding > (int)app.client.job_window && i<100; ++i) {
	    pjsip_endpt_handle_events(app.sip_endpt, &timeout);
	    outstanding = app.client.job_submitted - app.client.job_finished;
	}


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

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

	/* Check for time out */
	if (app.client.job_submitted - last_timeout_check >= 2000) {
	    pj_gettimeofday(&now);
	    if (PJ_TIME_VAL_GTE(now, end_time))
		break;
	    last_timeout_check = app.client.job_submitted;
	}
    }

    /* Wait until all jobs completes, or timed out */
    do {
	pj_time_val timeout = { 0, 0 };
	unsigned i;

	for (i=0; i<2000; ++i) {
	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, NULL);
	}

	pj_gettimeofday(&now);

    } while (now.sec < end_time.sec && 
	     app.client.job_finished < app.client.job_count && 
	     !app.thread_quit);

    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, 0 };
    unsigned thread_index = (unsigned)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];

    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;

    if (app.verbose) {
	pj_log_set_level(4);
	pjsip_endpt_register_module(app.sip_endpt, &msg_logger);
    } else {
        pj_log_set_level(3);
    }


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

    if (app.real_sdp) {
	PJ_LOG(3,(THIS_FILE, 
                  "Info: client/server using real SDP from PJMEDIA"));
    } else {
	PJ_LOG(3,(THIS_FILE, "Info: client/server using dummy SDP"));
    }


    if (app.client.dst_uri.slen) {
	/* Client mode */
	pj_status_t status;
	char test_type[64];
	unsigned msec;
	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);
	}
	

	PJ_LOG(3,(THIS_FILE, "Sending %d %s to %.*s, please wait..", 
		  app.client.job_count, test_type,
		  (int)app.client.dst_uri.slen, app.client.dst_uri.ptr));

	for (i=0; i<app.thread_count; ++i) {
	    status = pj_thread_create(app.pool, NULL, &client_thread, NULL,
				      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 = PJ_TIME_VAL_MSEC(duration);
	} else {
	    msec = app.client.timeout * 1000;
	}

	if (msec == 0) msec = 1;

	pj_ansi_snprintf(
	    report, sizeof(report),
	    "Total %d %s sent, %d responses received in %d ms:\n"
	    " - 2xx responses:  %7d (rate=%d/sec)\n"
	    " - 3xx responses:  %7d (rate=%d/sec)\n"
	    " - 4xx responses:  %7d (rate=%d/sec)\n"
	    " - 5xx responses:  %7d (rate=%d/sec)\n"
	    " - 6xx responses:  %7d (rate=%d/sec)\n"
	    " - 7xx responses:  %7d (rate=%d/sec)\n"
	    "                       ----------------\n"
	    " TOTAL responses:  %7d (rate=%d/sec)\n",
	    app.client.job_submitted, test_type,
	    app.client.total_responses, msec,
	    app.client.status_class[2], app.client.status_class[2]*1000/msec,
	    app.client.status_class[3], app.client.status_class[3]*1000/msec,
	    app.client.status_class[4], app.client.status_class[4]*1000/msec,
	    app.client.status_class[5], app.client.status_class[5]*1000/msec,
	    app.client.status_class[6], app.client.status_class[6]*1000/msec,
	    app.client.status_class[7], app.client.status_class[7]*1000/msec,
	    app.client.total_responses, app.client.total_responses*1000/msec);

	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("");
	puts("pjsip-perf started in server-mode");

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

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

	puts("Press <ENTER> to quit");
	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;
	}
    }


    destroy_app();

    return 0;
}

