// rtpduphello. 
// A very simple program for testing and illustrating basic features of ccRTP.
// Copyright (C) 2001,2002  Federico Montesino <fedemp@altern.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


// This is an introductory example file that illustrates basic usage
// of ccRTP. You will also see a bit on how to use CommonC++ threads.

// It is a typical hello world program. It consists of tow duplex
// connections that talk each other through RTP packets. They do not
// say more than a typical salutation message. They both send and
// receive messages, and print the messages they receive.


#include <cstdio>
#include <cstdlib>
// In order to use ccRTP, the RTP stack of CommonC++, you only need to
// include ...
#include <ccrtp/ext.h>

#ifdef	CCXX_NAMESPACES
using namespace ost;
using namespace std;
#endif

/**
 * @class ccRTP_dupHello
 * This is the class that will do almost everything.
 */
class ccRTP_dupHello: public Thread
{
private:
	// There will be two duplex connections. They both will send
	// and receive packets.
	RTPDuplex *duplexA, *duplexB;
	
public:
	// Destructor.
	~ccRTP_dupHello(){
		terminate();
		delete duplexA;
		delete duplexB;  
	}
	
	// Constructor.
	ccRTP_dupHello() : duplexA(NULL), duplexB(NULL)
	{ }

	// This method does almost everything.
	void run(void){    
		// redefined from Thread.
		
		// Before using ccRTP you should learn something about other
		// CommonC++ classes. We need InetHostAddress...

		// Construct loopback address
		InetHostAddress local_ip;
		local_ip = "127.0.0.1";
		
		// Is that correct?
		if( ! local_ip ){  
		// this is equivalent to `! local_ip.isInetAddress()'
			cerr << ": IP address is not correct!" << endl;
			exit();
		}
		
		cout << local_ip.getHostname() << 
			" is going to talk to perself through " <<
			local_ip << "..." << endl;
				
		// ____Here comes the real RTP stuff____
		
		// Construct two RTPSocket. 22222 will be the base
		// port of A.  33334 will be the base port of B.
		const int A_BASE = 22222;
		const int B_BASE = 33334;

		duplexA = new RTPDuplex(local_ip,A_BASE,B_BASE);
		
		duplexB = new RTPDuplex(local_ip,B_BASE,A_BASE);

		// Set up A's connection
		duplexA->setSchedulingTimeout(90000);
		duplexA->setExpireTimeout(2500000);
		if( duplexA->connect(local_ip,B_BASE) < 0 )
			cerr << "Duplex A could not connect.";
		
		// Set up B's connection
		duplexB->setSchedulingTimeout(160000);  
		duplexB->setExpireTimeout(3500000);
		if( duplexB->connect(local_ip,A_BASE) < 0 )
			cerr << "Duplex B could not connect.";
		
		// Let's check the queues  (you should read the documentation
		// so that you know what the queues are for).
		
		if( duplexA->RTPDataQueue::isActive() )
			cout << "The queue A is active." << endl;
		else
			cerr << "The queue  A is not active." << endl;
		
		if( duplexB->RTPDataQueue::isActive() )
			cout << "The queue B is active." << endl;
		else
			cerr << "The queue B is not active." << endl;
		

		cout << "Transmitting..." << endl;
		
		// This message will be sent on RTP packets, from A to
		// B and from B to A.
		unsigned char helloA[] = "Hello, brave gnu world from A!";
		unsigned char helloB[] = "Hello, brave gnu world from B!";

		// This is not important
		time_t sending_time;
		time_t receiving_time;
		char tmstring[30];

		StaticPayloadFormat pf = sptMP2T;
		duplexA->setPayloadFormat(pf);
		duplexB->setPayloadFormat(pf);

		// This is the main loop, where packets are sent and receipt.
		// A and B both will send and receive packets.
		for( int i = 0 ; true ; i++ ){

			// A and B do almost exactly the same things,
			// I have kept this here -out of a send/receive
			// method- in the interest of clarity.

			// A: Send an RTP packet			
			sending_time = time(NULL);
			duplexA->putData(2*(i)*90000,helloA,
					  strlen((char *)helloA));
			// Tell it
			strftime(tmstring,30,"%X",localtime(&sending_time));
			cout << "A: sending message at " << tmstring << "..." 
			     << endl;

			// A: Receive an RTP packet
			receiving_time = time(NULL);
			const AppDataUnit* aduA = 
				duplexA->getData(duplexA->getFirstTimestamp());
			if ( aduA ) {
				// Tell it
				strftime(tmstring,30,"%X",localtime(&receiving_time));
				cout << "A:[receiving at " << tmstring << "]: " << 
					aduA->getData() << endl;
			}
			// Wait for 0.1 seconds
			Thread::sleep(100);

			// B: Send an RTP packet			
			sending_time = time(NULL);
			duplexB->putData(2*(i)*90000,helloB,
					 strlen((char *)helloB));
			// Tell it
			strftime(tmstring,30,"%X",localtime(&sending_time));
			cout << "B: sending message at " << tmstring << "..." 
			     << endl;

			// B: Receive an RTP packet
			receiving_time = time(NULL);
			const AppDataUnit* aduB = 
				duplexB->getData(duplexB->getFirstTimestamp());
			if ( aduB ) {
				// Tell it
				strftime(tmstring,30,"%X",localtime(&receiving_time));
				cout << "B:[receiving at " << tmstring << "]: " << 
					aduB->getData() << endl;
			}

			Thread::sleep(1900);
		}

	}
};

int main(int argc, char *argv[])
{
	// Construct the main thread. It will not run yet.
	ccRTP_dupHello *hello = new ccRTP_dupHello;
	
	cout << "This is rtpduphello, a very simple test program for ccRTP." 
	     << endl << "Strike [Enter] when you are fed up." << endl;
	
	// Start execution of hello.
	hello->start();
	
	cin.get();

	cout << endl << "That's all" << endl;

	delete hello;

	exit(0);
}

/** EMACS **
 * Local variables:
 * mode: c++
 * c-basic-offset: 8
 * End:
 */





syntax highlighted by Code2HTML, v. 0.9.1