basic multicast transmit

Marc Lindahl <[email protected]> Fri, 26 Oct 2012 10:48:16 -0400
Newsgroups gmane.comp.gnu.ccrtp.devel
Message-ID <[email protected]>
I'm trying to get a basic multicast transmitter working to no avail.  (It 
would be great if any of the demos or examples showed this, or if there were 
anything but vague references in the doc) 

So I tried to modify the audiotx demo, but wireshark tells me i'm not 
sending any packets despite the program appearing to work ok.  (btw, another 
multicasting transmitter program on the same computer does show packets 
spewing so i'm pretty sure the setup is OK) 

Here's the modified source.... what am I missing? 

 ---------------------- 

// audiotx.
// A simple and amusing program for testing basic features of ccRTP.
// Copyright (C) 2001,2002  Federico Montesino <[email protected]>
//<snipped comment block> 

#include <cstdio>
#include <cstdlib>
// Some consts common to audiotx and audiorx
#include <audio.h>
// In order to use ccRTP, the RTP stack of CommonC++, you only need to
// include ...
#include <ccrtp/rtp.h>
#include <fcntl.h> 

using namespace ost;
using namespace std; 

// TODO: a temporary fix....just to allow building on broken platforms...
#ifndef O_NDELAY
#define O_NDELAY 0
#endif 

/**
 * @class ccRTP_AudioTransmitter
 * This is the class that will do almost everything.
 */
class ccRTP_AudioTransmitter: public Thread, public TimerPort
{
private:
    // This is the descriptor of the file we will read from
    // (commonly, /dev/audio or a .au file)
    int audioinput; 

    // If we are sending a .au file
    bool sendingfile; 

    // The aforementioned file will be transmitted through this socket
    RTPSession *socket; 

public:
    // Constructor. If it is given a file name, this thread will
    // transmit that file. If it is not, /dev/audio input is
    // transmitted
    ccRTP_AudioTransmitter(char *filename=(char *)"") { 

        if( !strcmp(filename,"") ) {
            filename=(char *)"/dev/audio";
            sendingfile = false;
        }else{
            sendingfile = true;
        } 

        audioinput=open(filename,O_RDONLY|O_NDELAY); 

        if( audioinput >= 0 ) {
            cout << "Ready to transmit " << filename << "." <<endl;
        }else{
            cout << "I could not open " << filename << "." << endl;
            exit();
        } 

        socket=NULL;
    } 

    // Destructor.
    ~ccRTP_AudioTransmitter() {
        terminate();
        delete socket;
        ::close(audioinput);
    } 

    // 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
        InetMcastAddress local_ip;
        local_ip = "239.192.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 transmit audio to perself through " <<
            local_ip << "..." << endl; 

        // ____Here comes the real RTP stuff____ 

        // Construct the RTP socket.
        socket = new RTPSession(local_ip,5004); 

        // Set up connection
        socket->setSchedulingTimeout(10000);
//        if( !socket->addDestination(local_ip,RECEIVER_BASE) )
//            cerr << "I could not connect."; 

	socket->setMcastTTL(2); 

        socket->setPayloadFormat(StaticPayloadFormat(sptL16_DUAL)); 

        socket->startRunning();
        cout << "The RTP queue service thread is ";
        if( socket->isActive() )
            cout << "active." << endl;
        else
            cerr << "not active." << endl; 

        cout << "Transmitting " << PACKET_SIZE
             << " octects long packets "
             << "every " << PERIOD << " milliseconds..." << endl; 

        unsigned char buffer[PACKET_SIZE];
        int count=PACKET_SIZE; 

        // This will be useful for periodic execution
        TimerPort::setTimer(PERIOD); 

        // This is the main loop, where packets are transmitted.
        for( int i = 0 ; (!sendingfile || count > 0) ; i++ ) { 

            count = ::read(audioinput,buffer,PACKET_SIZE);
            if( count > 0 ) {
                // send an RTP packet, providing timestamp,
                // payload type and payload.
                socket->putData(PACKET_SIZE*i,buffer,
                        PACKET_SIZE);
            }
            cout << "." << flush; 

            // Let's wait for the next cycle
            Thread::sleep(TimerPort::getTimer());
            TimerPort::incTimer(PERIOD);
        }
        cout << endl << "I have got no more data to send. " <<endl;
    }
}; 

int main(int argc, char *argv[])
{
    cout << "This is audiotx, a simple test program for ccRTP." << endl;
    cout << "You should have run audiorx (the server/receiver) before." << 
endl;
    cout << "Strike [Enter] when you are fed up. Enjoy!." << endl; 

    ccRTP_AudioTransmitter *transmitter; 

    // Construct the main thread. It will not run yet.
    if ( argc == 2 )
        transmitter = new ccRTP_AudioTransmitter(argv[1]);
    else
        transmitter = new ccRTP_AudioTransmitter(); 

    // Start transmitter thread.
    transmitter->start(); 

    cin.get(); 

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

    delete transmitter; 

    exit(0);
} 

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