blob: e544ef9f13ba9ec0f21e210e7fe008fc0f42961e [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// test ccRTP functionality
2// Copyright (C) 2004 Federico Montesino Pouzols <fedemp@altern.org>
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#include <cstdlib>
18#include <ccrtp/rtp.h>
19
20#ifdef CCXX_NAMESPACES
21using namespace ost;
22using namespace std;
23#endif
24
25class PacketsPattern
26{
27public:
28 inline const InetHostAddress& getDestinationAddress() const
29 { return destinationAddress; }
30
31 inline const tpport_t getDestinationPort() const
32 { return destinationPort; }
33
34 uint32 getPacketsNumber() const
35 { return packetsNumber; }
36
37 const unsigned char* getPacketData(uint32 i)
38 { return data; }
39
40 const size_t getPacketSize(uint32 i)
41 { return packetsSize; }
42
43private:
44 static const InetHostAddress destinationAddress;
45 static const uint16 destinationPort = 34566;
46 static const uint32 packetsNumber = 100;
47 static const uint32 packetsSize = 100;
48 static unsigned char data[65535];
49};
50
51const InetHostAddress PacketsPattern::destinationAddress =
52 InetHostAddress("localhost");
53
54unsigned char PacketsPattern::data[65535];
55
56PacketsPattern pattern;
57
58class Test
59{
60public:
61 virtual int doTest() = 0;
62};
63
64class SendPacketTransmissionTest : public Test, public Thread, public TimerPort
65{
66public:
67 void run()
68 {
69 doTest();
70 }
71
72 int doTest()
73 {
74 // should be valid?
75 //RTPSession tx();
76 RTPSession tx(InetHostAddress("localhost"));
77 tx.setSchedulingTimeout(10000);
78 tx.setExpireTimeout(1000000);
79
80 tx.startRunning();
81
82 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
83 if ( !tx.addDestination(pattern.getDestinationAddress(),
84 pattern.getDestinationPort()) ) {
85 return 1;
86 }
87
88 // 50 packets per second (packet duration of 20ms)
89 uint32 period = 20;
90 uint16 inc = tx.getCurrentRTPClockRate()/50;
91 TimerPort::setTimer(period);
92 for ( uint32 i = 0; i < pattern.getPacketsNumber(); i++ ) {
93 tx.putData(i*inc, pattern.getPacketData(i), pattern.getPacketSize(i));
94 Thread::sleep(TimerPort::getTimer());
95 TimerPort::incTimer(period);
96 }
97 return 0;
98 }
99};
100
101class RecvPacketTransmissionTest : public Test, public Thread
102{
103public:
104 void run()
105 {
106 doTest();
107 }
108
109 int doTest()
110 {
111 RTPSession rx(pattern.getDestinationAddress(), pattern.getDestinationPort());
112
113 rx.setSchedulingTimeout(10000);
114 rx.setExpireTimeout(1000000);
115
116 rx.startRunning();
117 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
118 // arbitrary number of loops
119 for ( int i = 0; i < 500 ; i++ ) {
120 const AppDataUnit* adu;
121 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
122
123 delete adu;
124 }
125 Thread::sleep(7);
126 }
127 return 0;
128 }
129};
130
131class MiscTest : public Test, public Thread, public TimerPort
132{
133 void run()
134 {
135 doTest();
136 }
137
138 int doTest()
139 {
140 const uint32 NSESSIONS = 10;
141 RTPSession rx(pattern.getDestinationAddress(),pattern.getDestinationPort());
142 RTPSession **tx = new RTPSession* [NSESSIONS];
143 for ( uint32 i = 0; i < NSESSIONS; i++ ) {
144 tx[i] = new RTPSession(InetHostAddress("localhost"));
145 }
146 for ( uint32 i = 0; i < NSESSIONS; i++) {
147 tx[i]->setSchedulingTimeout(10000);
148 tx[i]->setExpireTimeout(1000000);
149 tx[i]->setPayloadFormat(StaticPayloadFormat(sptPCMU));
150 if ( !tx[i]->addDestination(pattern.getDestinationAddress(), pattern.getDestinationPort()) ) {
151 return 1;
152 }
153 }
154
155 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
156 rx.setSchedulingTimeout(5000);
157 rx.setExpireTimeout(10000000); // 10 seconds!
158 rx.startRunning();
159
160 for ( uint32 i = 0; i < NSESSIONS; i++) {
161 tx[i]->startRunning();
162 }
163 uint32 period = 20;
164 TimerPort::setTimer(period);
165 for ( uint32 i = 0; i < pattern.getPacketsNumber(); i++ ) {
166 if ( i == 70 ) {
167 RTPApplication &app = defaultApplication();
168 app.setSDESItem(SDESItemTypeCNAME,"foo@bar");
169 }
170 for ( uint32 s = 0; s < NSESSIONS; s++) {
171 // 50 packets per second (packet duration of 20ms)
172 uint16 inc =
173 tx[s]->getCurrentRTPClockRate()/50;
174 tx[s]->putData(i*inc, pattern.getPacketData(i), pattern.getPacketSize(i));
175 }
176 Thread::sleep(TimerPort::getTimer());
177 TimerPort::incTimer(period);
178 }
179
180 Thread::sleep(5000);
181 for ( uint32 i = 0; i < NSESSIONS; i++ ) {
182 delete tx[i];
183 }
184 RTPSession::SyncSourcesIterator it;
185 cout << "Sources of synchronization:" << endl;
186 for (it = rx.begin() ; it != rx.end(); it++) {
187 const SyncSource &s = *it;
188 cout << s.getID();
189 if ( s.isSender() )
190 cout << " (sender) ";
191 cout << s.getNetworkAddress() << ":" <<
192 s.getControlTransportPort() << "/" <<
193 s.getDataTransportPort();
194 Participant *p = s.getParticipant();
195 cout << " (" <<
196 p->getSDESItem(SDESItemTypeCNAME)
197 << ") " << endl;
198 }
199 RTPApplication &app = defaultApplication();
200 RTPApplication::ParticipantsIterator ai;
201 cout << "Participants:" << endl;
202 for ( ai = app.begin(); ai != app.end(); ai++ ) {
203 const Participant &p = *ai;
204 cout << p.getSDESItem(SDESItemTypeCNAME) << endl;
205 //cout << p.getPRIVPrefix();
206 }
207 delete tx;
208 return 0;
209 }
210};
211
212// class TestPacketHeaders { }
213// header extension
214
215// class TestRTCPTransmission { }
216
217// class TestMiscellaneous { }
218
219// Things that should be tested:
220// extreme values (0 - big) for putData
221// segmentation (setMaxSendSegmentSize())
222// performance: packets/second (depending on packet size and # of participants)
223int main(int argc, char *argv[])
224{
225 int result = 0;
226 bool send = false;
227 bool recv = false;
228
229 RecvPacketTransmissionTest *rx;
230 SendPacketTransmissionTest *tx;
231
232 // accept as parameter if must run as --send or --recv
233
234 // run several tests in parallel threads
235 if ( send ) {
236 tx = new SendPacketTransmissionTest();
237 tx->start();
238 tx->join();
239 } else if ( recv ) {
240 rx = new RecvPacketTransmissionTest();
241 rx->start();
242 rx->join();
243 } else {
244 MiscTest m;
245 m.start();
246 m.join();
247 }
248 exit(result);
249}
250
251/** EMACS **
252 * Local variables:
253 * mode: c++
254 * c-basic-offset: 4
255 * End:
256 */