/* $Id$ */
/* 
 * Copyright (C) 2003-2007 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_ua.h>
#include <pjsip.h>
#include <pjlib.h>

#define THIS_FILE   "regc_test.c"


/************************************************************************/
/* A module to inject error into outgoing sending operation */
static pj_status_t mod_send_on_tx_request(pjsip_tx_data *tdata);

static struct 
{
    pjsip_module mod;
    unsigned	 count;
    unsigned	 count_before_reject;
} send_mod = 
{
    {
	NULL, NULL,			    /* prev, next.		*/
	{ "mod-send", 8 },		    /* Name.			*/
	-1,				    /* Id			*/
	PJSIP_MOD_PRIORITY_TRANSPORT_LAYER,	    /* Priority			*/
	NULL,				    /* load()			*/
	NULL,				    /* start()			*/
	NULL,				    /* stop()			*/
	NULL,				    /* unload()			*/
	NULL,				    /* on_rx_request()		*/
	NULL,				    /* on_rx_response()		*/
	&mod_send_on_tx_request,		    /* on_tx_request.		*/
	NULL,				    /* on_tx_response()		*/
	NULL,				    /* on_tsx_state()		*/
    },
    0,
    0xFFFF
};


static pj_status_t mod_send_on_tx_request(pjsip_tx_data *tdata)
{
    PJ_UNUSED_ARG(tdata);

    if (++send_mod.count > send_mod.count_before_reject)
	return PJ_ECANCELLED;
    else
	return PJ_SUCCESS;
};


/************************************************************************/
/* Registrar for testing */
static pj_bool_t regs_rx_request(pjsip_rx_data *rdata);

enum contact_op
{
    NONE,	/* don't put Contact header	    */
    EXACT,	/* return exact contact		    */
    MODIFIED,	/* return modified Contact header   */
};

struct registrar_cfg
{
    pj_bool_t	    respond;	    /* should it respond at all		*/
    unsigned	    status_code;    /* final response status code	*/
    pj_bool_t	    authenticate;   /* should we authenticate?		*/
    enum contact_op contact_op;	    /* What should we do with Contact   */
    unsigned	    expires_param;  /* non-zero to put in expires param	*/
    unsigned	    expires;	    /* non-zero to put in Expires header*/

    pj_str_t	    more_contacts;  /* Additional Contact headers to put*/
};

static struct registrar
{
    pjsip_module	    mod;
    struct registrar_cfg    cfg;
    unsigned		    response_cnt;
} registrar = 
{
    {
	NULL, NULL,			    /* prev, next.		*/
	{ "registrar", 9 },		    /* Name.			*/
	-1,				    /* Id			*/
	PJSIP_MOD_PRIORITY_APPLICATION,	    /* Priority			*/
	NULL,				    /* load()			*/
	NULL,				    /* start()			*/
	NULL,				    /* stop()			*/
	NULL,				    /* unload()			*/
	&regs_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 regs_rx_request(pjsip_rx_data *rdata)
{
    pjsip_msg *msg = rdata->msg_info.msg;
    pjsip_hdr hdr_list;
    int code;
    pj_status_t status;

    if (msg->line.req.method.id != PJSIP_REGISTER_METHOD)
	return PJ_FALSE;

    if (!registrar.cfg.respond)
	return PJ_TRUE;

    pj_list_init(&hdr_list);

    if (registrar.cfg.authenticate && 
	pjsip_msg_find_hdr(msg, PJSIP_H_AUTHORIZATION, NULL)==NULL) 
    {
	pjsip_generic_string_hdr *hwww;
	const pj_str_t hname = pj_str("WWW-Authenticate");
	const pj_str_t hvalue = pj_str("Digest realm=\"test\"");

	hwww = pjsip_generic_string_hdr_create(rdata->tp_info.pool, &hname, 
					       &hvalue);
	pj_list_push_back(&hdr_list, hwww);

	code = 401;

    } else {
	if (registrar.cfg.contact_op == EXACT ||
	    registrar.cfg.contact_op == MODIFIED) 
	{
	    pjsip_hdr *hsrc;

	    for (hsrc=msg->hdr.next; hsrc!=&msg->hdr; hsrc=hsrc->next) {
		pjsip_contact_hdr *hdst;

		if (hsrc->type != PJSIP_H_CONTACT)
		    continue;

		hdst = (pjsip_contact_hdr*)
		       pjsip_hdr_clone(rdata->tp_info.pool, hsrc);

		if (hdst->expires==0)
		    continue;

		if (registrar.cfg.contact_op == MODIFIED) {
		    if (PJSIP_URI_SCHEME_IS_SIP(hdst->uri) ||
			PJSIP_URI_SCHEME_IS_SIPS(hdst->uri))
		    {
			pjsip_sip_uri *sip_uri = (pjsip_sip_uri*)
						 pjsip_uri_get_uri(hdst->uri);
			sip_uri->host = pj_str("x-modified-host");
			sip_uri->port = 1;
		    }
		}

		if (registrar.cfg.expires_param)
		    hdst->expires = registrar.cfg.expires_param;

		pj_list_push_back(&hdr_list, hdst);
	    }
	}

	if (registrar.cfg.more_contacts.slen) {
	    pjsip_generic_string_hdr *hcontact;
	    const pj_str_t hname = pj_str("Contact");

	    hcontact = pjsip_generic_string_hdr_create(rdata->tp_info.pool, &hname, 
						       &registrar.cfg.more_contacts);
	    pj_list_push_back(&hdr_list, hcontact);
	}

	if (registrar.cfg.expires) {
	    pjsip_expires_hdr *hexp;

	    hexp = pjsip_expires_hdr_create(rdata->tp_info.pool, 
					    registrar.cfg.expires);
	    pj_list_push_back(&hdr_list, hexp);
	}

	registrar.response_cnt++;

	code = registrar.cfg.status_code;
    }

    status = pjsip_endpt_respond(endpt, NULL, rdata, code, NULL,
				 &hdr_list, NULL, NULL);
    pj_assert(status == PJ_SUCCESS);

    return PJ_TRUE;
}


/************************************************************************/
/* Client registration test session */
struct client
{
    /* Result/expected result */
    int		error;
    int		code;
    pj_bool_t	have_reg;
    int		expiration;
    unsigned	contact_cnt;
    pj_bool_t	auth;

    /* Commands */
    pj_bool_t	destroy_on_cb;

    /* Status */
    pj_bool_t	done;

    /* Additional results */
    int		interval;
    int		next_reg;
};

/* regc callback */
static void client_cb(struct pjsip_regc_cbparam *param)
{
    struct client *client = (struct client*) param->token;
    pjsip_regc_info info;
    pj_status_t status;

    client->done = PJ_TRUE;

    status = pjsip_regc_get_info(param->regc, &info);
    pj_assert(status == PJ_SUCCESS);

    client->error = (param->status != PJ_SUCCESS);
    client->code = param->code;

    if (client->error)
	return;

    client->have_reg = info.auto_reg && info.interval>0 &&
		       param->expiration>0;
    client->expiration = param->expiration;
    client->contact_cnt = param->contact_cnt;
    client->interval = info.interval;
    client->next_reg = info.next_reg;

    if (client->destroy_on_cb)
	pjsip_regc_destroy(param->regc);
}


/* Generic client test session */
static struct client client_result;
static int do_test(const char *title,
		   const struct registrar_cfg *srv_cfg, 
		   const struct client *client_cfg,
		   const pj_str_t *registrar_uri,
		   unsigned contact_cnt,
		   const pj_str_t contacts[],
		   unsigned expires,
		   pj_bool_t leave_session,
		   pjsip_regc **p_regc)
{
    pjsip_regc *regc;
    unsigned i;
    const pj_str_t aor = pj_str("<sip:regc-test@pjsip.org>");
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_LOG(3,(THIS_FILE, "  %s", title));

    /* Modify registrar settings */
    pj_memcpy(&registrar.cfg, srv_cfg, sizeof(*srv_cfg));

    pj_bzero(&client_result, sizeof(client_result));
    client_result.destroy_on_cb = client_cfg->destroy_on_cb;

    status = pjsip_regc_create(endpt, &client_result, &client_cb, &regc);
    if (status != PJ_SUCCESS)
	return -100;

    status = pjsip_regc_init(regc, registrar_uri, &aor, &aor, contact_cnt,
			     contacts, expires ? expires : 60);
    if (status != PJ_SUCCESS) {
	pjsip_regc_destroy(regc);
	return -110;
    }

    if (client_cfg->auth) {
	pjsip_cred_info cred;

	pj_bzero(&cred, sizeof(cred));
	cred.realm = pj_str("*");
	cred.scheme = pj_str("digest");
	cred.username = pj_str("user");
	cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
	cred.data = pj_str("password");

	status = pjsip_regc_set_credentials(regc, 1, &cred);
	if (status != PJ_SUCCESS) {
	    pjsip_regc_destroy(regc);
	    return -115;
	}
    }

    /* Register */
    status = pjsip_regc_register(regc, PJ_TRUE, &tdata);
    if (status != PJ_SUCCESS) {
	pjsip_regc_destroy(regc);
	return -120;
    }
    status = pjsip_regc_send(regc, tdata);

    /* That's it, wait until the callback is sent */
    for (i=0; i<600 && !client_result.done; ++i) {
	flush_events(100);
    }

    if (!client_result.done) {
	PJ_LOG(3,(THIS_FILE, "    error: test has timed out"));
	pjsip_regc_destroy(regc);
	return -200;
    }

    /* Destroy the regc, we're done with the test, unless we're
     * instructed to leave the session open.
     */
    if (!leave_session && !client_cfg->destroy_on_cb)
	pjsip_regc_destroy(regc);

    /* Compare results with expected results */

    if (client_result.error != client_cfg->error) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting err=%d, got err=%d",
		  client_cfg->error, client_result.error));
	return -210;
    }
    if (client_result.code != client_cfg->code) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting code=%d, got code=%d",
		  client_cfg->code, client_result.code));
	return -220;
    }
    if (client_result.expiration != client_cfg->expiration) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting expiration=%d, got expiration=%d",
		  client_cfg->expiration, client_result.expiration));
	return -240;
    }
    if (client_result.contact_cnt != client_cfg->contact_cnt) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting contact_cnt=%d, got contact_cnt=%d",
		  client_cfg->contact_cnt, client_result.contact_cnt));
	return -250;
    }
    if (client_result.have_reg != client_cfg->have_reg) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting have_reg=%d, got have_reg=%d",
		  client_cfg->have_reg, client_result.have_reg));
	return -260;
    }
    if (client_result.interval != client_result.expiration) {
	PJ_LOG(3,(THIS_FILE, "    error: interval (%d) is different than expiration (%d)",
		  client_result.interval, client_result.expiration));
	return -270;
    }
    if (client_result.expiration > 0 && client_result.next_reg < 1) {
	PJ_LOG(3,(THIS_FILE, "    error: next_reg=%d, expecting positive number because expiration is %d",
		  client_result.next_reg, client_result.expiration));
	return -280;
    }

    /* Looks like everything is okay. */
    if (leave_session) {
	*p_regc = regc;
    }

    return 0;
}


/************************************************************************/
/* Customized tests */

/* Check that client is sending register refresh */
static int keep_alive_test(const pj_str_t *registrar_uri)
{
    enum { TIMEOUT = 40 };
    struct registrar_cfg server_cfg = 
	/* respond	code	auth	  contact  exp_prm expires more_contacts */
	{ PJ_TRUE,	200,	PJ_FALSE, EXACT,   TIMEOUT, 0,	    {NULL, 0}};
    struct client client_cfg = 
	/* error	code	have_reg    expiration	contact_cnt auth?    destroy*/
	{ PJ_FALSE,	200,	PJ_TRUE,   TIMEOUT,	1,	    PJ_FALSE,PJ_FALSE};
    pj_str_t contact = pj_str("<sip:c@C>");


    pjsip_regc *regc;
    unsigned i;
    int ret;

    ret = do_test("register refresh (takes ~40 secs)", &server_cfg, &client_cfg, registrar_uri,
		  1, &contact, TIMEOUT, PJ_TRUE, &regc);
    if (ret != 0)
	return ret;

    /* Reset server response_cnt */
    registrar.response_cnt = 0;

    /* Wait until keep-alive/refresh is done */
    for (i=0; i<(TIMEOUT-1)*10 && registrar.response_cnt==0; ++i) {
	flush_events(100);
    }

    if (registrar.response_cnt==0) {
	PJ_LOG(3,(THIS_FILE, "    error: no refresh is received"));
	return -400;
    }

    if (client_result.error) {
	PJ_LOG(3,(THIS_FILE, "    error: got error"));
	return -410;
    }
    if (client_result.code != 200) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting code=%d, got code=%d",
		  200, client_result.code));
	return -420;
    }
    if (client_result.expiration != TIMEOUT) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting expiration=%d, got expiration=%d",
		  TIMEOUT, client_result.expiration));
	return -440;
    }
    if (client_result.contact_cnt != 1) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting contact_cnt=%d, got contact_cnt=%d",
		  TIMEOUT, client_result.contact_cnt));
	return -450;
    }
    if (client_result.have_reg == 0) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting have_reg=%d, got have_reg=%d",
		  1, client_result.have_reg));
	return -460;
    }
    if (client_result.interval != TIMEOUT) {
	PJ_LOG(3,(THIS_FILE, "    error: interval (%d) is different than expiration (%d)",
		  client_result.interval, TIMEOUT));
	return -470;
    }
    if (client_result.expiration > 0 && client_result.next_reg < 1) {
	PJ_LOG(3,(THIS_FILE, "    error: next_reg=%d, expecting positive number because expiration is %d",
		  client_result.next_reg, client_result.expiration));
	return -480;
    }

    /* Success */
    pjsip_regc_destroy(regc);
    return 0;
}


/* Send error on refresh */
static int refresh_error(const pj_str_t *registrar_uri,
			 pj_bool_t destroy_on_cb)
{
    enum { TIMEOUT = 40 };
    struct registrar_cfg server_cfg = 
	/* respond	code	auth	  contact  exp_prm expires more_contacts */
	{ PJ_TRUE,	200,	PJ_FALSE, EXACT,   TIMEOUT, 0,	    {NULL, 0}};
    struct client client_cfg = 
	/* error	code	have_reg    expiration	contact_cnt auth?    destroy*/
	{ PJ_FALSE,	200,	PJ_TRUE,   TIMEOUT,	1,	    PJ_FALSE,PJ_FALSE};
    pj_str_t contact = pj_str("<sip:c@C>");

    pjsip_regc *regc;
    unsigned i;
    int ret;

    ret = do_test("refresh error (takes ~40 secs)", &server_cfg, &client_cfg, registrar_uri,
		  1, &contact, TIMEOUT, PJ_TRUE, &regc);
    if (ret != 0)
	return ret;

    /* Reset server response_cnt */
    registrar.response_cnt = 0;

    /* inject error for transmission */
    send_mod.count = 0;
    send_mod.count_before_reject = 0;

    /* reconfigure client */
    client_result.done = PJ_FALSE;
    client_result.destroy_on_cb = destroy_on_cb;

    /* Wait until keep-alive/refresh is done */
    for (i=0; i<TIMEOUT*10 && !client_result.done; ++i) {
	flush_events(100);
    }

    send_mod.count_before_reject = 0xFFFF;

    if (!destroy_on_cb)
	pjsip_regc_destroy(regc);

    if (!client_result.done) {
	PJ_LOG(3,(THIS_FILE, "    error: test has timed out"));
	return -500;
    }

    /* Expecting error */
    if (client_result.error==PJ_FALSE && client_result.code/100==2) {
	PJ_LOG(3,(THIS_FILE, "    error: expecting error got successfull result"));
	return -510;
    }

    return PJ_SUCCESS;
};


/* Send error on refresh */
static int update_test(const pj_str_t *registrar_uri)
{
    enum { TIMEOUT = 40 };
    struct registrar_cfg server_cfg = 
	/* respond	code	auth	  contact  exp_prm expires more_contacts */
	{ PJ_TRUE,	200,	PJ_FALSE, EXACT,   TIMEOUT, 0,	    {NULL, 0}};
    struct client client_cfg = 
	/* error	code	have_reg    expiration	contact_cnt auth?    destroy*/
	{ PJ_FALSE,	200,	PJ_TRUE,   TIMEOUT,	1,	    PJ_FALSE,PJ_FALSE};
    pj_str_t contacts[] = {
	{ "<sip:a>", 7 },
	{ "<sip:b>", 7 },
	{ "<sip:c>", 7 }
    };

    pjsip_regc *regc;
    pjsip_contact_hdr *h1, *h2;
    pjsip_sip_uri *u1, *u2;
    unsigned i;
    pj_status_t status;
    pjsip_tx_data *tdata = NULL;
    int ret = 0;

    /* initially only has 1 contact */
    ret = do_test("update test", &server_cfg, &client_cfg, registrar_uri,
		  1, &contacts[0], TIMEOUT, PJ_TRUE, &regc);
    if (ret != 0) {
	return -600;
    }

    /*****
     * replace the contact with new one 
     */
    PJ_LOG(3,(THIS_FILE, "   replacing contact"));
    status = pjsip_regc_update_contact(regc, 1, &contacts[1]);
    if (status != PJ_SUCCESS) {
	ret = -610;
	goto on_return;
    }

    status = pjsip_regc_register(regc, PJ_TRUE, &tdata);
    if (status != PJ_SUCCESS) {
	ret = -620;
	goto on_return;
    }

    /* Check that the REGISTER contains two Contacts:
     *  - <sip:a>;expires=0,
     *  - <sip:b>
     */
    h1 = (pjsip_contact_hdr*) 
	  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
    if (!h1) {
	ret = -630;
	goto on_return;
    }
    if (h1->next == (pjsip_contact_hdr*)&tdata->msg->hdr)
	h2 = NULL;
    else
	h2 = (pjsip_contact_hdr*) 
	      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, h1->next);
    if (!h2) {
	ret = -640;
	goto on_return;
    }
    /* must not have other Contact header */
    if (h2->next != (pjsip_contact_hdr*)&tdata->msg->hdr &&
	pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, h2->next) != NULL)
    {
	ret = -645;
	goto on_return;
    }

    u1 = (pjsip_sip_uri*) pjsip_uri_get_uri(h1->uri);
    u2 = (pjsip_sip_uri*) pjsip_uri_get_uri(h2->uri);

    if (*u1->host.ptr == 'a') {
	if (h1->expires != 0) {
	    ret = -650;
	    goto on_return;
	}
	if (h2->expires == 0) {
	    ret = -660;
	    goto on_return;
	}

    } else {
	pj_assert(*u1->host.ptr == 'b');
	if (h1->expires == 0) {
	    ret = -670;
	    goto on_return;
	}
	if (h2->expires != 0) {
	    ret = -680;
	    goto on_return;
	}
    }

    /* Destroy tdata */
    pjsip_tx_data_dec_ref(tdata);
    tdata = NULL;



    /** 
     * First loop, it will update with more contacts. Second loop
     * should do nothing.
     */
    for (i=0; i<2; ++i) {
	if (i==0)
	    PJ_LOG(3,(THIS_FILE, "   replacing with more contacts"));
	else
	    PJ_LOG(3,(THIS_FILE, "   updating contacts with same contacts"));

	status = pjsip_regc_update_contact(regc, 2, &contacts[1]);
	if (status != PJ_SUCCESS) {
	    ret = -710;
	    goto on_return;
	}

	status = pjsip_regc_register(regc, PJ_TRUE, &tdata);
	if (status != PJ_SUCCESS) {
	    ret = -720;
	    goto on_return;
	}

	/* Check that the REGISTER contains two Contacts:
	 *  - <sip:b>
	 *  - <sip:c>
	 */
	h1 = (pjsip_contact_hdr*) 
	      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
	if (!h1) {
	    ret = -730;
	    goto on_return;
	}
	if (h1->next == (pjsip_contact_hdr*)&tdata->msg->hdr)
	    h2 = NULL;
	else
	    h2 = (pjsip_contact_hdr*) 
		  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, h1->next);
	if (!h2) {
	    ret = -740;
	    goto on_return;
	}
	/* must not have other Contact header */
	if (h2->next != (pjsip_contact_hdr*)&tdata->msg->hdr &&
	    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, h2->next) != NULL)
	{
	    ret = -745;
	    goto on_return;
	}

	/* both contacts must not have expires=0 parameter */
	if (h1->expires == 0) {
	    ret = -750;
	    goto on_return;
	}
	if (h2->expires == 0) {
	    ret = -760;
	    goto on_return;
	}

	/* Destroy tdata */
	pjsip_tx_data_dec_ref(tdata);
	tdata = NULL;
    }

on_return:
    if (tdata) pjsip_tx_data_dec_ref(tdata);
    pjsip_regc_destroy(regc);
    return ret;
};


/* send error on authentication */
static int auth_send_error(const pj_str_t *registrar_uri,
			   pj_bool_t destroy_on_cb)
{
    enum { TIMEOUT = 40 };
    struct registrar_cfg server_cfg = 
	/* respond	code	auth	  contact  exp_prm expires more_contacts */
	{ PJ_TRUE,	200,	PJ_TRUE,  EXACT,   75,	    0,	    {NULL, 0}};
    struct client client_cfg = 
	/* error	code	have_reg    expiration	contact_cnt auth?    destroy*/
	{ PJ_TRUE,	401,	PJ_FALSE, -1,		0,	    PJ_TRUE, PJ_TRUE};
    pj_str_t contact = pj_str("<sip:c@C>");

    pjsip_regc *regc;
    int ret;

    client_cfg.destroy_on_cb = destroy_on_cb;

    /* inject error for second request retry */
    send_mod.count = 0;
    send_mod.count_before_reject = 1;

    ret = do_test("auth send error", &server_cfg, &client_cfg, registrar_uri,
		  1, &contact, TIMEOUT, PJ_TRUE, &regc);

    send_mod.count_before_reject = 0xFFFF;

    return ret;
};




/************************************************************************/
enum
{
    OFF	    = 1,
    ON	    = 2,
    ON_OFF  = 3,
};

int regc_test(void)
{
    struct test_rec {
	unsigned		 check_contact;
	unsigned		 add_xuid_param;

	const char		*title;
	char			*alt_registrar;
	unsigned		 contact_cnt;
	char			*contacts[4];
	unsigned		 expires;
	struct registrar_cfg	 server_cfg;
	struct client		 client_cfg;
    } test_rec[] = 
    {
	/* immediate error */
	{
	    OFF,			    /* check_contact	*/
	    OFF,			    /* add_xuid_param	*/
	    "immediate error",		    /* title		*/
	    "sip:unresolved-host-xyy",	    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "sip:user@127.0.0.1:5060" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_FALSE,	200,	PJ_FALSE, NONE,	    0,	    0,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	503,	PJ_FALSE,   -1,		0,	    PJ_FALSE}
	},

	/* timeout test */
	{
	    OFF,			    /* check_contact	*/
	    OFF,			    /* add_xuid_param	*/
	    "timeout test (takes ~32 secs)",/* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "sip:user@127.0.0.1:5060" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_FALSE,	200,	PJ_FALSE, NONE,	    0,	    0,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth? */
	    { PJ_FALSE,	408,	PJ_FALSE,   -1,		0,	    PJ_FALSE}
	},

	/* Basic successful registration scenario:
	 * a good registrar returns the Contact header as is and
	 * add expires parameter. In this test no additional bindings
	 * are returned.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "basic",			    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060;transport=udp;x-param=1234>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact  exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, EXACT,    75,	    65,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   75,		1,	    PJ_FALSE}
	},

	/* Basic successful registration scenario with authentication
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "authentication",		    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060;transport=udp;x-param=1234>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact  exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_TRUE,  EXACT,    75,	    65,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   75,		1,	    PJ_TRUE}
	},

	/* a good registrar returns the Contact header as is and
	 * add expires parameter. Also it adds bindings from other
	 * clients in this test.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON,				    /* add_xuid_param	*/
	    "more bindings in response",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060;transport=udp>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact  exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, EXACT,    75,	    65,	    {"<sip:a@a>;expires=70", 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   75,		2,	    PJ_FALSE}
	},


	/* a bad registrar returns modified Contact header, but it
	 * still returns all parameters intact. In this case
	 * the expiration is taken from the expires param because
	 * of matching xuid param or because the number of
	 * Contact header matches.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "registrar modifies Contact header",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, MODIFIED, 75,	    65,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   75,		1,	    PJ_FALSE}
	},


	/* a bad registrar returns modified Contact header, but it
	 * still returns all parameters intact. In addition it returns
	 * bindings from other clients.
	 *
	 * In this case the expiration is taken from the expires param 
	 * because add_xuid_param is enabled.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON,				    /* add_xuid_param	*/
	    "registrar modifies Contact header and add bindings",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, MODIFIED, 75,	    65,	    {"<sip:a@a>;expires=70", 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   75,		2,	    PJ_FALSE}
	},


	/* a bad registrar returns completely different Contact and
	 * all parameters are gone. In this case the expiration is 
	 * also taken from the expires param since the number of 
	 * header matches.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "registrar replaces Contact header",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	202,	PJ_FALSE, NONE,	    0,	    65,	    {"<sip:a@A>;expires=75", 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	202,	PJ_TRUE,   75,		1,	    PJ_FALSE}
	},


	/* a bad registrar returns completely different Contact (and
	 * all parameters are gone) and it also includes bindings from
	 * other clients.
	 * In this case the expiration is taken from the Expires header.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    " as above with additional bindings",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, NONE,	    0,	    65,	    {"<sip:a@A>;expires=75, <sip:b@B;expires=70>", 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   65,		2,	    PJ_FALSE}
	},

	/* the registrar doesn't return any bindings, but for some
	 * reason it includes an Expires header.
	 * In this case the expiration is taken from the Expires header.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "no Contact but with Expires",  /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },  /* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, NONE,	    0,	    65,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   65,		0,	    PJ_FALSE}
	},

	/* Neither Contact header nor Expires header are present.
	 * In this case the expiration is taken from the request.
	 */
	{
	    ON_OFF,			    /* check_contact	*/
	    ON_OFF,			    /* add_xuid_param	*/
	    "no Contact and no Expires",    /* title		*/
	    NULL,			    /* alt_registrar	*/
	    1,				    /* contact cnt	*/
	    { "<sip:user@127.0.0.1:5060>" },/* contacts[]	*/
	    600,			    /* expires		*/

	    /* registrar config: */
	    /* respond	code	auth	  contact   exp_prm expires more_contacts */
	    { PJ_TRUE,	200,	PJ_FALSE, NONE,	    0,	    0,	    {NULL, 0}},

	    /* client expected results: */
	    /* error	code	have_reg    expiration	contact_cnt auth?*/
	    { PJ_FALSE,	200,	PJ_TRUE,   600,		0,	    PJ_FALSE}
	},
    };

    unsigned i;
    pj_sockaddr_in addr;
    pjsip_transport *udp = NULL;
    pj_uint16_t port; 
    char registrar_uri_buf[80];
    pj_str_t registrar_uri;
    int rc = 0;

    pj_sockaddr_in_init(&addr, 0, 0);

    /* Acquire existing transport, if any */
    rc = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP, &addr, sizeof(addr), NULL, &udp);
    if (rc == PJ_SUCCESS) {
	port = pj_sockaddr_get_port(&udp->local_addr);
	pjsip_transport_dec_ref(udp);
	udp = NULL;
    } else {
	rc = pjsip_udp_transport_start(endpt, NULL, NULL, 1, &udp);
	if (rc != PJ_SUCCESS) {
	    app_perror("   error creating UDP transport", rc);
	    rc = -2;
	    goto on_return;
	}

	port = pj_sockaddr_get_port(&udp->local_addr);
    }

    /* Register registrar module */
    rc = pjsip_endpt_register_module(endpt, &registrar.mod);
    if (rc != PJ_SUCCESS) {
	app_perror("   error registering module", rc);
	rc = -3;
	goto on_return;
    }

    /* Register send module */
    rc = pjsip_endpt_register_module(endpt, &send_mod.mod);
    if (rc != PJ_SUCCESS) {
	app_perror("   error registering module", rc);
	rc = -3;
	goto on_return;
    }

    pj_ansi_snprintf(registrar_uri_buf, sizeof(registrar_uri_buf),
		    "sip:127.0.0.1:%d", (int)port);
    registrar_uri = pj_str(registrar_uri_buf);

    for (i=0; i<PJ_ARRAY_SIZE(test_rec); ++i) {
	struct test_rec *t = &test_rec[i];
	unsigned j, x;
	pj_str_t reg_uri;
	pj_str_t contacts[8];

	/* Fill in the registrar address if it's not specified */
	if (t->alt_registrar == NULL) {
	    reg_uri = registrar_uri;
	} else {
	    reg_uri = pj_str(t->alt_registrar);
	}

	/* Build contact pj_str_t's */
	for (j=0; j<t->contact_cnt; ++j) {
	    contacts[j] = pj_str(t->contacts[j]);
	}

	/* Normalize more_contacts field */
	if (t->server_cfg.more_contacts.ptr)
	    t->server_cfg.more_contacts.slen = strlen(t->server_cfg.more_contacts.ptr);

	/* Do tests with three combinations:
	 *  - check_contact on/off
	 *  - add_xuid_param on/off
	 *  - destroy_on_callback on/off
	 */
	for (x=1; x<=2; ++x) {
	    unsigned y;

	    if ((t->check_contact & x) == 0)
		continue;

	    pjsip_cfg()->regc.check_contact = (x-1);

	    for (y=1; y<=2; ++y) {
		unsigned z;

		if ((t->add_xuid_param & y) == 0)
		    continue;

		pjsip_cfg()->regc.add_xuid_param = (y-1);

		for (z=0; z<=1; ++z) {
		    char new_title[200];

		    t->client_cfg.destroy_on_cb = z;

		    sprintf(new_title, "%s [check=%d, xuid=%d, destroy=%d]", 
			    t->title, pjsip_cfg()->regc.check_contact,
			    pjsip_cfg()->regc.add_xuid_param, z);
		    rc = do_test(new_title, &t->server_cfg, &t->client_cfg, 
				 &reg_uri, t->contact_cnt, contacts, 
				 t->expires, PJ_FALSE, NULL);
		    if (rc != 0)
			goto on_return;
		}

	    }
	}

	/* Sleep between test groups to avoid using up too many
	 * active transactions.
	 */
	pj_thread_sleep(1000);
    }

    /* keep-alive test */
    rc = keep_alive_test(&registrar_uri);
    if (rc != 0)
	goto on_return;

    /* Send error on refresh without destroy on callback */
    rc = refresh_error(&registrar_uri, PJ_FALSE);
    if (rc != 0)
	goto on_return;

    /* Send error on refresh, destroy on callback */
    rc = refresh_error(&registrar_uri, PJ_TRUE);
    if (rc != 0)
	goto on_return;

    /* Updating contact */
    rc = update_test(&registrar_uri);
    if (rc != 0)
	goto on_return;

    /* Send error during auth, don't destroy on callback */
    rc = auth_send_error(&registrar_uri, PJ_FALSE);
    if (rc != 0)
	goto on_return;

    /* Send error during auth, destroy on callback */
    rc = auth_send_error(&registrar_uri, PJ_FALSE);
    if (rc != 0)
	goto on_return;

on_return:
    if (registrar.mod.id != -1) {
	pjsip_endpt_unregister_module(endpt, &registrar.mod);
    }
    if (send_mod.mod.id != -1) {
	pjsip_endpt_unregister_module(endpt, &send_mod.mod);
    }
    if (udp) {
	pjsip_transport_dec_ref(udp);
    }
    return rc;
}


