rtphello.cpp

A basic example of how to use RTPPacket

// rtphello
// 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 other classes from
// CommonC++.

// I am a typical hello world program. I consist of a sender thread,
// that sends the salutation message on RTP packets; and a receiver
// thread, that prints the messages. This is a program with an unsual
// structure, the receiver just tries to process the first available
// packet periodically, and both are in the same program. Thus, it
// should not be seen as an example for typical applications but as a
// test of some functions of ccRTP.

#include <cstdio>
#include <ctime>
// In order to use ccRTP, the RTP stack of CommonC++, just include...
#include <ccrtp/rtp.h>

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

// base ports
const int RECEIVER_BASE = 33634;
const int TRANSMITTER_BASE = 32522;

// For this example, this is irrelevant. 
//const int TIMESTAMP_RATE = 90000;

class ccRTP_Hello_Rx: public Thread
{

private:
        // socket to receive packets
        RTPSession *socket;
        // loopback network address
        InetHostAddress local_ip;
        // identifier of this sender
        uint32 ssrc;
        
public:
        ccRTP_Hello_Rx(){
                // Before using ccRTP you should learn something about other
                // CommonC++ classes. We need InetHostAddress...

                // Construct loopback address
                local_ip = "127.0.0.1";

                // Is that correct?
                if( ! local_ip ){  
                        // this is equivalent to `! local_ip.isInetAddress()'
                        cerr << "Rx: IP address is not correct!" << endl;
                        exit();
                }

                // create socket for RTP connection and get a random
                // SSRC identifier
                socket = new RTPSession(local_ip,RECEIVER_BASE);
                ssrc = socket->getLocalSSRC();
        }
        
        ~ccRTP_Hello_Rx(){
                cout << endl << "Destroying receiver -ID: " << hex
                     << (int)ssrc;
                terminate();
                delete socket;
                cout << "... " << "destroyed.";
        }

        // This method does almost everything.
        void run(void){    

                cout << "Hello, " << defaultApplication().
                        getSDESItem(SDESItemTypeCNAME)
                     << " ..." << endl;
                // redefined from Thread.
                // Set up connection
                socket->setSchedulingTimeout(20000);
                socket->setExpireTimeout(3000000);
                //socket->UDPTransmit::setTypeOfService(SOCKET_IPTOS_LOWDELAY);
                if( !socket->addDestination(local_ip,TRANSMITTER_BASE) )
                        cerr << "Rx (" << hex << (int)ssrc 
                             << "): could not connect to port." 
                             << TRANSMITTER_BASE;
                
                cout << "Rx (" << hex << (int)ssrc
                     << "): " << local_ip.getHostname() 
                     << " is waiting for salutes in port "
                     << RECEIVER_BASE << "..." << endl;
                
                socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
                socket->startRunning();
                // Let's check the queues  (you should read the documentation
                // so that you know what the queues are for).
                cout << "Rx (" << hex << (int)ssrc 
                     << "): The queue is " 
                     << ( socket->isActive() ? "" : "in") 
                     << "active." << endl;              

                // This is the main loop, where packets are received.
                for( int i = 0 ; true ; i++ ){
                        
                        // Wait for an RTP packet.
                        const AppDataUnit *adu = NULL;
                        while ( NULL == adu ) {
                                Thread::sleep(10);
                                adu = socket->getData(socket->getFirstTimestamp());
                        }
                        
                        // Print content (likely a salute :))
                        // Note we are sure the data is an asciiz string.
                        time_t receiving_time = time(NULL);
                        char tmstring[30];
                        strftime(tmstring,30,"%X",localtime(&receiving_time));
                        cout << "Rx (" << hex << (int)ssrc 
                             << "): [receiving at " << tmstring << "]: " 
                             << adu->getData() << endl;
                        delete adu;
                }
        }
};

class ccRTP_Hello_Tx: public Thread, public TimerPort
{

private:
        // socket to transmit
        RTPSession *socket;
        // loopback network address
        InetHostAddress local_ip;
        // identifier of this sender
        uint32 ssrc;

public:
        ccRTP_Hello_Tx(){
                // Before using ccRTP you should learn something about other
                // CommonC++ classes. We need InetHostAddress...

                // Construct loopback address
                local_ip = "127.0.0.1";
                
                // Is that correct?
                if( ! local_ip ){  
                // this is equivalent to `! local_ip.isInetAddress()'
                        cerr << "Tx: IP address is not correct!" << endl;
                        exit();
                }
                
                socket = new RTPSession(local_ip,TRANSMITTER_BASE);
                ssrc = socket->getLocalSSRC();
        }

        ~ccRTP_Hello_Tx(){
                cout << endl << "Destroying transmitter -ID: " << hex 
                     << (int)ssrc;
                terminate();
                delete socket;
                cout << "... " << "destroyed.";
        }

        // This method does almost everything.
        void run(void){    
                // redefined from Thread.
                cout << "Tx (" << hex << (int)ssrc << "): " << 
                        local_ip.getHostname() 
                     << " is going to salute perself through " 
                     << local_ip << "..." << endl;
                
                // Set up connection
                socket->setSchedulingTimeout(20000);
                socket->setExpireTimeout(3000000);
                if( !socket->addDestination(local_ip,RECEIVER_BASE) )
                        cerr << "Tx (" << hex << (int)ssrc 
                             << "): could not connect to port." 
                             << RECEIVER_BASE;
                
                cout << "Tx (" << hex << (int)ssrc << 
                        "): Transmitting salutes to port "
                     << RECEIVER_BASE << "..." << endl;

                uint32 timestamp = 0;
                // This will be useful for periodic execution
                TimerPort::setTimer(1000);

                // This is the main loop, where packets are sent.
                socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
                socket->startRunning();
                // Let's check the queues  (you should read the documentation
                // so that you know what the queues are for).
                cout << "Tx (" << hex << (int)ssrc << "): The queue is "
                     << ( socket->isActive()? "" : "in")
                     << "active." << endl;

                for( int i = 0 ; true ;i++ ){

                        // send RTP packets, providing timestamp,
                        // payload type and payload.  
                        // construct salute.
                        unsigned char salute[50];
                        snprintf((char *)salute,50,
                                 "Hello, brave gnu world (#%u)!",i);
                        time_t sending_time = time(NULL);
                        // get timestamp to send salute
                        if ( 0 == i ){
                                timestamp = socket->getCurrentTimestamp();
                                
                        } else {
                                // increment for 1 second
                                timestamp += socket->getCurrentRTPClockRate();
                        }       

                        socket->putData(timestamp,salute,
                                        strlen((char *)salute)+1);
                        // print info
                        char tmstring[30];
                        strftime(tmstring,30,"%X",
                                 localtime(&sending_time));
                        cout << "Tx (" << hex << (int)ssrc 
                             << "): sending salute " << "no " << dec << i 
                             << ", at " << tmstring 
                             << "..." << endl;

                        // Let's wait for the next cycle
                        Thread::sleep(TimerPort::getTimer());
                        TimerPort::incTimer(1000);
                }
        }
};

int main(int argc, char *argv[])
{

        // Construct the two main threads. they will not run yet.
        ccRTP_Hello_Rx *receiver = new ccRTP_Hello_Rx;
        ccRTP_Hello_Tx *transmitter = new ccRTP_Hello_Tx;
        
        cout << "This is rtphello, a very simple test program for ccRTP." << 
                endl << "Strike [Enter] when you are fed up with it." << endl;

        // Start execution of hello now.
        receiver->start();
        transmitter->start();

        cin.get();

        delete transmitter;
        delete receiver;

        cout << endl << "That's all." << endl;
        
        return 0;
}


Generated on 15 Dec 2009 for ccRTP by  doxygen 1.6.1