ccrtptest.cpp

00001 // test ccRTP functionality
00002 // Copyright (C) 2004 Federico Montesino Pouzols <fedemp@altern.org>
00003 //  
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 2 of the License, or
00007 // (at your option) any later version.
00008 //  
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //  
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 #include <cstdlib>
00018 #include <ccrtp/rtp.h>
00019 
00020 #ifdef  CCXX_NAMESPACES
00021 using namespace ost;
00022 using namespace std;
00023 #endif
00024 
00025 
00026 class PacketsPattern
00027 {
00028 public:
00029         inline const InetHostAddress&
00030         getDestinationAddress() const
00031         { return destinationAddress; }
00032 
00033         inline const tpport_t
00034         getDestinationPort() const
00035         { return destinationPort; }
00036 
00037         uint32
00038         getPacketsNumber() const
00039         { return packetsNumber; }
00040 
00041         const unsigned char*
00042         getPacketData(uint32 i)
00043         { return data; }
00044         
00045         const size_t
00046         getPacketSize(uint32 i)
00047         { return packetsSize; }
00048 
00049 private:
00050         static const InetHostAddress destinationAddress;
00051         static const uint16 destinationPort = 34566;
00052         static const uint32 packetsNumber = 100;
00053         static const uint32 packetsSize = 100;
00054         static unsigned char data[65535];
00055 };
00056 
00057 const InetHostAddress PacketsPattern::destinationAddress = 
00058 InetHostAddress("localhost");
00059 unsigned char PacketsPattern::data[65535];
00060 
00061 PacketsPattern pattern;
00062 
00063 class
00064 Test
00065 {
00066 public:
00067         virtual int
00068         doTest() = 0;
00069 };
00070 
00071 class
00072 SendPacketTransmissionTest : public Test, public Thread, public TimerPort
00073 {
00074 public:
00075         void
00076         run()
00077         {
00078                 doTest();
00079         }
00080 
00081         int doTest()
00082         {
00083                 // should be valid?
00084                 //RTPSession tx();
00085                 RTPSession tx(InetHostAddress("localhost"));
00086                 tx.setSchedulingTimeout(10000);
00087                 tx.setExpireTimeout(1000000);
00088                 
00089                 tx.startRunning();
00090                 
00091                 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
00092                 if ( !tx.addDestination(pattern.getDestinationAddress(),
00093                                         pattern.getDestinationPort()) ) {
00094                 return 1;
00095                 }
00096                 
00097                 // 50 packets per second (packet duration of 20ms)
00098                 uint32 period = 20;
00099                 uint16 inc = tx.getCurrentRTPClockRate()/50;
00100                 TimerPort::setTimer(period);
00101                 for ( uint32 i = 0; i < pattern.getPacketsNumber(); i++ ) {
00102                         tx.putData(i*inc,
00103                                    pattern.getPacketData(i),
00104                                    pattern.getPacketSize(i));
00105                         Thread::sleep(TimerPort::getTimer());
00106                         TimerPort::incTimer(period);
00107                 }
00108                 return 0;
00109         }
00110 };
00111 
00112 
00113 class
00114 RecvPacketTransmissionTest : public Test, public Thread
00115 {
00116 public:
00117         void
00118         run()
00119         {
00120                 doTest();
00121         }
00122 
00123         int
00124         doTest()
00125         {               
00126                 RTPSession rx(pattern.getDestinationAddress(),
00127                               pattern.getDestinationPort());
00128 
00129                 rx.setSchedulingTimeout(10000);
00130                 rx.setExpireTimeout(1000000);
00131                 
00132                 rx.startRunning();
00133                 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
00134                 // arbitrary number of loops
00135                 for ( int i = 0; i < 500 ; i++ ) {
00136                         const AppDataUnit* adu;
00137                         while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
00138 
00139                                 delete adu;
00140                         }
00141                         Thread::sleep(7);
00142                 }
00143                 return 0;
00144         }
00145 };
00146 
00147 class
00148 MiscTest : public Test, public Thread, public TimerPort
00149 {
00150         void
00151         run()
00152         {
00153                 doTest();
00154         }
00155 
00156         int
00157         doTest()
00158         {
00159                 const uint32 NSESSIONS = 10;
00160                 RTPSession rx(pattern.getDestinationAddress(),pattern.getDestinationPort());
00161                 RTPSession **tx = new RTPSession* [NSESSIONS];
00162                 for ( uint32 i = 0; i < NSESSIONS; i++ ) {
00163                         tx[i] = new RTPSession(InetHostAddress("localhost"));
00164                 }
00165                 for ( uint32 i = 0; i  < NSESSIONS; i++) {
00166                         tx[i]->setSchedulingTimeout(10000);
00167                         tx[i]->setExpireTimeout(1000000);
00168                         tx[i]->setPayloadFormat(StaticPayloadFormat(sptPCMU));
00169                         if ( !tx[i]->addDestination(pattern.getDestinationAddress(),
00170                                                     pattern.getDestinationPort()) ) {
00171                                 return 1;
00172                         }
00173                 }
00174 
00175                 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
00176                 rx.setSchedulingTimeout(5000);
00177                 rx.setExpireTimeout(10000000); // 10 seconds!
00178                 rx.startRunning();
00179 
00180                 for ( uint32 i = 0; i  < NSESSIONS; i++) {
00181                         tx[i]->startRunning();
00182                 }
00183                 uint32 period = 20;
00184                 TimerPort::setTimer(period);
00185                 for ( uint32 i = 0; i < pattern.getPacketsNumber(); i++ ) {
00186                         if ( i == 70 ) {
00187                                 RTPApplication &app = defaultApplication();
00188                                 app.setSDESItem(SDESItemTypeCNAME,"foo@bar");
00189                         }
00190                         for ( uint32 s = 0; s  < NSESSIONS; s++) {
00191                         // 50 packets per second (packet duration of 20ms)
00192                                 uint16 inc = 
00193                                         tx[s]->getCurrentRTPClockRate()/50;
00194                                 tx[s]->putData(i*inc,
00195                                                pattern.getPacketData(i),
00196                                                pattern.getPacketSize(i));
00197                         }
00198                         Thread::sleep(TimerPort::getTimer());
00199                         TimerPort::incTimer(period);
00200                 }
00201 
00202                 Thread::sleep(5000);
00203                 for ( uint32 i = 0; i < NSESSIONS; i++ ) {
00204                         delete tx[i];
00205                 }
00206                 RTPSession::SyncSourcesIterator it;
00207                 cout << "Sources of synchronization:" << endl;
00208                 for (it = rx.begin() ; it != rx.end(); it++) {
00209                         const SyncSource &s = *it;
00210                         cout << s.getID();
00211                         if ( s.isSender() ) 
00212                                 cout << " (sender) ";
00213                         cout << s.getNetworkAddress() << ":" <<
00214                                 s.getControlTransportPort() << "/" <<
00215                                 s.getDataTransportPort();
00216                         Participant *p = s.getParticipant();
00217                         cout << " (" << 
00218                                 p->getSDESItem(SDESItemTypeCNAME)
00219                              << ") " << endl;
00220                 }
00221                 RTPApplication &app = defaultApplication();
00222                 RTPApplication::ParticipantsIterator ai;
00223                 cout << "Participants:" << endl;
00224                 for ( ai = app.begin(); ai != app.end(); ai++ ) {
00225                         const Participant &p = *ai;
00226                         cout << p.getSDESItem(SDESItemTypeCNAME) << endl;
00227                         //cout << p.getPRIVPrefix();
00228                 }
00229                 delete tx;
00230                 return 0;
00231         }
00232 };
00233 
00234 // class TestPacketHeaders { }
00235 // header extension
00236 
00237 // class TestRTCPTransmission { }
00238 
00239 // class TestMiscellaneous { }
00240 
00241 // Things that should be tested:
00242 // extreme values (0 - big) for putData
00243 // segmentation (setMaxSendSegmentSize())
00244 // performance: packets/second (depending on packet size and # of participants)
00245 int main(int argc, char *argv[])
00246 {
00247         int result = 0;
00248         bool send = false;
00249         bool recv = false;
00250 
00251         RecvPacketTransmissionTest *rx;
00252         SendPacketTransmissionTest *tx;
00253 
00254         // accept as parameter if must run as --send or --recv
00255 
00256         // run several tests in parallel threads
00257         if ( send ) {
00258                 tx = new SendPacketTransmissionTest();
00259                 tx->start();
00260                 tx->join();
00261         } else  if ( recv ) {
00262                 rx = new RecvPacketTransmissionTest();
00263                 rx->start();
00264                 rx->join();
00265         } else {
00266                 MiscTest m;
00267                 m.start();
00268                 m.join();
00269         }
00270         exit(result);
00271 }
00272 

Generated on Tue May 1 12:19:54 2007 for ccRTP by  doxygen 1.5.1