blob: fc3490d66ae4e5ebceed1ed712a6cb0b02117372 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001// Test ZRTP extension for ccRTP
2//
3// Copyright (C) 2008 Werner Dittmann <Werner.Dittmann@t-online.de>
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
Alexandre Lisionddd731e2014-01-31 11:50:08 -050019#include <commoncpp/string.h>
20
21
Alexandre Lision51140e12013-12-02 10:54:09 -050022#include <cstdlib>
23#include <map>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050024#include <zrtpccrtp.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050025#include <libzrtpcpp/ZrtpUserCallback.h>
26
27using namespace ost;
28using namespace std;
29using namespace GnuZrtpCodes;
30
31class PacketsPattern
32{
33public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050034 inline const InetHostAddress&
35 getDestinationAddress() const
36 { return destinationAddress; }
Alexandre Lision51140e12013-12-02 10:54:09 -050037
Alexandre Lisionddd731e2014-01-31 11:50:08 -050038 inline const tpport_t
39 getDestinationPort() const
40 { return destinationPort; }
Alexandre Lision51140e12013-12-02 10:54:09 -050041
Alexandre Lisionddd731e2014-01-31 11:50:08 -050042 uint32
43 getPacketsNumber() const
44 { return packetsNumber; }
Alexandre Lision51140e12013-12-02 10:54:09 -050045
Alexandre Lisionddd731e2014-01-31 11:50:08 -050046 uint32
47 getSsrc() const
48 { return 0xdeadbeef; }
Alexandre Lision51140e12013-12-02 10:54:09 -050049
Alexandre Lisionddd731e2014-01-31 11:50:08 -050050 const unsigned char*
51 getPacketData(uint32 i)
52 { return data[i%2]; }
Alexandre Lision51140e12013-12-02 10:54:09 -050053
Alexandre Lisionddd731e2014-01-31 11:50:08 -050054 const size_t
55 getPacketSize(uint32 i)
56 { return strlen((char*)data[i%2]) + 1 ; }
Alexandre Lision51140e12013-12-02 10:54:09 -050057
58private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050059 static const InetHostAddress destinationAddress;
60 static const uint16 destinationPort = 5002;
Alexandre Lision51140e12013-12-02 10:54:09 -050061 static const uint32 packetsNumber = 10;
62 static const uint32 packetsSize = 12;
63 static const unsigned char* data[];
64};
65
Alexandre Lisionddd731e2014-01-31 11:50:08 -050066const InetHostAddress PacketsPattern::destinationAddress =
67 InetHostAddress("localhost");
Alexandre Lision51140e12013-12-02 10:54:09 -050068
69const unsigned char* PacketsPattern::data[] = {
70 (unsigned char*)"0123456789\n",
71 (unsigned char*)"987654321\n"
72};
73
74PacketsPattern pattern;
75
76class ExtZrtpSession : public SymmetricZRTPSession {
77// ExtZrtpSession(InetMcastAddress& ima, tpport_t port) :
78// RTPSession(ima,port) {}
Alexandre Lisionddd731e2014-01-31 11:50:08 -050079//
Alexandre Lision51140e12013-12-02 10:54:09 -050080// ExtZrtpSession(InetHostAddress& ia, tpport_t port) :
81// RTPSession(ia,port) {}
82
83public:
84 ExtZrtpSession(uint32 ssrc, const InetHostAddress& ia) :
85 SingleThreadRTPSession(ssrc, ia){
86 cout << "Extended" << endl;
87 }
88
89 ExtZrtpSession(uint32 ssrc, const InetHostAddress& ia, tpport_t dataPort) :
90 SingleThreadRTPSession(ssrc, ia, dataPort) {
91 cout << "Extended" << endl;
92 }
93
94 ExtZrtpSession(const InetHostAddress& ia, tpport_t dataPort) :
95 SingleThreadRTPSession(ia, dataPort) {
96 cout << "Extended" << endl;
97 }
98
99 void onGotGoodbye(const SyncSource& source, const std::string& reason)
100 {
101 cout << "I got a Goodbye packet from "
102 << hex << (int)source.getID() << "@"
103 << dec
104 << source.getNetworkAddress() << ":"
105 << source.getControlTransportPort() << endl;
106 cout << " Goodbye reason: \"" << reason << "\"" << endl;
107 }
108 // redefined from QueueRTCPManager
109 void onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks)
110 {
111 SingleThreadRTPSession::onGotRR(source,RR,blocks);
112 cout << "I got an RR RTCP report from "
113 << hex << (int)source.getID() << "@"
114 << dec
115 << source.getNetworkAddress() << ":"
116 << source.getControlTransportPort() << endl;
117 }
118};
119
120
121/**
122 * SymmetricZRTPSession in non-security mode (RTPSession compatible).
123 *
124 * The next two classes show how to use <code>SymmetricZRTPSession</code>
125 * in the same way as <code>RTPSession</code>. This is straightforward,
126 * just don't do any configuration or initialization.
127 */
128class SendPacketTransmissionTest: public Thread, public TimerPort {
129public:
130 void
131 run() {
132 doTest();
133 }
134
135 int doTest() {
136 // should be valid?
137 //RTPSession tx();
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500138 ExtZrtpSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
Alexandre Lision51140e12013-12-02 10:54:09 -0500139// SymmetricZRTPSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
140 tx.setSchedulingTimeout(10000);
141 tx.setExpireTimeout(1000000);
142
143 tx.startRunning();
144
145 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500146 if (!tx.addDestination(pattern.getDestinationAddress(),
147 pattern.getDestinationPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500148 return 1;
149 }
150
151 // 2 packets per second (packet duration of 500ms)
152 uint32 period = 500;
153 uint16 inc = tx.getCurrentRTPClockRate()/2;
154 TimerPort::setTimer(period);
155 uint32 i;
156 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
157 tx.putData(i*inc,
158 pattern.getPacketData(i),
159 pattern.getPacketSize(i));
160 cout << "Sent some data: " << i << endl;
161 Thread::sleep(TimerPort::getTimer());
162 TimerPort::incTimer(period);
163 }
164 tx.putData(i*inc, (unsigned char*)"exit", 5);
165 Thread::sleep(TimerPort::getTimer());
166 return 0;
167 }
168};
169
170
171class RecvPacketTransmissionTest: public Thread {
172public:
173 void
174 run() {
175 doTest();
176 }
177
178 int
179 doTest() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500180 ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
181 pattern.getDestinationPort());
Alexandre Lision51140e12013-12-02 10:54:09 -0500182
183// SymmetricZRTPSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
184// pattern.getDestinationPort());
185 rx.setSchedulingTimeout(10000);
186 rx.setExpireTimeout(1000000);
187
188 rx.startRunning();
189 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
190 // arbitrary number of loops to provide time to start transmitter
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500191 if (!rx.addDestination(pattern.getDestinationAddress(),
192 pattern.getDestinationPort()+2) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500193 return 1;
194 }
195 for ( int i = 0; i < 5000 ; i++ ) {
196 const AppDataUnit* adu;
197 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
198 cerr << "got some data: " << adu->getData() << endl;
199 if (*adu->getData() == 'e') {
200 delete adu;
201 return 0;
202 }
203 delete adu;
204 }
205 Thread::sleep(70);
206 }
207 return 0;
208 }
209};
210
211
212/**
213 * SymmetricZRTPSession in security mode.
214 *
215 * The next two classes show how to use <code>SymmetricZRTPSession</code>
216 * using the standard ZRTP handshake an switching to encrypted (SRTP) mode.
217 * The application enables this by calling <code>initialize(...)</code>.
218 * Some embedded logging informs about the ZRTP processing.
219 */
220
221class ZrtpSendPacketTransmissionTest: public Thread, public TimerPort {
222public:
223 void
224 run() {
225 doTest();
226 }
227
228 int doTest() {
229 // should be valid?
230 //RTPSession tx();
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500231 ExtZrtpSession tx(pattern.getSsrc(), pattern.getDestinationAddress(),
232 pattern.getDestinationPort()+2);
Alexandre Lision51140e12013-12-02 10:54:09 -0500233 tx.initialize("test_t.zid");
234
235 tx.setSchedulingTimeout(10000);
236 tx.setExpireTimeout(1000000);
237
238 tx.startRunning();
239
240 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500241 if (!tx.addDestination(pattern.getDestinationAddress(),
242 pattern.getDestinationPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500243 return 1;
244 }
245 tx.startZrtp();
246 // 2 packets per second (packet duration of 500ms)
247 uint32 period = 500;
248 uint16 inc = tx.getCurrentRTPClockRate()/2;
249 TimerPort::setTimer(period);
250 uint32 i;
251 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
252 tx.putData(i*inc,
253 pattern.getPacketData(i),
254 pattern.getPacketSize(i));
255 cout << "Sent some data: " << i << endl;
256 Thread::sleep(TimerPort::getTimer());
257 TimerPort::incTimer(period);
258 }
259 tx.putData(i*inc, (unsigned char*)"exit", 5);
260 Thread::sleep(200);
261 return 0;
262 }
263};
264
265class ZrtpRecvPacketTransmissionTest: public Thread {
266public:
267 void
268 run() {
269 doTest();
270 }
271
272 int
273 doTest() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500274 ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
275 pattern.getDestinationPort());
Alexandre Lision51140e12013-12-02 10:54:09 -0500276
277 rx.initialize("test_r.zid");
278
279 rx.setSchedulingTimeout(10000);
280 rx.setExpireTimeout(1000000);
281
282 rx.startRunning();
283 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
284 // arbitrary number of loops to provide time to start transmitter
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500285 if (!rx.addDestination(pattern.getDestinationAddress(),
286 pattern.getDestinationPort()+2) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500287 return 1;
288 }
289 rx.startZrtp();
290 for ( int i = 0; i < 5000 ; i++ ) {
291 const AppDataUnit* adu;
292 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
293 cerr << "got some data: " << adu->getData() << endl;
294 if (*adu->getData() == 'e') {
295 delete adu;
296 return 0;
297 }
298 delete adu;
299 }
300 Thread::sleep(70);
301 }
302 return 0;
303 }
304};
305
306/**
307 * Simple User Callback class
308 *
309 * This class overwrite some methods from ZrtpUserCallback to get information
310 * about ZRTP processing and information about ZRTP results. The standard
311 * implementation of this class just perform return, thus effectively
312 * supressing any callback or trigger.
313 */
314class MyUserCallback: public ZrtpUserCallback {
315
316 static map<int32, std::string*> infoMap;
317 static map<int32, std::string*> warningMap;
318 static map<int32, std::string*> severeMap;
319 static map<int32, std::string*> zrtpMap;
320
321 static bool initialized;
322
323 SymmetricZRTPSession* session;
324 public:
325 MyUserCallback(SymmetricZRTPSession* s) {
326 session = s;
327 if (initialized) {
328 return;
329 }
330 infoMap.insert(pair<int32, std::string*>(InfoHelloReceived, new string("Hello received, preparing a Commit")));
331 infoMap.insert(pair<int32, std::string*>(InfoCommitDHGenerated, new string("Commit: Generated a public DH key")));
332 infoMap.insert(pair<int32, std::string*>(InfoRespCommitReceived, new string("Responder: Commit received, preparing DHPart1")));
333 infoMap.insert(pair<int32, std::string*>(InfoDH1DHGenerated, new string("DH1Part: Generated a public DH key")));
334 infoMap.insert(pair<int32, std::string*>(InfoInitDH1Received, new string("Initiator: DHPart1 received, preparing DHPart2")));
335 infoMap.insert(pair<int32, std::string*>(InfoRespDH2Received, new string("Responder: DHPart2 received, preparing Confirm1")));
336 infoMap.insert(pair<int32, std::string*>(InfoInitConf1Received, new string("Initiator: Confirm1 received, preparing Confirm2")));
337 infoMap.insert(pair<int32, std::string*>(InfoRespConf2Received, new string("Responder: Confirm2 received, preparing Conf2Ack")));
338 infoMap.insert(pair<int32, std::string*>(InfoRSMatchFound, new string("At least one retained secrets matches - security OK")));
339 infoMap.insert(pair<int32, std::string*>(InfoSecureStateOn, new string("Entered secure state")));
340 infoMap.insert(pair<int32, std::string*>(InfoSecureStateOff, new string("No more security for this session")));
341
342 warningMap.insert(pair<int32, std::string*>(WarningDHAESmismatch,
343 new string("Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096")));
344 warningMap.insert(pair<int32, std::string*>(WarningGoClearReceived, new string("Received a GoClear message")));
345 warningMap.insert(pair<int32, std::string*>(WarningDHShort,
346 new string("Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096")));
347 warningMap.insert(pair<int32, std::string*>(WarningNoRSMatch, new string("No retained secret matches - verify SAS")));
348 warningMap.insert(pair<int32, std::string*>(WarningCRCmismatch, new string("Internal ZRTP packet checksum mismatch - packet dropped")));
349 warningMap.insert(pair<int32, std::string*>(WarningSRTPauthError, new string("Dropping packet because SRTP authentication failed!")));
350 warningMap.insert(pair<int32, std::string*>(WarningSRTPreplayError, new string("Dropping packet because SRTP replay check failed!")));
351
352 severeMap.insert(pair<int32, std::string*>(SevereHelloHMACFailed, new string("Hash HMAC check of Hello failed!")));
353 severeMap.insert(pair<int32, std::string*>(SevereCommitHMACFailed, new string("Hash HMAC check of Commit failed!")));
354 severeMap.insert(pair<int32, std::string*>(SevereDH1HMACFailed, new string("Hash HMAC check of DHPart1 failed!")));
355 severeMap.insert(pair<int32, std::string*>(SevereDH2HMACFailed, new string("Hash HMAC check of DHPart2 failed!")));
356 severeMap.insert(pair<int32, std::string*>(SevereCannotSend, new string("Cannot send data - connection or peer down?")));
357 severeMap.insert(pair<int32, std::string*>(SevereProtocolError, new string("Internal protocol error occured!")));
358 severeMap.insert(pair<int32, std::string*>(SevereNoTimer, new string("Cannot start a timer - internal resources exhausted?")));
359 severeMap.insert(pair<int32, std::string*>(SevereTooMuchRetries,
360 new string("Too much retries during ZRTP negotiation - connection or peer down?")));
361
362 zrtpMap.insert(pair<int32, std::string*>(MalformedPacket, new string("Malformed packet (CRC OK, but wrong structure)")));
363 zrtpMap.insert(pair<int32, std::string*>(CriticalSWError, new string("Critical software error")));
364 zrtpMap.insert(pair<int32, std::string*>(UnsuppZRTPVersion, new string("Unsupported ZRTP version")));
365 zrtpMap.insert(pair<int32, std::string*>(HelloCompMismatch, new string("Hello components mismatch")));
366 zrtpMap.insert(pair<int32, std::string*>(UnsuppHashType, new string("Hash type not supported")));
367 zrtpMap.insert(pair<int32, std::string*>(UnsuppCiphertype, new string("Cipher type not supported")));
368 zrtpMap.insert(pair<int32, std::string*>(UnsuppPKExchange, new string("Public key exchange not supported")));
369 zrtpMap.insert(pair<int32, std::string*>(UnsuppSRTPAuthTag, new string("SRTP auth. tag not supported")));
370 zrtpMap.insert(pair<int32, std::string*>(UnsuppSASScheme, new string("SAS scheme not supported")));
371 zrtpMap.insert(pair<int32, std::string*>(NoSharedSecret, new string("No shared secret available, DH mode required")));
372 zrtpMap.insert(pair<int32, std::string*>(DHErrorWrongPV, new string("DH Error: bad pvi or pvr ( == 1, 0, or p-1)")));
373 zrtpMap.insert(pair<int32, std::string*>(DHErrorWrongHVI, new string("DH Error: hvi != hashed data")));
374 zrtpMap.insert(pair<int32, std::string*>(SASuntrustedMiTM, new string("Received relayed SAS from untrusted MiTM")));
375 zrtpMap.insert(pair<int32, std::string*>(ConfirmHMACWrong, new string("Auth. Error: Bad Confirm pkt HMAC")));
376 zrtpMap.insert(pair<int32, std::string*>(NonceReused, new string("Nonce reuse")));
377 zrtpMap.insert(pair<int32, std::string*>(EqualZIDHello, new string("Equal ZIDs in Hello")));
378 zrtpMap.insert(pair<int32, std::string*>(GoCleatNotAllowed, new string("GoClear packet received, but not allowed")));
379
380 initialized = true;
381 }
382
383 void showMessage(GnuZrtpCodes::MessageSeverity sev, int32_t subCode) {
384 string* msg;
385 if (sev == Info) {
386 msg = infoMap[subCode];
387 if (msg != NULL) {
388 cout << *msg << endl;
389 }
390 }
391 if (sev == Warning) {
392 msg = warningMap[subCode];
393 if (msg != NULL) {
394 cout << *msg << endl;
395 }
396 }
397 if (sev == Severe) {
398 msg = severeMap[subCode];
399 if (msg != NULL) {
400 cout << *msg << endl;
401 }
402 }
403 if (sev == ZrtpError) {
404 if (subCode < 0) { // received an error packet from peer
405 subCode *= -1;
406 cout << "Received error packet: ";
407 }
408 else {
409 cout << "Sent error packet: ";
410 }
411 msg = zrtpMap[subCode];
412 if (msg != NULL) {
413 cout << *msg << endl;
414 }
415 }
416 }
417
418 void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity sev, int32_t subCode) {
419 string* msg;
420 if (sev == ZrtpError) {
421 if (subCode < 0) { // received an error packet from peer
422 subCode *= -1;
423 cout << "Received error packet: ";
424 }
425 else {
426 cout << "Sent error packet: ";
427 }
428 msg = zrtpMap[subCode];
429 if (msg != NULL) {
430 cout << *msg << endl;
431 }
432 }
433 else {
434 msg = severeMap[subCode];
435 cout << *msg << endl;
436 }
437 }
438
439 void secureOn(std::string cipher) {
440 cout << "Using cipher:" << cipher << endl;
441 }
442
443 void showSAS(std::string sas, bool verified) {
444 cout << "SAS is: " << sas << endl;
445
446 }
447};
448
449map<int32, std::string*>MyUserCallback::infoMap;
450map<int32, std::string*>MyUserCallback::warningMap;
451map<int32, std::string*>MyUserCallback::severeMap;
452map<int32, std::string*>MyUserCallback::zrtpMap;
453
454bool MyUserCallback::initialized = false;
455
456/**
457 * SymmetricZRTPSession in security mode and using a callback class.
458 *
459 * The next two classes show how to use <code>SymmetricZRTPSession</code>
460 * using the standard ZRTP handshake an switching to encrypted (SRTP) mode.
461 * The application enables this by calling <code>initialize(...)</code>.
462 * In addition the application sets a callback class (see above). ZRTP calls
463 * the methods of the callback class and the application may implement
464 * appropriate methods to deal with these triggers.
465 */
466
467class
468ZrtpSendPacketTransmissionTestCB : public Thread, public TimerPort
469{
470public:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500471
472 ZrtpConfigure config;
473
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500474 void run()
475 {
Alexandre Lision51140e12013-12-02 10:54:09 -0500476 doTest();
477 }
478
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500479 int doTest()
480 {
Alexandre Lision51140e12013-12-02 10:54:09 -0500481 // should be valid?
482 //RTPSession tx();
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500483 ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getDestinationAddress(),
484 pattern.getDestinationPort()+2);
485// config.clear();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500486// config.setStandardConfig();
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500487 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500488 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500489 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500490
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500491 config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500492
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500493// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
494// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500495
496 config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
497
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500498 tx.initialize("test_t.zid", true, &config);
Alexandre Lision51140e12013-12-02 10:54:09 -0500499 // At this point the Hello hash is available. See ZRTP specification
500 // chapter 9.1 for further information when an how to use the Hello
501 // hash.
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500502 cout << "TX Hello hash: " << tx.getHelloHash() << endl;
503 cout << "TX Hello hash length: " << tx.getHelloHash().length() << endl;
504
Alexandre Lision51140e12013-12-02 10:54:09 -0500505 tx.setUserCallback(new MyUserCallback(&tx));
506
507 tx.setSchedulingTimeout(10000);
508 tx.setExpireTimeout(1000000);
509
510 tx.startRunning();
511
512 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500513 if (!tx.addDestination(pattern.getDestinationAddress(),
514 pattern.getDestinationPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500515 return 1;
516 }
517 tx.startZrtp();
518
519 // 2 packets per second (packet duration of 500ms)
520 uint32 period = 500;
521 uint16 inc = tx.getCurrentRTPClockRate()/2;
522 TimerPort::setTimer(period);
523 uint32 i;
524 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
525 tx.putData(i*inc,
526 pattern.getPacketData(i),
527 pattern.getPacketSize(i));
528 cout << "Sent some data: " << i << endl;
529 Thread::sleep(TimerPort::getTimer());
530 TimerPort::incTimer(period);
531 }
532 tx.putData(i*inc, (unsigned char*)"exit", 5);
533 Thread::sleep(TimerPort::getTimer());
534 return 0;
535 }
536};
537
538
539class
540ZrtpRecvPacketTransmissionTestCB: public Thread
541{
542public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500543 void
544 run() {
Alexandre Lision51140e12013-12-02 10:54:09 -0500545 doTest();
546 }
547
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500548 int
549 doTest() {
550 ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getDestinationAddress(),
551 pattern.getDestinationPort());
Alexandre Lision51140e12013-12-02 10:54:09 -0500552
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500553 rx.initialize("test_r.zid");
Alexandre Lision51140e12013-12-02 10:54:09 -0500554 // At this point the Hello hash is available. See ZRTP specification
555 // chapter 9.1 for further information when an how to use the Hello
556 // hash.
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500557 cout << "RX Hello hash: " << rx.getHelloHash() << endl;
558 cout << "RX Hello hash length: " << rx.getHelloHash().length() << endl;
559
Alexandre Lision51140e12013-12-02 10:54:09 -0500560 rx.setUserCallback(new MyUserCallback(&rx));
561
562 rx.setSchedulingTimeout(10000);
563 rx.setExpireTimeout(1000000);
564
565 rx.startRunning();
566 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
567 // arbitrary number of loops to provide time to start transmitter
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500568 if (!rx.addDestination(pattern.getDestinationAddress(),
569 pattern.getDestinationPort()+2) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500570 return 1;
571 }
572 rx.startZrtp();
573
574 for ( int i = 0; i < 5000 ; i++ ) {
575 const AppDataUnit* adu;
576 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
577 cerr << "got some data: " << adu->getData() << endl;
578 if (*adu->getData() == 'e') {
579 delete adu;
580 return 0;
581 }
582 delete adu;
583 }
584 Thread::sleep(500);
585 }
586 return 0;
587 }
588};
589
590
591int main(int argc, char *argv[])
592{
593 int result = 0;
594 bool send = false;
595 bool recv = false;
596
597 char c;
598
599 /* check args */
600 while (1) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500601 c = getopt(argc, argv, "rs");
Alexandre Lision51140e12013-12-02 10:54:09 -0500602 if (c == -1) {
603 break;
604 }
605 switch (c) {
606 case 'r':
607 recv = true;
608 break;
609 case 's':
610 send = true;
611 break;
Alexandre Lision51140e12013-12-02 10:54:09 -0500612 default:
613 cerr << "Wrong Arguments, only -s and -r are accepted" << endl;
614 }
615 }
616
617 if (send || recv) {
618 if (send) {
619 cout << "Running as sender" << endl;
620 }
621 else {
622 cout << "Running as receiver" << endl;
623 }
624 }
625 else {
626 cerr << "No send or receive argument specificied" << endl;
627 exit(1);
628 }
629
630 // accept as parameter if must run as --send or --recv
631
632#if 0
633 RecvPacketTransmissionTest *rx;
634 SendPacketTransmissionTest *tx;
635
636 // run several tests in parallel threads
637 if ( send ) {
638 tx = new SendPacketTransmissionTest();
639 tx->start();
640 tx->join();
641 } else if ( recv ) {
642 rx = new RecvPacketTransmissionTest();
643 rx->start();
644 rx->join();
645 }
646//#endif
647//#if 0
648 ZrtpRecvPacketTransmissionTest *zrx;
649 ZrtpSendPacketTransmissionTest *ztx;
650
651 if ( send ) {
652 ztx = new ZrtpSendPacketTransmissionTest();
653 ztx->start();
654 ztx->join();
655 } else if ( recv ) {
656 zrx = new ZrtpRecvPacketTransmissionTest();
657 zrx->start();
658 zrx->join();
659 }
660#endif
661 ZrtpRecvPacketTransmissionTestCB *zrxcb;
662 ZrtpSendPacketTransmissionTestCB *ztxcb;
663
664 if ( send ) {
665 ztxcb = new ZrtpSendPacketTransmissionTestCB();
666 ztxcb->start();
667 ztxcb->join();
668 } else if ( recv ) {
669 zrxcb = new ZrtpRecvPacketTransmissionTestCB();
670 zrxcb->start();
671 zrxcb->join();
672 }
673
674 exit(result);
675}
676
677/** EMACS **
678 * Local variables:
679 * mode: c++
680 * c-default-style: ellemtel
681 * c-basic-offset: 4
682 * End:
683 */