ccRTP 2.1.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ccsrtptest.cpp
Go to the documentation of this file.
1 // 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 
18 #include <cstdlib>
19 #include <cstring>
20 #include <ccrtp/rtp.h>
21 #include <ccrtp/rtppkt.h>
23 #include <ccrtp/CryptoContext.h>
25 
26 #ifdef CCXX_NAMESPACES
27 using namespace ost;
28 using namespace std;
29 #endif
30 
31 // Select one of SrtpEncryptionAESF8, SrtpEncryptionAESCM, SrtpEncryptionTWOCM, SrtpEncryptionTWOF8
32 // per RFC 3711 standard is: SrtpEncryptionAESCM
33 static int cryptoAlgo = SrtpEncryptionAESCM;
34 
35 inline int hex_char_to_nibble(uint8_t c)
36 {
37  switch(c) {
38  case ('0'): return 0x0;
39  case ('1'): return 0x1;
40  case ('2'): return 0x2;
41  case ('3'): return 0x3;
42  case ('4'): return 0x4;
43  case ('5'): return 0x5;
44  case ('6'): return 0x6;
45  case ('7'): return 0x7;
46  case ('8'): return 0x8;
47  case ('9'): return 0x9;
48  case ('a'): return 0xa;
49  case ('A'): return 0xa;
50  case ('b'): return 0xb;
51  case ('B'): return 0xb;
52  case ('c'): return 0xc;
53  case ('C'): return 0xc;
54  case ('d'): return 0xd;
55  case ('D'): return 0xd;
56  case ('e'): return 0xe;
57  case ('E'): return 0xe;
58  case ('f'): return 0xf;
59  case ('F'): return 0xf;
60  default: return -1; /* this flags an error */
61  }
62  /* NOTREACHED */
63  return -1; /* this keeps compilers from complaining */
64 }
65 
66 /*
67  * hex_string_to_octet_string converts a hexadecimal string
68  * of length 2 * len to a raw octet string of length len
69  */
70 
71 int hex_string_to_octet_string(char *raw, char *hex, int len)
72 {
73  uint8 x;
74  int tmp;
75  int hex_len;
76 
77  hex_len = 0;
78  while (hex_len < len) {
79  tmp = hex_char_to_nibble(hex[0]);
80  if (tmp == -1)
81  return hex_len;
82  x = (tmp << 4);
83  hex_len++;
84  tmp = hex_char_to_nibble(hex[1]);
85  if (tmp == -1)
86  return hex_len;
87  x |= (tmp & 0xff);
88  hex_len++;
89  *raw++ = x;
90  hex += 2;
91  }
92  return hex_len;
93 }
94 
95 class PacketsPattern
96 {
97 public:
98  inline const InetHostAddress& getDestinationAddress() const
99  { return destinationAddress; }
100 
101  inline const tpport_t getDestinationPort() const
102  { return destinationPort; }
103 
104  uint32 getPacketsNumber() const
105  { return packetsNumber; }
106 
107  uint32 getSsrc() const
108  { return 0xdeadbeef; }
109 
110  const unsigned char* getPacketData(uint32 i)
111  { return data; }
112 
113  const size_t getPacketSize(uint32 i)
114  { return packetsSize; }
115 
116 private:
117  static const InetHostAddress destinationAddress;
118  static const uint16 destinationPort = 5002;
119  static const uint32 packetsNumber = 10;
120  static const uint32 packetsSize = 12;
121  static unsigned char data[];
122 };
123 
124 const InetHostAddress PacketsPattern::destinationAddress =
125  InetHostAddress("localhost");
126 
127 unsigned char PacketsPattern::data[] = {
128  "0123456789\n"
129 };
130 
132 
133 static char* fixKey = (char *)"c2479f224b21c2008deea6ef0e5dbd4a761aef98e7ebf8eed405986c4687";
134 
135 // static uint8* masterKey = (uint8*)"masterKeymasterKeymasterKeymaster";
136 // static uint8* masterSalt = (uint8*)"NaClNaClNaClNa";
137 
138 uint8 masterKey[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
139  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
140 
141 uint8 masterSalt[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
142  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d };
143 
144 static uint8 binKeys[60];
145 
146 class SendPacketTransmissionTest: public Thread, public TimerPort
147 {
148 public:
149  void run() {
150  doTest();
151  }
152 
153  int doTest()
154  {
155  // should be valid?
156  //RTPSession tx();
157  RTPSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
158  tx.setSchedulingTimeout(10000);
159  tx.setExpireTimeout(1000000);
160 
161  CryptoContext* txCryptoCtx =
163  0, // roc,
164  0L, // keydr << 48,
165  cryptoAlgo, // encryption algo
166  SrtpAuthenticationSha1Hmac, // authtication algo
167  masterKey, // Master Key
168  128 / 8, // Master Key length
169  masterSalt, // Master Salt
170  112 / 8, // Master Salt length
171  128 / 8, // encryption keyl
172  160 / 8, // authentication key len (SHA1))
173  112 / 8, // session salt len
174  80 / 8); // authentication tag len
175  txCryptoCtx->deriveSrtpKeys(0);
176 
177  tx.setOutQueueCryptoContext(txCryptoCtx);
178 
179  CryptoContextCtrl* txCryptoCtxCtrl = new CryptoContextCtrl(0,
180  cryptoAlgo, // encryption algo
181  SrtpAuthenticationSha1Hmac, // authtication algo
182  masterKey, // Master Key
183  128 / 8, // Master Key length
184  masterSalt, // Master Salt
185  112 / 8, // Master Salt length
186  128 / 8, // encryption keyl
187  160 / 8, // authentication key len (SHA1))
188  112 / 8, // session salt len
189  80 / 8); // authentication tag len
190  tx.setOutQueueCryptoContextCtrl(txCryptoCtxCtrl);
191 
192  tx.startRunning();
193 
194  tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
195  if (!tx.addDestination(pattern.getDestinationAddress(), pattern.getDestinationPort()) ) {
196  return 1;
197  }
198 
199  // 50 packets per second (packet duration of 20ms)
200  uint32 period = 20;
201  uint16 inc = tx.getCurrentRTPClockRate()/50;
202  TimerPort::setTimer(period);
203  for ( uint32 i = 0; i < pattern.getPacketsNumber(); i++ ) {
204  tx.putData(i*inc, pattern.getPacketData(i), pattern.getPacketSize(i));
205  cout << "Sent some data: " << i << endl;
206  Thread::sleep(TimerPort::getTimer());
207  TimerPort::incTimer(period);
208  }
209  return 0;
210  }
211 };
212 
213 
214 class RecvPacketTransmissionTest: public Thread
215 {
216 public:
217  void run() {
218  doTest();
219  }
220 
221  int doTest()
222  {
225 
226  rx.setSchedulingTimeout(10000);
227  rx.setExpireTimeout(1000000);
228 
229  CryptoContext* rxCryptoCtx =
230  new CryptoContext(0, // SSRC == 0 -> Context template
231  0, // roc,
232  0L, // keydr << 48,
233  cryptoAlgo, // encryption algo
234  SrtpAuthenticationSha1Hmac, // authtication algo
235  masterKey, // Master Key
236  128 / 8, // Master Key length
237  masterSalt, // Master Salt
238  112 / 8, // Master Salt length
239  128 / 8, // encryption keyl
240  160 / 8, // authentication keylen (SHA1))
241  112 / 8, // session salt len
242  80 / 8); // authentication tag len
243  rx.setInQueueCryptoContext(rxCryptoCtx);
244 
245  CryptoContextCtrl* rxCryptoCtxCtrl = new CryptoContextCtrl(0,
246  cryptoAlgo, // encryption algo
247  SrtpAuthenticationSha1Hmac, // authtication algo
248  masterKey, // Master Key
249  128 / 8, // Master Key length
250  masterSalt, // Master Salt
251  112 / 8, // Master Salt length
252  128 / 8, // encryption keyl
253  160 / 8, // authentication key len (SHA1))
254  112 / 8, // session salt len
255  80 / 8); // authentication tag len
256 
257  rx.setInQueueCryptoContextCtrl(rxCryptoCtxCtrl);
258 
259  rx.startRunning();
260  rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
261  // arbitrary number of loops
262  for ( int i = 0; i < 500 ; i++ ) {
263  const AppDataUnit* adu;
264  while ( (adu = rx.getData(rx.getFirstTimestamp())) ) {
265  cerr << "got some data: " << adu->getData() << endl;
266  delete adu;
267  }
268  Thread::sleep(70);
269  }
270  return 0;
271  }
272 };
273 
274 int main(int argc, char *argv[])
275 {
276  int result = 0;
277  bool send = false;
278  bool recv = false;
279  bool f8Test = false;
280 
281  char* inputKey = NULL;
282  char *args = *argv++;
283 
284  while(NULL != (args = *argv++)) {
285  if(*args == '-')
286  ++args;
287  if(!strcmp(args, "r") || !strcmp(args, "recv"))
288  recv = true;
289  else if(!strcmp(args, "s") || !strcmp(args, "send"))
290  send = true;
291  else if(!strcmp(args, "8") || !strcmp(args, "8test"))
292  f8Test = true;
293  else if(!strcmp(args, "k") || !strcmp(args, "key"))
294  inputKey = *argv++;
295  else
296  fprintf(stderr, "*** ccsrtptest: %s: unknown option\n", args);
297  }
298 
299  if (inputKey == NULL) {
300  inputKey = fixKey;
301  }
302  hex_string_to_octet_string((char*)binKeys, inputKey, 60);
303 
304  if (send || recv) {
305  if (send) {
306  cout << "Running as sender" << endl;
307  }
308  else {
309  cout << "Running as receiver" << endl;
310  }
311  }
312  else if (f8Test) {
313  cout << "Running F8 test: ";
314  int ret = testF8();
315  cout << ret << endl;
316  exit(ret);
317  }
320 
321  // accept as parameter if must run as -s, -r, -8
322 
323  // run several tests in parallel threads
324  if (send) {
325  tx = new SendPacketTransmissionTest();
326  tx->start();
327  tx->join();
328  } else if (recv) {
329  rx = new RecvPacketTransmissionTest();
330  rx->start();
331  rx->join();
332  }
333  exit(result);
334 }
335 
const size_t getPacketSize(uint32 i)
Definition: ccsrtptest.cpp:113
The implementation for a SRTCP cryptographic context.
ITU-T G.711. mu-law audio 8 Khz (RFC 1890)
Definition: formats.h:75
Interface (envelope) to data received over RTP packets.
Definition: queuebase.h:68
The implementation for a SRTP cryptographic context.
Definition: CryptoContext.h:82
uint32 getPacketsNumber() const
Definition: ccsrtptest.cpp:104
uint32 getSsrc() const
Definition: ccsrtptest.cpp:107
int hex_string_to_octet_string(char *raw, char *hex, int len)
Definition: ccsrtptest.cpp:71
uint8 masterSalt[]
Definition: ccsrtptest.cpp:141
const InetHostAddress & getDestinationAddress() const
Definition: ccsrtptest.cpp:98
int main(int argc, char *argv[])
Definition: ccsrtptest.cpp:274
uint8 masterKey[]
Definition: ccsrtptest.cpp:138
const tpport_t getDestinationPort() const
Definition: ccsrtptest.cpp:101
int testF8()
const unsigned char * getPacketData(uint32 i)
Definition: ccsrtptest.cpp:110
This template class adds the threading aspect to the RTPSessionBase template in one of the many possi...
Definition: rtp.h:418
const int SrtpAuthenticationSha1Hmac
Definition: CryptoContext.h:31
PacketsPattern pattern
Definition: ccsrtptest.cpp:131
static const InetHostAddress destinationAddress
Definition: ccrtptest.cpp:44
int hex_char_to_nibble(uint8_t c)
Definition: ccsrtptest.cpp:35
Class which implements SRTP AES cryptographic functions.
void deriveSrtpKeys(uint64 index)
Perform key derivation according to SRTP specification.
Static payload format objects.
Definition: formats.h:200
const uint8 *const getData() const
Get data as it is received in RTP packets (i.e.
Definition: queuebase.h:105
Generic and audio/video profile specific RTP interface of ccRTP.
static unsigned char data[65535]
Definition: ccrtptest.cpp:48
const int SrtpEncryptionAESCM
Definition: CryptoContext.h:35
RTP packets handling.