/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjmedia/transport_loop.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/ioqueue.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>


struct user
{
    pj_bool_t		rx_disabled;	/**< Doesn't want to receive pkt?   */
    void	       *user_data;	/**< Only valid when attached	    */
    void  (*rtp_cb)(	void*,		/**< To report incoming RTP.	    */
			void*,
			pj_ssize_t);
    void  (*rtcp_cb)(	void*,		/**< To report incoming RTCP.	    */
			void*,
			pj_ssize_t);
};

struct transport_loop
{
    pjmedia_transport	base;		/**< Base transport.		    */

    pj_pool_t	       *pool;		/**< Memory pool		    */
    unsigned		user_cnt;	/**< Number of attachments	    */
    struct user		users[4];	/**< Array of users.		    */

    unsigned		tx_drop_pct;	/**< Percent of tx pkts to drop.    */
    unsigned		rx_drop_pct;	/**< Percent of rx pkts to drop.    */

};



/*
 * These are media transport operations.
 */
static pj_status_t transport_get_info (pjmedia_transport *tp,
				       pjmedia_transport_info *info);
static pj_status_t transport_attach   (pjmedia_transport *tp,
				       void *user_data,
				       const pj_sockaddr_t *rem_addr,
				       const pj_sockaddr_t *rem_rtcp,
				       unsigned addr_len,
				       void (*rtp_cb)(void*,
						      void*,
						      pj_ssize_t),
				       void (*rtcp_cb)(void*,
						       void*,
						       pj_ssize_t));
static void	   transport_detach   (pjmedia_transport *tp,
				       void *strm);
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
				       const pj_sockaddr_t *addr,
				       unsigned addr_len,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_media_create(pjmedia_transport *tp,
				       pj_pool_t *pool,
				       unsigned options,
				       const pjmedia_sdp_session *sdp_remote,
				       unsigned media_index);
static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
				        pj_pool_t *pool,
				        pjmedia_sdp_session *sdp_local,
				        const pjmedia_sdp_session *rem_sdp,
				        unsigned media_index);
static pj_status_t transport_media_start (pjmedia_transport *tp,
				       pj_pool_t *pool,
				       const pjmedia_sdp_session *sdp_local,
				       const pjmedia_sdp_session *sdp_remote,
				       unsigned media_index);
static pj_status_t transport_media_stop(pjmedia_transport *tp);
static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
				       pjmedia_dir dir,
				       unsigned pct_lost);
static pj_status_t transport_destroy  (pjmedia_transport *tp);


static pjmedia_transport_op transport_udp_op = 
{
    &transport_get_info,
    &transport_attach,
    &transport_detach,
    &transport_send_rtp,
    &transport_send_rtcp,
    &transport_send_rtcp2,
    &transport_media_create,
    &transport_encode_sdp,
    &transport_media_start,
    &transport_media_stop,
    &transport_simulate_lost,
    &transport_destroy
};


/**
 * Create loopback transport.
 */
PJ_DEF(pj_status_t) pjmedia_transport_loop_create(pjmedia_endpt *endpt,
						  pjmedia_transport **p_tp)
{
    struct transport_loop *tp;
    pj_pool_t *pool;

    /* Sanity check */
    PJ_ASSERT_RETURN(endpt && p_tp, PJ_EINVAL);

    /* Create transport structure */
    pool = pjmedia_endpt_create_pool(endpt, "tploop", 512, 512);
    if (!pool)
	return PJ_ENOMEM;

    tp = PJ_POOL_ZALLOC_T(pool, struct transport_loop);
    tp->pool = pool;
    pj_ansi_strncpy(tp->base.name, tp->pool->obj_name, PJ_MAX_OBJ_NAME-1);
    tp->base.op = &transport_udp_op;
    tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;

    /* Done */
    *p_tp = &tp->base;
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_transport_loop_disable_rx( pjmedia_transport *tp,
						       void *user,
						       pj_bool_t disabled)
{
    struct transport_loop *loop = (struct transport_loop*) tp;
    unsigned i;

    for (i=0; i<loop->user_cnt; ++i) {
	if (loop->users[i].user_data == user) {
	    loop->users[i].rx_disabled = disabled;
	    return PJ_SUCCESS;
	}
    }
    pj_assert(!"Invalid stream user");
    return PJ_ENOTFOUND;
}

/**
 * Close loopback transport.
 */
static pj_status_t transport_destroy(pjmedia_transport *tp)
{
    struct transport_loop *loop = (struct transport_loop*) tp;

    /* Sanity check */
    PJ_ASSERT_RETURN(tp, PJ_EINVAL);

    pj_pool_release(loop->pool);

    return PJ_SUCCESS;
}


/* Called to get the transport info */
static pj_status_t transport_get_info(pjmedia_transport *tp,
				      pjmedia_transport_info *info)
{
    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);

    info->sock_info.rtp_sock = 1;
    pj_sockaddr_in_init(&info->sock_info.rtp_addr_name.ipv4, 0, 0);
    info->sock_info.rtcp_sock = 2;
    pj_sockaddr_in_init(&info->sock_info.rtcp_addr_name.ipv4, 0, 0);

    return PJ_SUCCESS;
}


/* Called by application to initialize the transport */
static pj_status_t transport_attach(   pjmedia_transport *tp,
				       void *user_data,
				       const pj_sockaddr_t *rem_addr,
				       const pj_sockaddr_t *rem_rtcp,
				       unsigned addr_len,
				       void (*rtp_cb)(void*,
						      void*,
						      pj_ssize_t),
				       void (*rtcp_cb)(void*,
						       void*,
						       pj_ssize_t))
{
    struct transport_loop *loop = (struct transport_loop*) tp;
    unsigned i;
    const pj_sockaddr *rtcp_addr;

    /* Validate arguments */
    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);

    /* Must not be "attached" to same user */
    for (i=0; i<loop->user_cnt; ++i) {
	PJ_ASSERT_RETURN(loop->users[i].user_data != user_data,
			 PJ_EINVALIDOP);
    }
    PJ_ASSERT_RETURN(loop->user_cnt != PJ_ARRAY_SIZE(loop->users), 
		     PJ_ETOOMANY);

    PJ_UNUSED_ARG(rem_rtcp);
    PJ_UNUSED_ARG(rtcp_addr);

    /* "Attach" the application: */

    /* Save the new user */
    loop->users[loop->user_cnt].rtp_cb = rtp_cb;
    loop->users[loop->user_cnt].rtcp_cb = rtcp_cb;
    loop->users[loop->user_cnt].user_data = user_data;
    ++loop->user_cnt;

    return PJ_SUCCESS;
}


/* Called by application when it no longer needs the transport */
static void transport_detach( pjmedia_transport *tp,
			      void *user_data)
{
    struct transport_loop *loop = (struct transport_loop*) tp;
    unsigned i;

    pj_assert(tp);

    for (i=0; i<loop->user_cnt; ++i) {
	if (loop->users[i].user_data == user_data)
	    break;
    }

    /* Remove this user */
    if (i != loop->user_cnt) {
	pj_array_erase(loop->users, sizeof(loop->users[0]),
		       loop->user_cnt, i);
	--loop->user_cnt;
    }
}


/* Called by application to send RTP packet */
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size)
{
    struct transport_loop *loop = (struct transport_loop*)tp;
    unsigned i;

    /* Simulate packet lost on TX direction */
    if (loop->tx_drop_pct) {
	if ((pj_rand() % 100) <= (int)loop->tx_drop_pct) {
	    PJ_LOG(5,(loop->base.name, 
		      "TX RTP packet dropped because of pkt lost "
		      "simulation"));
	    return PJ_SUCCESS;
	}
    }

    /* Simulate packet lost on RX direction */
    if (loop->rx_drop_pct) {
	if ((pj_rand() % 100) <= (int)loop->rx_drop_pct) {
	    PJ_LOG(5,(loop->base.name, 
		      "RX RTP packet dropped because of pkt lost "
		      "simulation"));
	    return PJ_SUCCESS;
	}
    }

    /* Distribute to users */
    for (i=0; i<loop->user_cnt; ++i) {
	if (!loop->users[i].rx_disabled && loop->users[i].rtp_cb)
	    (*loop->users[i].rtp_cb)(loop->users[i].user_data, (void*)pkt, 
				     size);
    }

    return PJ_SUCCESS;
}

/* Called by application to send RTCP packet */
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size)
{
    return transport_send_rtcp2(tp, NULL, 0, pkt, size);
}


/* Called by application to send RTCP packet */
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
					const pj_sockaddr_t *addr,
					unsigned addr_len,
				        const void *pkt,
				        pj_size_t size)
{
    struct transport_loop *loop = (struct transport_loop*)tp;
    unsigned i;

    PJ_UNUSED_ARG(addr_len);
    PJ_UNUSED_ARG(addr);

    /* Distribute to users */
    for (i=0; i<loop->user_cnt; ++i) {
	if (!loop->users[i].rx_disabled && loop->users[i].rtcp_cb)
	    (*loop->users[i].rtcp_cb)(loop->users[i].user_data, (void*)pkt,
				      size);
    }

    return PJ_SUCCESS;
}


static pj_status_t transport_media_create(pjmedia_transport *tp,
				  pj_pool_t *pool,
				  unsigned options,
				  const pjmedia_sdp_session *sdp_remote,
				  unsigned media_index)
{
    PJ_UNUSED_ARG(tp);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(options);
    PJ_UNUSED_ARG(sdp_remote);
    PJ_UNUSED_ARG(media_index);
    return PJ_SUCCESS;
}

static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
				        pj_pool_t *pool,
				        pjmedia_sdp_session *sdp_local,
				        const pjmedia_sdp_session *rem_sdp,
				        unsigned media_index)
{
    PJ_UNUSED_ARG(tp);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(sdp_local);
    PJ_UNUSED_ARG(rem_sdp);
    PJ_UNUSED_ARG(media_index);
    return PJ_SUCCESS;
}

static pj_status_t transport_media_start(pjmedia_transport *tp,
				  pj_pool_t *pool,
				  const pjmedia_sdp_session *sdp_local,
				  const pjmedia_sdp_session *sdp_remote,
				  unsigned media_index)
{
    PJ_UNUSED_ARG(tp);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(sdp_local);
    PJ_UNUSED_ARG(sdp_remote);
    PJ_UNUSED_ARG(media_index);
    return PJ_SUCCESS;
}

static pj_status_t transport_media_stop(pjmedia_transport *tp)
{
    PJ_UNUSED_ARG(tp);
    return PJ_SUCCESS;
}

static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
					   pjmedia_dir dir,
					   unsigned pct_lost)
{
    struct transport_loop *loop = (struct transport_loop*)tp;

    PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL);

    if (dir & PJMEDIA_DIR_ENCODING)
	loop->tx_drop_pct = pct_lost;
    
    if (dir & PJMEDIA_DIR_DECODING)
	loop->rx_drop_pct = pct_lost;

    return PJ_SUCCESS;
}

