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

/**
 * invtester.c
 *
 * Send INVITE/re-INVITE without SDP.
 */


/* Include all headers. */
#include <pjsip.h>
#include <pjlib-util.h>
#include <pjlib.h>

#define THIS_FILE	"invtester.c"

#define PORT		50060
#define PORT_STR	":50060"
#define SAME_BRANCH	0
#define ACK_HAS_SDP	1

static pjsip_endpoint *sip_endpt;
static pj_bool_t       quit_flag;
static pjsip_dialog   *dlg;


/* Callback to handle incoming requests. */
static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event);

static pjsip_module mod_app =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-app", 7 },		    /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    NULL,			    /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    &on_tsx_state		    /* on_tsx_state()		*/
};


/* Worker thread */
static int worker_thread(void *arg)
{
    PJ_UNUSED_ARG(arg);

    while (!quit_flag) {
	pj_time_val timeout = {0, 500};
	pjsip_endpt_handle_events(sip_endpt, &timeout);
    }

    return 0;
}

/* Send request */
static void send_request(const pjsip_method *method,
			 int cseq,
			 const pj_str_t *branch,
			 pj_bool_t with_offer)
{
    pjsip_tx_data *tdata;
    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 0 101\r\n"
	"a=rtcp:4001 IN IP4 192.168.0.68\r\n"
	"a=rtpmap:0 PCMU/8000\r\n"
	"a=sendrecv\r\n"
	"a=rtpmap:101 telephone-event/8000\r\n"
	"a=fmtp:101 0-15\r\n",
	0
    };
    pj_status_t status;

    status = pjsip_dlg_create_request(dlg, method, cseq, &tdata);
    pj_assert(status == PJ_SUCCESS);

    if (branch) {
	pjsip_via_hdr *via;

	via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
	pj_strdup(tdata->pool, &via->branch_param, branch);
    }

    if (with_offer) {
	pjsip_msg_body *body;
	pj_str_t mime_application = { "application", 11};
	pj_str_t mime_sdp = {"sdp", 3};


	dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
	body = pjsip_msg_body_create(tdata->pool, 
				     &mime_application, &mime_sdp, 
				     &dummy_sdp_str);
	tdata->msg->body = body;
    }

    status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
    pj_assert(status == PJ_SUCCESS);
}

/* Callback to handle incoming requests. */
static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
{
    if (tsx->role == PJSIP_ROLE_UAC) {
	if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->state == PJSIP_TSX_STATE_TERMINATED) {
#if SAME_BRANCH
	    send_request(&pjsip_ack_method, tsx->cseq, &tsx->branch, ACK_HAS_SDP);
#else
	    send_request(&pjsip_ack_method, tsx->cseq, NULL, ACK_HAS_SDP);
#endif
	}

    } else {
	if (event->type == PJSIP_EVENT_RX_MSG && tsx->state == PJSIP_TSX_STATE_TRYING) {
	    pjsip_tx_data *tdata;

	    pjsip_dlg_create_response(dlg, event->body.tsx_state.src.rdata,
				      200, NULL, &tdata);
	    pjsip_dlg_send_response(dlg, tsx, tdata);
	}
    }
}

/* make call */
void make_call(char *uri, pj_bool_t with_offer)
{
    pj_str_t local = pj_str("sip:localhost" PORT_STR);
    pj_str_t remote = pj_str(uri);
    pj_status_t status;

    status = pjsip_dlg_create_uac(pjsip_ua_instance(),
				  &local, &local, &remote, &remote, &dlg);
    pj_assert(status == PJ_SUCCESS);

    pjsip_dlg_inc_lock(dlg);

    status = pjsip_dlg_add_usage(dlg, &mod_app, NULL);
    pj_assert(status == PJ_SUCCESS);

    pjsip_dlg_inc_session(dlg, &mod_app);

    send_request(&pjsip_invite_method, -1, NULL, with_offer);

    pjsip_dlg_dec_lock(dlg);
}

/* reinvite */
void reinvite(pj_bool_t with_offer)
{
    send_request(&pjsip_invite_method, -1, NULL, with_offer);
}

/* hangup call */
void hangup(void)
{
    send_request(&pjsip_bye_method, -1, NULL, PJ_FALSE);
    pjsip_dlg_dec_session(dlg, &mod_app);
}

/*
 * main()
 *
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pj_thread_t *thread;
    pj_pool_t *pool;
    pj_status_t status;
    
    if (argc != 2) {
	puts("Error: destination URL needed");
	return 0;
    }

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


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

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


    /* Create the endpoint: */
    status = pjsip_endpt_create(&cp.factory, "sipstateless", 
				&sip_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 
     * Add UDP transport, with hard-coded port 
     */
    {
	pj_sockaddr_in addr;

	addr.sin_family = PJ_AF_INET;
	addr.sin_addr.s_addr = 0;
	addr.sin_port = pj_htons(PORT);

	status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(3,(THIS_FILE, 
		      "Error starting UDP transport (port in use?)"));
	    return 1;
	}
    }

    status = pjsip_tsx_layer_init_module(sip_endpt);
    pj_assert(status == PJ_SUCCESS);

    status = pjsip_ua_init_module(sip_endpt, NULL);
    pj_assert(status == PJ_SUCCESS);

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

    pool = pjsip_endpt_create_pool(sip_endpt, "", 1000, 1000);

    status = pj_thread_create(pool, "", &worker_thread, NULL, 0, 0, &thread);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    printf("Destination URL: %s\n", argv[1]);

    for (;;) {
	char line[10];

	fgets(line, sizeof(line), stdin);

	switch (line[0]) {
	case 'm':
	    make_call(argv[1], PJ_FALSE);
	    break;
	case 'M':
	    make_call(argv[1], PJ_TRUE);
	    break;
	case 'r':
	    reinvite(PJ_FALSE);
	    break;
	case 'R':
	    reinvite(PJ_TRUE);
	    break;
	case 'h':
	    hangup();
	    break;
	case 'q':
	    goto on_quit;
	}
    }

on_quit:
    quit_flag = 1;
    pj_thread_join(thread);

    pjsip_endpt_destroy(sip_endpt);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();
    return 0;
}

