blob: 0595543f06116c2d1219c37803fdb3759ffb8dbf [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
19#include <cstdlib>
20#include <map>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050021#include <zrtpccrtp.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050022#include <libzrtpcpp/ZrtpUserCallback.h>
23
24using namespace ost;
25using namespace std;
26using namespace GnuZrtpCodes;
27
28class PacketsPattern
29{
30public:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050031 inline const InetHostAddress& getReceiverAddress() const { return *receiverAddress; }
32 inline const InetHostAddress& getSenderAddress() const { return *senderAddress; }
Alexandre Lision51140e12013-12-02 10:54:09 -050033
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050034 inline void setReceiverAddress(InetHostAddress *addr) const { delete receiverAddress; receiverAddress = addr; }
35 inline void setSenderAddress(InetHostAddress *addr) const { delete senderAddress; senderAddress = addr; }
Alexandre Lision51140e12013-12-02 10:54:09 -050036
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050037 inline const tpport_t getReceiverPort() const { return receiverPort; }
38 inline const tpport_t getSenderPort() const { return senderPort; }
Alexandre Lision51140e12013-12-02 10:54:09 -050039
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050040 uint32 getPacketsNumber() const { return packetsNumber; }
Alexandre Lision51140e12013-12-02 10:54:09 -050041
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050042 uint32 getSsrc() const { return 0xdeadbeef; }
Alexandre Lision51140e12013-12-02 10:54:09 -050043
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050044 const unsigned char*getPacketData(uint32 i) { return data[i%2]; }
45
46 const size_t getPacketSize(uint32 i) { return strlen((char*)data[i%2]) + 1 ; }
Alexandre Lision51140e12013-12-02 10:54:09 -050047
48private:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050049 static const InetHostAddress *receiverAddress;
50 static const InetHostAddress *senderAddress;
51
52 static const uint16 receiverPort = 5002;
53 static const uint16 senderPort = 5004;
Alexandre Lision51140e12013-12-02 10:54:09 -050054 static const uint32 packetsNumber = 10;
55 static const uint32 packetsSize = 12;
56 static const unsigned char* data[];
57};
58
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050059const InetHostAddress *PacketsPattern::receiverAddress = new InetHostAddress("localhost");
60const InetHostAddress *PacketsPattern::senderAddress = new InetHostAddress("localhost");
Alexandre Lision51140e12013-12-02 10:54:09 -050061
62const unsigned char* PacketsPattern::data[] = {
63 (unsigned char*)"0123456789\n",
64 (unsigned char*)"987654321\n"
65};
66
67PacketsPattern pattern;
68
69class ExtZrtpSession : public SymmetricZRTPSession {
70// ExtZrtpSession(InetMcastAddress& ima, tpport_t port) :
71// RTPSession(ima,port) {}
72//
73// ExtZrtpSession(InetHostAddress& ia, tpport_t port) :
74// RTPSession(ia,port) {}
75
76public:
77 ExtZrtpSession(uint32 ssrc, const InetHostAddress& ia) :
78 SingleThreadRTPSession(ssrc, ia){
79 cout << "Extended" << endl;
80 }
81
82 ExtZrtpSession(uint32 ssrc, const InetHostAddress& ia, tpport_t dataPort) :
83 SingleThreadRTPSession(ssrc, ia, dataPort) {
84 cout << "Extended" << endl;
85 }
86
87 ExtZrtpSession(const InetHostAddress& ia, tpport_t dataPort) :
88 SingleThreadRTPSession(ia, dataPort) {
89 cout << "Extended" << endl;
90 }
91
92 void onGotGoodbye(const SyncSource& source, const std::string& reason)
93 {
94 cout << "I got a Goodbye packet from "
95 << hex << (int)source.getID() << "@"
96 << dec
97 << source.getNetworkAddress() << ":"
98 << source.getControlTransportPort() << endl;
99 cout << " Goodbye reason: \"" << reason << "\"" << endl;
100 }
101 // redefined from QueueRTCPManager
102 void onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks)
103 {
104 SingleThreadRTPSession::onGotRR(source,RR,blocks);
105 cout << "I got an RR RTCP report from "
106 << hex << (int)source.getID() << "@"
107 << dec
108 << source.getNetworkAddress() << ":"
109 << source.getControlTransportPort() << endl;
110 }
111};
112
113
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500114/*
115 * The following classes use:
116 * - localAddress and destination port+2 for the sender classes
117 * - destinationAddress and destination port for the receiver classes.
118 *
119 */
120
Alexandre Lision51140e12013-12-02 10:54:09 -0500121/**
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 Lision7fd5d3d2013-12-04 13:06:40 -0500138 ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
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 Lision7fd5d3d2013-12-04 13:06:40 -0500146
147 // We are sender:
148 if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500149 return 1;
150 }
151
152 // 2 packets per second (packet duration of 500ms)
153 uint32 period = 500;
154 uint16 inc = tx.getCurrentRTPClockRate()/2;
155 TimerPort::setTimer(period);
156 uint32 i;
157 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
158 tx.putData(i*inc,
159 pattern.getPacketData(i),
160 pattern.getPacketSize(i));
161 cout << "Sent some data: " << i << endl;
162 Thread::sleep(TimerPort::getTimer());
163 TimerPort::incTimer(period);
164 }
165 tx.putData(i*inc, (unsigned char*)"exit", 5);
166 Thread::sleep(TimerPort::getTimer());
167 return 0;
168 }
169};
170
171
172class RecvPacketTransmissionTest: public Thread {
173public:
174 void
175 run() {
176 doTest();
177 }
178
179 int
180 doTest() {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500181 ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
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 Lision7fd5d3d2013-12-04 13:06:40 -0500191 if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500192 return 1;
193 }
194 for ( int i = 0; i < 5000 ; i++ ) {
195 const AppDataUnit* adu;
196 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
197 cerr << "got some data: " << adu->getData() << endl;
198 if (*adu->getData() == 'e') {
199 delete adu;
200 return 0;
201 }
202 delete adu;
203 }
204 Thread::sleep(70);
205 }
206 return 0;
207 }
208};
209
210
211/**
212 * SymmetricZRTPSession in security mode.
213 *
214 * The next two classes show how to use <code>SymmetricZRTPSession</code>
215 * using the standard ZRTP handshake an switching to encrypted (SRTP) mode.
216 * The application enables this by calling <code>initialize(...)</code>.
217 * Some embedded logging informs about the ZRTP processing.
218 */
219
220class ZrtpSendPacketTransmissionTest: public Thread, public TimerPort {
221public:
222 void
223 run() {
224 doTest();
225 }
226
227 int doTest() {
228 // should be valid?
229 //RTPSession tx();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500230 // Initialize with local address and Local port is detination port +2 - keep RTP/RTCP port pairs
231 ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
Alexandre Lision51140e12013-12-02 10:54:09 -0500232 tx.initialize("test_t.zid");
233
234 tx.setSchedulingTimeout(10000);
235 tx.setExpireTimeout(1000000);
236
237 tx.startRunning();
238
239 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500240 if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500241 return 1;
242 }
243 tx.startZrtp();
244 // 2 packets per second (packet duration of 500ms)
245 uint32 period = 500;
246 uint16 inc = tx.getCurrentRTPClockRate()/2;
247 TimerPort::setTimer(period);
248 uint32 i;
249 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
250 tx.putData(i*inc,
251 pattern.getPacketData(i),
252 pattern.getPacketSize(i));
253 cout << "Sent some data: " << i << endl;
254 Thread::sleep(TimerPort::getTimer());
255 TimerPort::incTimer(period);
256 }
257 tx.putData(i*inc, (unsigned char*)"exit", 5);
258 Thread::sleep(200);
259 return 0;
260 }
261};
262
263class ZrtpRecvPacketTransmissionTest: public Thread {
264public:
265 void
266 run() {
267 doTest();
268 }
269
270 int
271 doTest() {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500272 ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
Alexandre Lision51140e12013-12-02 10:54:09 -0500273
274 rx.initialize("test_r.zid");
275
276 rx.setSchedulingTimeout(10000);
277 rx.setExpireTimeout(1000000);
278
279 rx.startRunning();
280 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
281 // arbitrary number of loops to provide time to start transmitter
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500282 if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500283 return 1;
284 }
285 rx.startZrtp();
286 for ( int i = 0; i < 5000 ; i++ ) {
287 const AppDataUnit* adu;
288 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
289 cerr << "got some data: " << adu->getData() << endl;
290 if (*adu->getData() == 'e') {
291 delete adu;
292 return 0;
293 }
294 delete adu;
295 }
296 Thread::sleep(70);
297 }
298 return 0;
299 }
300};
301
302/**
303 * Simple User Callback class
304 *
305 * This class overwrite some methods from ZrtpUserCallback to get information
306 * about ZRTP processing and information about ZRTP results. The standard
307 * implementation of this class just perform return, thus effectively
308 * supressing any callback or trigger.
309 */
310class MyUserCallback: public ZrtpUserCallback {
311
312 static map<int32, std::string*> infoMap;
313 static map<int32, std::string*> warningMap;
314 static map<int32, std::string*> severeMap;
315 static map<int32, std::string*> zrtpMap;
316
317 static bool initialized;
318
319 SymmetricZRTPSession* session;
320 public:
321 MyUserCallback(SymmetricZRTPSession* s) {
322 session = s;
323 if (initialized) {
324 return;
325 }
326 infoMap.insert(pair<int32, std::string*>(InfoHelloReceived, new string("Hello received, preparing a Commit")));
327 infoMap.insert(pair<int32, std::string*>(InfoCommitDHGenerated, new string("Commit: Generated a public DH key")));
328 infoMap.insert(pair<int32, std::string*>(InfoRespCommitReceived, new string("Responder: Commit received, preparing DHPart1")));
329 infoMap.insert(pair<int32, std::string*>(InfoDH1DHGenerated, new string("DH1Part: Generated a public DH key")));
330 infoMap.insert(pair<int32, std::string*>(InfoInitDH1Received, new string("Initiator: DHPart1 received, preparing DHPart2")));
331 infoMap.insert(pair<int32, std::string*>(InfoRespDH2Received, new string("Responder: DHPart2 received, preparing Confirm1")));
332 infoMap.insert(pair<int32, std::string*>(InfoInitConf1Received, new string("Initiator: Confirm1 received, preparing Confirm2")));
333 infoMap.insert(pair<int32, std::string*>(InfoRespConf2Received, new string("Responder: Confirm2 received, preparing Conf2Ack")));
334 infoMap.insert(pair<int32, std::string*>(InfoRSMatchFound, new string("At least one retained secrets matches - security OK")));
335 infoMap.insert(pair<int32, std::string*>(InfoSecureStateOn, new string("Entered secure state")));
336 infoMap.insert(pair<int32, std::string*>(InfoSecureStateOff, new string("No more security for this session")));
337
338 warningMap.insert(pair<int32, std::string*>(WarningDHAESmismatch,
339 new string("Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096")));
340 warningMap.insert(pair<int32, std::string*>(WarningGoClearReceived, new string("Received a GoClear message")));
341 warningMap.insert(pair<int32, std::string*>(WarningDHShort,
342 new string("Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096")));
343 warningMap.insert(pair<int32, std::string*>(WarningNoRSMatch, new string("No retained secret matches - verify SAS")));
344 warningMap.insert(pair<int32, std::string*>(WarningCRCmismatch, new string("Internal ZRTP packet checksum mismatch - packet dropped")));
345 warningMap.insert(pair<int32, std::string*>(WarningSRTPauthError, new string("Dropping packet because SRTP authentication failed!")));
346 warningMap.insert(pair<int32, std::string*>(WarningSRTPreplayError, new string("Dropping packet because SRTP replay check failed!")));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500347 warningMap.insert(pair<int32, std::string*>(WarningNoExpectedRSMatch, new string("No RS match found - but ZRTP expected a match.")));
348 warningMap.insert(pair<int32, std::string*>(WarningNoExpectedAuxMatch, new string("The auxlliary secrets do not match.")));
Alexandre Lision51140e12013-12-02 10:54:09 -0500349
350 severeMap.insert(pair<int32, std::string*>(SevereHelloHMACFailed, new string("Hash HMAC check of Hello failed!")));
351 severeMap.insert(pair<int32, std::string*>(SevereCommitHMACFailed, new string("Hash HMAC check of Commit failed!")));
352 severeMap.insert(pair<int32, std::string*>(SevereDH1HMACFailed, new string("Hash HMAC check of DHPart1 failed!")));
353 severeMap.insert(pair<int32, std::string*>(SevereDH2HMACFailed, new string("Hash HMAC check of DHPart2 failed!")));
354 severeMap.insert(pair<int32, std::string*>(SevereCannotSend, new string("Cannot send data - connection or peer down?")));
355 severeMap.insert(pair<int32, std::string*>(SevereProtocolError, new string("Internal protocol error occured!")));
356 severeMap.insert(pair<int32, std::string*>(SevereNoTimer, new string("Cannot start a timer - internal resources exhausted?")));
357 severeMap.insert(pair<int32, std::string*>(SevereTooMuchRetries,
358 new string("Too much retries during ZRTP negotiation - connection or peer down?")));
359
360 zrtpMap.insert(pair<int32, std::string*>(MalformedPacket, new string("Malformed packet (CRC OK, but wrong structure)")));
361 zrtpMap.insert(pair<int32, std::string*>(CriticalSWError, new string("Critical software error")));
362 zrtpMap.insert(pair<int32, std::string*>(UnsuppZRTPVersion, new string("Unsupported ZRTP version")));
363 zrtpMap.insert(pair<int32, std::string*>(HelloCompMismatch, new string("Hello components mismatch")));
364 zrtpMap.insert(pair<int32, std::string*>(UnsuppHashType, new string("Hash type not supported")));
365 zrtpMap.insert(pair<int32, std::string*>(UnsuppCiphertype, new string("Cipher type not supported")));
366 zrtpMap.insert(pair<int32, std::string*>(UnsuppPKExchange, new string("Public key exchange not supported")));
367 zrtpMap.insert(pair<int32, std::string*>(UnsuppSRTPAuthTag, new string("SRTP auth. tag not supported")));
368 zrtpMap.insert(pair<int32, std::string*>(UnsuppSASScheme, new string("SAS scheme not supported")));
369 zrtpMap.insert(pair<int32, std::string*>(NoSharedSecret, new string("No shared secret available, DH mode required")));
370 zrtpMap.insert(pair<int32, std::string*>(DHErrorWrongPV, new string("DH Error: bad pvi or pvr ( == 1, 0, or p-1)")));
371 zrtpMap.insert(pair<int32, std::string*>(DHErrorWrongHVI, new string("DH Error: hvi != hashed data")));
372 zrtpMap.insert(pair<int32, std::string*>(SASuntrustedMiTM, new string("Received relayed SAS from untrusted MiTM")));
373 zrtpMap.insert(pair<int32, std::string*>(ConfirmHMACWrong, new string("Auth. Error: Bad Confirm pkt HMAC")));
374 zrtpMap.insert(pair<int32, std::string*>(NonceReused, new string("Nonce reuse")));
375 zrtpMap.insert(pair<int32, std::string*>(EqualZIDHello, new string("Equal ZIDs in Hello")));
376 zrtpMap.insert(pair<int32, std::string*>(GoCleatNotAllowed, new string("GoClear packet received, but not allowed")));
377
378 initialized = true;
379 }
380
381 void showMessage(GnuZrtpCodes::MessageSeverity sev, int32_t subCode) {
382 string* msg;
383 if (sev == Info) {
384 msg = infoMap[subCode];
385 if (msg != NULL) {
386 cout << *msg << endl;
387 }
388 }
389 if (sev == Warning) {
390 msg = warningMap[subCode];
391 if (msg != NULL) {
392 cout << *msg << endl;
393 }
394 }
395 if (sev == Severe) {
396 msg = severeMap[subCode];
397 if (msg != NULL) {
398 cout << *msg << endl;
399 }
400 }
401 if (sev == ZrtpError) {
402 if (subCode < 0) { // received an error packet from peer
403 subCode *= -1;
404 cout << "Received error packet: ";
405 }
406 else {
407 cout << "Sent error packet: ";
408 }
409 msg = zrtpMap[subCode];
410 if (msg != NULL) {
411 cout << *msg << endl;
412 }
413 }
414 }
415
416 void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity sev, int32_t subCode) {
417 string* msg;
418 if (sev == ZrtpError) {
419 if (subCode < 0) { // received an error packet from peer
420 subCode *= -1;
421 cout << "Received error packet: ";
422 }
423 else {
424 cout << "Sent error packet: ";
425 }
426 msg = zrtpMap[subCode];
427 if (msg != NULL) {
428 cout << *msg << endl;
429 }
430 }
431 else {
432 msg = severeMap[subCode];
433 cout << *msg << endl;
434 }
435 }
436
437 void secureOn(std::string cipher) {
438 cout << "Using cipher:" << cipher << endl;
439 }
440
441 void showSAS(std::string sas, bool verified) {
442 cout << "SAS is: " << sas << endl;
443
444 }
445};
446
447map<int32, std::string*>MyUserCallback::infoMap;
448map<int32, std::string*>MyUserCallback::warningMap;
449map<int32, std::string*>MyUserCallback::severeMap;
450map<int32, std::string*>MyUserCallback::zrtpMap;
451
452bool MyUserCallback::initialized = false;
453
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500454static unsigned char transmAuxSecret[] = {1,2,3,4,5,6,7,8,9,0};
455
Alexandre Lision51140e12013-12-02 10:54:09 -0500456/**
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
474 void run() {
Alexandre Lision51140e12013-12-02 10:54:09 -0500475 doTest();
476 }
477
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500478 int doTest() {
Alexandre Lision51140e12013-12-02 10:54:09 -0500479 // should be valid?
480 //RTPSession tx();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500481 ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getSenderAddress(), pattern.getSenderPort());
482 config.clear();
483// config.setStandardConfig();
484// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
485// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
486
487 // This ordering prefers NIST
488 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
489 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
490
491 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
492 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
493
494 config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
495 config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
496
497 config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
498 config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
499
500 config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
501
502 config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
503 config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
504 config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
505 config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
506
507 tx.initialize("test_t.zid", true, &config);
Alexandre Lision51140e12013-12-02 10:54:09 -0500508 // At this point the Hello hash is available. See ZRTP specification
509 // chapter 9.1 for further information when an how to use the Hello
510 // hash.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500511 int numSupportedVersion = tx.getNumberSupportedVersions();
512 cout << "TX Hello hash 0: " << tx.getHelloHash(0) << endl;
513 cout << "TX Hello hash 0 length: " << tx.getHelloHash(0).length() << endl;
514 if (numSupportedVersion > 1) {
515 cout << "TX Hello hash 1: " << tx.getHelloHash(1) << endl;
516 cout << "TX Hello hash 1 length: " << tx.getHelloHash(1).length() << endl;
517 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500518 tx.setUserCallback(new MyUserCallback(&tx));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500519 tx.setAuxSecret(transmAuxSecret, sizeof(transmAuxSecret));
Alexandre Lision51140e12013-12-02 10:54:09 -0500520
521 tx.setSchedulingTimeout(10000);
522 tx.setExpireTimeout(1000000);
523
524 tx.startRunning();
525
526 tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500527
528 if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500529 return 1;
530 }
531 tx.startZrtp();
532
533 // 2 packets per second (packet duration of 500ms)
534 uint32 period = 500;
535 uint16 inc = tx.getCurrentRTPClockRate()/2;
536 TimerPort::setTimer(period);
537 uint32 i;
538 for (i = 0; i < pattern.getPacketsNumber(); i++ ) {
539 tx.putData(i*inc,
540 pattern.getPacketData(i),
541 pattern.getPacketSize(i));
542 cout << "Sent some data: " << i << endl;
543 Thread::sleep(TimerPort::getTimer());
544 TimerPort::incTimer(period);
545 }
546 tx.putData(i*inc, (unsigned char*)"exit", 5);
547 Thread::sleep(TimerPort::getTimer());
548 return 0;
549 }
550};
551
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500552static unsigned char recvAuxSecret[] = {1,2,3,4,5,6,7,8,9,9};
Alexandre Lision51140e12013-12-02 10:54:09 -0500553
554class
555ZrtpRecvPacketTransmissionTestCB: public Thread
556{
557public:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500558 ZrtpConfigure config;
559
560 void run() {
Alexandre Lision51140e12013-12-02 10:54:09 -0500561 doTest();
562 }
563
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500564 int doTest() {
565 ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getReceiverAddress(), pattern.getReceiverPort());
566 config.clear();
567// config.setStandardConfig();
568// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
Alexandre Lision51140e12013-12-02 10:54:09 -0500569
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500570 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
571 config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
572
573 config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
574 config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
575
576// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
577// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
578
579 config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
580
581
582 rx.initialize("test_r.zid", true, &config);
Alexandre Lision51140e12013-12-02 10:54:09 -0500583 // At this point the Hello hash is available. See ZRTP specification
584 // chapter 9.1 for further information when an how to use the Hello
585 // hash.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500586 int numSupportedVersion = rx.getNumberSupportedVersions();
587 cout << "RX Hello hash 0: " << rx.getHelloHash(0) << endl;
588 cout << "RX Hello hash 0 length: " << rx.getHelloHash(0).length() << endl;
589 if (numSupportedVersion > 1) {
590 cout << "RX Hello hash 1: " << rx.getHelloHash(1) << endl;
591 cout << "RX Hello hash 1 length: " << rx.getHelloHash(1).length() << endl;
592 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500593 rx.setUserCallback(new MyUserCallback(&rx));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500594 rx.setAuxSecret(recvAuxSecret, sizeof(recvAuxSecret));
Alexandre Lision51140e12013-12-02 10:54:09 -0500595
596 rx.setSchedulingTimeout(10000);
597 rx.setExpireTimeout(1000000);
598
599 rx.startRunning();
600 rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
601 // arbitrary number of loops to provide time to start transmitter
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500602 if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500603 return 1;
604 }
605 rx.startZrtp();
606
607 for ( int i = 0; i < 5000 ; i++ ) {
608 const AppDataUnit* adu;
609 while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
610 cerr << "got some data: " << adu->getData() << endl;
611 if (*adu->getData() == 'e') {
612 delete adu;
613 return 0;
614 }
615 delete adu;
616 }
617 Thread::sleep(500);
618 }
619 return 0;
620 }
621};
622
623
624int main(int argc, char *argv[])
625{
626 int result = 0;
627 bool send = false;
628 bool recv = false;
629
630 char c;
631
632 /* check args */
633 while (1) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500634 c = getopt(argc, argv, "rsR:S:");
Alexandre Lision51140e12013-12-02 10:54:09 -0500635 if (c == -1) {
636 break;
637 }
638 switch (c) {
639 case 'r':
640 recv = true;
641 break;
642 case 's':
643 send = true;
644 break;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500645 case 'R':
646 pattern.setReceiverAddress(new InetHostAddress(optarg));
647 break;
648 case 'S':
649 pattern.setSenderAddress(new InetHostAddress(optarg));
650 break;
Alexandre Lision51140e12013-12-02 10:54:09 -0500651 default:
652 cerr << "Wrong Arguments, only -s and -r are accepted" << endl;
653 }
654 }
655
656 if (send || recv) {
657 if (send) {
658 cout << "Running as sender" << endl;
659 }
660 else {
661 cout << "Running as receiver" << endl;
662 }
663 }
664 else {
665 cerr << "No send or receive argument specificied" << endl;
666 exit(1);
667 }
668
669 // accept as parameter if must run as --send or --recv
670
671#if 0
672 RecvPacketTransmissionTest *rx;
673 SendPacketTransmissionTest *tx;
674
675 // run several tests in parallel threads
676 if ( send ) {
677 tx = new SendPacketTransmissionTest();
678 tx->start();
679 tx->join();
680 } else if ( recv ) {
681 rx = new RecvPacketTransmissionTest();
682 rx->start();
683 rx->join();
684 }
685//#endif
686//#if 0
687 ZrtpRecvPacketTransmissionTest *zrx;
688 ZrtpSendPacketTransmissionTest *ztx;
689
690 if ( send ) {
691 ztx = new ZrtpSendPacketTransmissionTest();
692 ztx->start();
693 ztx->join();
694 } else if ( recv ) {
695 zrx = new ZrtpRecvPacketTransmissionTest();
696 zrx->start();
697 zrx->join();
698 }
699#endif
700 ZrtpRecvPacketTransmissionTestCB *zrxcb;
701 ZrtpSendPacketTransmissionTestCB *ztxcb;
702
703 if ( send ) {
704 ztxcb = new ZrtpSendPacketTransmissionTestCB();
705 ztxcb->start();
706 ztxcb->join();
707 } else if ( recv ) {
708 zrxcb = new ZrtpRecvPacketTransmissionTestCB();
709 zrxcb->start();
710 zrxcb->join();
711 }
712
713 exit(result);
714}
715
716/** EMACS **
717 * Local variables:
718 * mode: c++
719 * c-default-style: ellemtel
720 * c-basic-offset: 4
721 * End:
722 */