// Copyright (C) 1999 Open Source Telecom Corporation.
//  
// 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.

#ifndef __RTS_RTP_H__
#define __RTS_RTP_H__

#ifndef __RTS_THREAD_H__
#include <RTS/thread.h>
#endif

#ifndef __APE_SOCKET_H__
#include <APE/socket.h>
#endif

#ifndef __RTS_MISC_H__
#include <RTS/misc.h>
#endif

#ifdef  WIN32
class __EXPORT RTPSocket;
class __EXPORT RTPBroadcast;
class __EXPORT RTPReceiver;
class __EXPORT RTPTransceiver;
#endif

/**
 * This abstract class implements the basic support needed for a UDP
 * RTP socket.  The RTP Socket with dual service threads are now known
 * as RTPTransiever.
 * 
 * @author David Sugar <dyfet@ostel.com>.
 * @short Abstract base class for UDP RTP protocol service.
 */
class RTPSocket : public UDPSocket
{
private:
	long _framesize;
protected:
#pragma pack(1)
	struct
	{
		unsigned char flags[2];
		unsigned char sequence[2];
		unsigned char timestamp[4];
		unsigned char source[4];
		unsigned char conf[15][4];
	} rtprecv, rtpsend;            
#pragma pack()
	/**
	 * set default frame sample size currently in effect.
	 *
	 * @param number of samples in the current frame.
	 */
	void setFrameSampleSize(long samples)
		{_framesize = samples;};
	/**
	 * Sets the payload id for sending RTP packets.  This is
	 * virtualized so that RTPAudio can also specify sampling
	 * rates based on the returned value.
	 * 
	 * @param payload message type (0-127) for sending.
	 * @param optional frame timeout for sample size.
	 */
	virtual void setPayload(unsigned payload, timeout_t frame_timeout = 0);
	/**
	 * Retrieve payload format and header info for host socket.
	 * 
	 * @return RTP payload format.
	 * @param seq number of last sent packet.
	 * @param timestamp of last sent packet.
	 */
public:
	unsigned getHostHeader(unsigned short *seq = NULL, unsigned long *timestamp = NULL);
	/**
	 * Retrieve payload format and header info from peer socket.
	 * 
	 * @return RTP payload format.
	 * @param seq number of last received packet.
	 * @param timestamp of last received packet.
	 */
	unsigned getPeerHeader(unsigned short *seq = NULL, unsigned long *timestamp = NULL);
	/**
	 * Add a conference id to the RTP send message.
	 * 
	 * @param source for added conference id.
	 */
	virtual void addConference(unsigned long source);
	/**
	 * Set this server's stream source id.
	 * 
	 * @param source id to use for my stream.
	 */
	 inline void setSource(unsigned long source)
		{setRTLong(rtpsend.source, source);};
	/**
	 * Write data to the UDP socket.  This implements the send
	 * service thread writer.
	 * 
	 * @return number of bytes written on success, -1 on failure.
	 * @param address buffer to write.
	 * @param len of bytes to write in addition to the header.
	 */
	int Write(void *buf, size_t len);
	/**
	 * read data from the UDP socket.  This implements the receive
	 * service thread reader.
	 * 
	 * @return number of bytes read on success, -1 on failure.
	 * @param address buffer to read.
	 * @param len of bytes to read from buffer.
	 */
	int Read(void *buf, size_t len);
	/**
	 * wait for data to appear in the socket, and if it does, fill
	 * the header.
	 * 
	 * @return 0 on success, -1 if timed out.
	 * @param timeout in milliseconds.
	 */
	int Wait(timeout_t timer);
	/**
	 * Update the time stamp for the next sent packet.
	 *
	 * @param count of frames to skip.
	 */
	void Skip(int count = 1);
	/**
	 * Get default frame sample size currently in effect.
	 *
	 * @return number of samples in the current frame.
	 */
	long getFrameSampleSize(void)
		{return _framesize;};
	/**
	 * Create and bind an RTP socket to an internet interface address
	 * and known port number.  The sending thread timeout can be
	 * adjusted with setTimeout() before calling Start() for the sending
	 * service thread.  One might also call setPayload, etc.
	 * 
	 * @param bind address to bind this socket to.
	 * @param port address to bind the service under.
	 */
	RTPSocket(InetAddress &bind, short port);
	RTPSocket(BroadcastAddress &bind, short port);
};

/**
 * This abstract class implements the basic support needed for a RTP
 * broadcast session using UDP packets.  Broadcasts are uni-directional
 * and can be used to flood a subnet with real-time streaming.  There
 * should also be a RTPMulticast added soon.
 * 
 * @author David Sugar <dyfet@ostel.com>.
 * @short Abstract base class for UDP RTP subnet broadcast.
 */
class RTPBroadcast : public RTPSocket, public RTSSendThread
{
private:
	Semaphore _start;
	
protected:
	/**
	 * Update the time stamp for the next sent packet from the
	 * service thread. 
	 *
	 * @param number of samples to increment by.
	 */
	void RTSUpdate(void)
		{Skip();};
	/**
	 * Write data from the service thread to the RTP socket.
	 * 
	 * @return number of bytes written on success, -1 on failure.
	 * @param address buffer to write.
	 * @param len of bytes to write in addition to the header.
	 */
	ssize_t RTSSend(unsigned char *buf, size_t len);
public:
	/**
	 * Create and bind an RTP socket to an internet interface address
	 * and known port number for the purpose of subnet broadcasting
	 * with RTP.
	 * 
	 * @param bind address to bind this socket to.
	 * @param port address to bind the service under.
	 * @param pri of service threads relative to parent.
	 * @param session id for sending under.
	 */
	RTPBroadcast(BroadcastAddress &bind, short port, int pri);
};

/**
 * This abstract class implements the basic support needed for a RTP
 * packet reception using UDP packets.  The receiver is uni-directional
 * and can be used to receive real-time streaming broadcasts.  
 * 
 * @author David Sugar <dyfet@ostel.com>.
 * @short Abstract base class for UDP RTP reception.
 */
class RTPReceiver : public RTPSocket, public RTSRecvThread
{
private:
	Semaphore _start;
	
protected:
	/**
	 * Read data from the service thread to the RTP socket.
	 * 
	 * @return number of bytes read on success, -1 on failure.
	 * @param address buffer to write.
	 * @param seq number of current packet.
	 * @param timestamp of current packet.
	 */
	ssize_t RTSRecv(unsigned char *buf, unsigned short *seq, unsigned long *stamp);
public:
	/**
	 * Create and bind an RTP receiver to an internet interface address
	 * and known port number for the purpose of receiving RTP.
	 * 
	 * @param bind address to bind this socket to.
	 * @param port address to bind the service under.
	 * @param pri of service threads relative to parent.
	 * @param session id for sending under.
	 */
	RTPReceiver(InetAddress &bind, short port, int pri);
};

/**
 * This abstract class implements the basic support needed for full
 * duplex realtime streaming using two service threads.
 * 
 * @author David Sugar <dyfet@ostel.com>.
 * @short Abstract base class for full duplex UDP RTP streaming.
 */
class RTPTransceiver : public RTPReceiver, public RTSSendThread
{
private:
	Semaphore _start;
	
protected:
	ssize_t RTSRecv(unsigned char *buf, unsigned short *seq, unsigned long *timestamp);
	/**
	 * Update the time stamp for the next sent packet from the
	 * service thread. 
	 * @param current sending timeout.
	 *
	void RTSUpdate(timeout_t timer)
		{Skip();};
	/**
	 * Write data from the service thread to the RTP socket.
	 * 
	 * @return number of bytes written on success, -1 on failure.
	 * @param address buffer to write.
	 * @param len of bytes to write in addition to the header.
	 */
	ssize_t RTSSend(unsigned char *buf, size_t len);
	/**
	 * Complex setTimeout must set both sender and receiver.
	 * 
	 * @param session time window in milliseconds.
	 */
	void setTimeout(timeout_t timeout);
public:
	/**
	 * Start both the sender and receiver service threads.
	 */
	void Start(void);
	/**
	 * Create and bind an RTP receiver to an internet interface address
	 * and known port number for the purpose of receiving RTP.
	 * 
	 * @param bind address to bind this socket to.
	 * @param port address to bind the service under.
	 * @param pri of service threads relative to parent.
	 * @param session id for sending under.
	 */
	RTPTransceiver(InetAddress &bind, short port, int pri);
};

#endif

Documentation generated by dyfet@home.tycho.com on Fri Jul 2 11:43:56 EDT 1999