/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef _RTP_API_H
#define _RTP_API_H

#include "mas/mas_types.h"
#include "rtp_transport.h"
#include "rtp_transport_stream.h"
#include "rtperror.h"

/************************************************************************
 * rtp_api
 *
 * This is a C wrapper of the C++ library "jrtplib."  Make no mistake:
 * this is only a subset of the rich functionality jrtplib provides.
 * We developed this for the Media Application Server project, so many
 * of the functions here are tailored to it.  Note well the use of the
 * term "p2p"; this is due to a simplification made in the MAS RTP
 * profile, excluding the possibility of multicast UDP in the core
 * protocol.  You can use the p2p functions when there's only one
 * peer, when a RTP session is comprised of two transport endpoints.
 *
 * We include rtp_transport_stream.h, the C wrapper that accesses our
 * stream-transport extensions to jrtplib.  With these functions, one
 * can do RTP over TCP and UNIX sockets.
 *
 ************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

    struct rtp_packet
    {
        char		*payload;
        int		 payload_len;
        unsigned char	*header_ext;
        uint16	 header_ext_len;
        uint16	 header_ext_type;
        uint8    v;		/* packet type (version)      */
        uint8    p;		/* padding flag               */
        uint8    x;		/* header extension flag      */
        uint8    cc;	/* CSRC count                 */
        uint8    m;		/* marker bit                 */
        uint8    pt;	/* payload type               */
        uint16   seq;	/* sequence number            */
        uint32   ts;	/* timestamp                  */
        uint32   ssrc;	/* synchronization source     */
    };

    struct rtp_sr
    {
        int srreceived;
        struct timeval srtime;
        struct mas_ntpval ntp;
        uint32 ts;
        uint32 packetcount;
        uint32 bytecount;
    };

    struct rtp_rr
    {
        int rrreceived;
        struct timeval rrtime;
        uint8 fractionlost;
        int32 packetslost;
        uint32 exthighseqnum;
        uint32 jitter;
        uint32 lsr;
        uint32 dlsr;
    };

    struct rtp_source_stats
    {
        int hassentdata;
        int32 numpacketsreceived;
        int32 numnewpackets;
        int32 numcycles;
        uint32 seqbase;
        uint32 maxseq;
        uint32 prevmaxseq;
        uint32 prevts;
        uint32 jitter;
        double djitter;
        struct timeval prevpacktime;
        struct timeval rtt;
        uint32 lastmsgtime;
    };

    struct rtp_sdes
    {
        uint32 src;
        char  *sdesinfo[RTP_NUM_SDES_INDICES];
        int    sdesinfolen[RTP_NUM_SDES_INDICES];
    };
    
    struct rtp_source_data
    {
        uint32 ssrc;
        struct rtp_sr sr;
        struct rtp_rr rr;
        struct rtp_sdes sdes;
        struct rtp_source_stats stats;
        int hassentnewdata;
        int isaCSRC;
        uint32 ip;
        int rtpport;
        int rtcpport;
        double tsunit;
    };

    struct rtp_session
    {
        int        id;
        MAS_SOCKET rx_rtp_socket;
        MAS_SOCKET rx_rtcp_socket;
        MAS_SOCKET tx_socket;
        struct rtp_source_data sd;
    };
    
    extern int32 rtp_create_udp_p2p_session(struct rtp_session* s, uint32
                                            peer_addr, 
                                            uint16 peer_rx_portbase,
                                            uint16 local_rx_portbase);

    extern int32 rtp_create_stream_pair_p2p_session(struct rtp_session* s,
                                                    uint32 peer_addr,
                                                    int peer_portbase,
                                                    int session_type,
                                                    RTPSOCKET rtpsock, 
                                                    RTPSOCKET rtcpsock);

    extern int32 rtp_send( struct rtp_session* s, char* data, int len,
                           char pt, int mark, uint32 ts, uint32 seq);

    extern int32 rtp_p2p_send( struct rtp_session* s, char* data, int len,
                               char pt, int mark, uint32 ts, uint32 seq );

    extern int32 rtp_send_simple( struct rtp_session* s, char* data, int len);

    extern int32 rtp_send_control(struct rtp_session* s, char* data, int len);

    extern int32 rtp_p2p_send_simple( struct rtp_session* s, char* data, int len );

    extern int32 rtp_p2p_send_control(struct rtp_session* s, char* data, int len);

    extern int32 rtp_p2p_recv( struct rtp_session* s, 
                               struct rtp_packet* packet, 
                               int check_net_for_rtp, int check_net_for_rtcp);

    extern int32 rtp_p2p_retrieve_packet_from_library(struct rtp_session* s, 
                                                      struct rtp_packet* packet);

    extern int32 rtp_process_packets(struct rtp_session* s, int rtp, int rtcp, int check_for_data );

    extern int32 rtp_process_rtcp_if_any(struct rtp_session* s);
    
    extern int32 rtp_is_data_in_library_queue(struct rtp_session* s);

    extern int32 rtp_destroy_session( struct rtp_session* s );

    extern int32 rtp_get_local_ssrc( struct rtp_session* s, uint32* ssrc );

    extern int32 rtp_set_local_ssrc( struct rtp_session* s, uint32 ssrc );

    extern int32 rtp_get_peer_ssrc( struct rtp_session* s, uint32* ssrc );

    extern int32 rtp_get_peer_sr(struct rtp_session* s);
    
    extern int32 rtp_update_sd( struct rtp_session* s );

    extern int32 rtp_set_tsu( struct rtp_session* s, double tsu );
    extern int32 rtp_set_pt( struct rtp_session* s, uint8 pt );
    extern int32 rtp_set_rtcp_bw( struct rtp_session* s, double bwfrac );
    
/***** TO DO **********************************/
/*  rtp_poll */
/*  rtp_get_rr */
/*  rtp_get_sr */
/*  rtp_bye */
/*  rtp_recv_packet */
/*  rtcp_send_report */


/*  rtp_set_timestamp_unit */
/*  rtp_set_destination */
/*  rtp_set_payload_type */
/*  rtp_set_mark */
/*  rtp_set_timestamp_increment */

#if defined(__cplusplus)
}
#endif

#endif /* _RTP_API_H */
