test_engine.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*
  2. * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
  3. * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
  4. * Contact: http://philzimmermann.com
  5. * For licensing and other legal details, see the file zrtp_legal.c.
  6. *
  7. * Viktor Krykun <v.krikun at zfoneproject.com>
  8. */
  9. #include <stdio.h> /* for sprintf(), remove() */
  10. #include <string.h> /* for string operations */
  11. #include "test_engine.h"
  12. #include "queue.h"
  13. #define _ZTU_ "test engine"
  14. #define K_ZRTP_TEST_MAX_ENDPOINTS 10
  15. #define K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT 100
  16. #define K_ZRTP_TEST_MAX_CHANNELS (K_ZRTP_TEST_MAX_ENDPOINTS * K_ZRTP_TEST_MAX_ENDPOINTS * ZRTP_MAX_STREAMS_PER_SESSION)
  17. #define K_ZRTP_TEST_PROCESSORS_COUNT 2
  18. #define K_ZRTP_TEST_RTP_RATE 200
  19. extern uint8_t hash_word_list_odd[256][12];
  20. extern uint8_t hash_word_list_even[256][10];
  21. typedef struct {
  22. zrtp_test_id_t id;
  23. zrtp_test_id_t session_id;
  24. zrtp_test_id_t channel_id;
  25. zrtp_test_id_t endpoint_id;
  26. zrtp_stream_t *zrtp;
  27. uint16_t seq;
  28. zrtp_queue_t *input;
  29. zrtp_queue_t *output;
  30. unsigned zrtp_events_queueu[128];
  31. unsigned zrtp_events_count;
  32. } zrtp_test_stream_t;
  33. typedef struct {
  34. zrtp_test_id_t id;
  35. zrtp_test_id_t endpoint_id;
  36. zrtp_test_session_cfg_t cfg;
  37. zrtp_session_t *zrtp;
  38. zrtp_test_stream_t streams[ZRTP_MAX_STREAMS_PER_SESSION];
  39. unsigned streams_count;
  40. } zrtp_test_session_t;
  41. typedef struct {
  42. zrtp_test_id_t id;
  43. char name[ZRTP_TEST_STR_LEN];
  44. zrtp_zid_t zid;
  45. zrtp_test_endpoint_cfg_t cfg;
  46. zrtp_test_session_t sessions[K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT];
  47. unsigned sessions_count;
  48. zrtp_global_t *zrtp;
  49. unsigned is_running;
  50. zrtp_queue_t *input_queue;
  51. } zrtp_endpoint_t;
  52. typedef struct {
  53. zrtp_test_id_t id;
  54. zrtp_test_stream_t *left;
  55. zrtp_test_stream_t *right;
  56. unsigned is_attached;
  57. unsigned is_secure;
  58. } zrtp_test_channel_t;
  59. typedef struct zrtp_test_packet {
  60. uint32_t is_rtp; /*! Defines is packet RTP or RTCP */
  61. uint32_t length; /*! Packet Length in bytes */
  62. char body[1024]; /*! Packet body */
  63. } zrtp_test_packet_t;
  64. static zrtp_endpoint_t g_test_endpoints[K_ZRTP_TEST_MAX_ENDPOINTS];
  65. static unsigned g_test_endpoints_count = 0;
  66. static zrtp_test_channel_t g_test_channels[K_ZRTP_TEST_MAX_CHANNELS];
  67. static unsigned g_test_channels_count = 0;
  68. static int g_endpoints_counter = 7;
  69. static int g_channels_counter = 7;
  70. static int g_sessions_counter = 7;
  71. static int g_streams_counter = 7;
  72. zrtp_endpoint_t *zrtp_test_endpoint_by_id(zrtp_test_id_t id);
  73. zrtp_test_stream_t *zrtp_test_stream_by_id(zrtp_test_id_t id);
  74. zrtp_test_stream_t *zrtp_test_stream_by_peerid(zrtp_test_id_t id);
  75. zrtp_test_session_t *zrtp_test_session_by_id(zrtp_test_id_t id);
  76. zrtp_test_channel_t *zrtp_test_channel_by_id(zrtp_test_id_t id);
  77. /******************************************************************************
  78. * libzrtp interface implementation
  79. */
  80. static void on_zrtp_event(zrtp_stream_t *ctx, zrtp_protocol_event_t event) {
  81. zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
  82. zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
  83. stream->zrtp_events_queueu[stream->zrtp_events_count++] = event;
  84. }
  85. static void on_zrtp_secure(zrtp_stream_t *ctx) {
  86. zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
  87. zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
  88. zrtp_test_channel_t *channel = zrtp_test_channel_by_id(stream->channel_id);
  89. zrtp_test_stream_t *remote_stream = (channel->left == stream) ? channel->right : channel->left;
  90. if (stream->zrtp->state == ZRTP_STATE_SECURE &&
  91. remote_stream->zrtp->state == ZRTP_STATE_SECURE) {
  92. channel->is_secure = 1;
  93. }
  94. }
  95. static int on_send_packet(const zrtp_stream_t* ctx, char* message, unsigned int length) {
  96. zrtp_queue_elem_t* elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
  97. if (elem) {
  98. zrtp_test_packet_t* packet = (zrtp_test_packet_t*) elem->data;
  99. elem->size = length;
  100. packet->is_rtp = 1;
  101. packet->length = length;
  102. zrtp_memcpy(packet->body, message, length);
  103. zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
  104. zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
  105. if (stream) {
  106. zrtp_test_queue_push(stream->output, elem);
  107. return zrtp_status_ok;
  108. } else {
  109. return zrtp_status_fail;
  110. }
  111. } else {
  112. return zrtp_status_alloc_fail;
  113. }
  114. }
  115. /******************************************************************************
  116. * Processing Loop
  117. */
  118. static zrtp_test_stream_t *get_stream_to_process_(zrtp_endpoint_t *endpoint) {
  119. zrtp_test_id_t all_streams[K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT*ZRTP_MAX_STREAMS_PER_SESSION];
  120. unsigned streams_count = 0;
  121. unsigned i, j;
  122. for (i=0; i<endpoint->sessions_count; i++) {
  123. for (j=0; j<endpoint->sessions[i].streams_count; j++) {
  124. zrtp_test_stream_t *stream = &endpoint->sessions[i].streams[j];
  125. if (stream->input && stream->output)
  126. all_streams[streams_count++] = stream->id;
  127. }
  128. }
  129. if (0 == streams_count)
  130. return NULL;
  131. zrtp_randstr(endpoint->zrtp, (unsigned char*)&i, sizeof(i));
  132. j = (unsigned)i;
  133. j = j % streams_count;
  134. //printf("trace>>> CHOOSE stream Endpoint=%u IDX=%u ID=%u\n", endpoint->id, j, all_streams[j]);
  135. return zrtp_test_stream_by_id(all_streams[j]);
  136. }
  137. #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
  138. DWORD WINAPI process_incoming(void *param)
  139. #else
  140. void *process_incoming(void *param)
  141. #endif
  142. {
  143. zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;
  144. while (the_endpoint->is_running) {
  145. zrtp_test_packet_t* packet = NULL;
  146. zrtp_queue_elem_t* elem = NULL;
  147. zrtp_status_t s = zrtp_status_fail;
  148. zrtp_test_stream_t *stream;
  149. int is_protocol = 0;
  150. // TODO: use peak to not to block processing if queue for this stream is empty
  151. elem = zrtp_test_queue_pop(the_endpoint->input_queue);
  152. if (!elem || elem->size <= 0) {
  153. if (elem) zrtp_sys_free(elem);
  154. break;
  155. }
  156. packet = (zrtp_test_packet_t*) elem->data;
  157. zrtp_test_id_t stream_id;
  158. {
  159. if (packet->is_rtp) {
  160. ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
  161. stream_id = zrtp_ntoh32(rtp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
  162. } else {
  163. ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
  164. stream_id = zrtp_ntoh32(rtcp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
  165. }
  166. stream = zrtp_test_stream_by_peerid(stream_id);
  167. }
  168. /*
  169. * Process incoming packet by libzrtp. Is this a RTP media packet - copy it to the buffer
  170. * to print out later.
  171. */
  172. if (packet->is_rtp) {
  173. s = zrtp_process_srtp(stream->zrtp, packet->body, &packet->length);
  174. } else {
  175. s = zrtp_process_srtcp(stream->zrtp, packet->body, &packet->length);
  176. }
  177. if (!is_protocol) {
  178. char *body;
  179. if (packet->is_rtp) {
  180. body = packet->body + sizeof(zrtp_rtp_hdr_t);
  181. body[packet->length - sizeof(zrtp_rtp_hdr_t)] = 0;
  182. } else {
  183. body = packet->body + sizeof(zrtp_rtcp_hdr_t);
  184. body[packet->length - sizeof(zrtp_rtcp_hdr_t)] = 0;
  185. }
  186. switch (s)
  187. {
  188. case zrtp_status_ok: {
  189. ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] OK. <%s> decrypted %d bytes.\n",
  190. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body, packet->length));
  191. } break;
  192. case zrtp_status_drop: {
  193. ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DROPPED. <%s>\n",
  194. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
  195. } break;
  196. case zrtp_status_fail: {
  197. ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DECRYPT FAILED. <%s>\n",
  198. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
  199. } break;
  200. default:
  201. break;
  202. }
  203. }
  204. zrtp_sys_free(elem);
  205. /*
  206. * When zrtp_stream is in the pending clear state and other side wants to send plain
  207. * traffic. We have to call zrtp_clear_stream().
  208. */
  209. if (stream->zrtp->state == ZRTP_STATE_PENDINGCLEAR) {
  210. zrtp_stream_clear(stream->zrtp);
  211. }
  212. }
  213. #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
  214. return 0;
  215. #else
  216. return NULL;
  217. #endif
  218. }
  219. #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
  220. DWORD WINAPI process_outgoing(void *param)
  221. #else
  222. void *process_outgoing(void *param)
  223. #endif
  224. {
  225. unsigned packets_counter = 0;
  226. zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;
  227. while (the_endpoint->is_running) {
  228. zrtp_test_stream_t* stream = NULL;
  229. unsigned i;
  230. zrtp_status_t s = zrtp_status_fail;
  231. zrtp_test_packet_t* packet;
  232. zrtp_queue_elem_t* elem;
  233. char* word = NULL;
  234. zrtp_sleep(K_ZRTP_TEST_RTP_RATE);
  235. /* Get random channel to operate with and select random peer */
  236. stream = get_stream_to_process_(the_endpoint);
  237. if (!stream) {
  238. continue;
  239. }
  240. elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
  241. if (!elem) {
  242. break;
  243. }
  244. packet = (zrtp_test_packet_t*) elem->data;
  245. packet->is_rtp = (packets_counter++ % 20); /* Every 20-th packet is RTCP */
  246. /*
  247. * Construct RTP/RTCP Packet
  248. */
  249. if (packet->is_rtp)
  250. {
  251. ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
  252. /* Fill RTP Header according to the specification */
  253. zrtp_memset(rtp_hdr, 0, sizeof(zrtp_rtp_hdr_t));
  254. rtp_hdr->version = 2; /* Current RTP version 2 */
  255. rtp_hdr->pt = 0; /* PCMU padding type */
  256. rtp_hdr->ssrc = zrtp_hton32(stream->id); /* Use stream Identifier as it's SSRC */
  257. if (stream->seq >= 0xFFFF) {
  258. stream->seq = 0;
  259. }
  260. rtp_hdr->seq = zrtp_hton16(stream->seq++);
  261. rtp_hdr->ts = zrtp_hton32((uint32_t)(zrtp_time_now()/1000));
  262. /* Get RTP body from PGP words lists */
  263. word = (char*)(i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
  264. zrtp_memcpy(packet->body + sizeof(zrtp_rtp_hdr_t), word, (uint32_t)strlen(word));
  265. packet->length = sizeof(zrtp_rtp_hdr_t) + (uint32_t)strlen(word);
  266. /* Process RTP media with libzrtp */
  267. s = zrtp_process_rtp(stream->zrtp, packet->body, &packet->length);
  268. }
  269. else {
  270. ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
  271. /* Fill RTCP Header according to the specification */
  272. rtcp_hdr->rc = 0;
  273. rtcp_hdr->version = 2;
  274. rtcp_hdr->ssrc = stream->id;
  275. /* Get RTP body from PGP words lists. Put RTCP marker at the beginning */
  276. zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t), "RTCP", 4);
  277. word = (char*)( i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
  278. zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t) + 4, word, (uint32_t)strlen(word));
  279. packet->length = sizeof(zrtp_rtcp_hdr_t) + (uint32_t)strlen(word) + 4;
  280. /* RTCP packets sould be 32 byes aligned */
  281. packet->length += (packet->length % 4) ? (4 - packet->length % 4) : 0;
  282. /* Process RTCP control with libzrtp */
  283. s = zrtp_process_rtcp(stream->zrtp, packet->body, &packet->length);
  284. }
  285. elem->size = packet->length;
  286. /* Handle zrtp_process_xxx() instructions */
  287. switch (s) {
  288. /* Put the packet to the queue ==> send packet to the other side pear */
  289. case zrtp_status_ok: {
  290. ZRTP_LOG(3, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] OK. <%s%s> encrypted %d bytes.\n",
  291. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, packet->is_rtp ? "" : "RTCP", word, packet->length));
  292. zrtp_test_queue_push(stream->output, elem);
  293. } break;
  294. case zrtp_status_drop: {
  295. ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] DROPPED.\n",
  296. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
  297. } break;
  298. case zrtp_status_fail: {
  299. ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] ENCRYPT FAILED.\n",
  300. zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
  301. } break;
  302. default:
  303. break;
  304. }
  305. if (zrtp_status_ok != s) {
  306. zrtp_sys_free(packet);
  307. }
  308. }
  309. #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
  310. return 0;
  311. #else
  312. return NULL;
  313. #endif
  314. }
  315. /******************************************************************************
  316. * Test Engine Public API
  317. */
  318. void zrtp_test_endpoint_config_defaults(zrtp_test_endpoint_cfg_t* cfg) {
  319. zrtp_memset(cfg, 0, sizeof(zrtp_test_endpoint_cfg_t));
  320. cfg->generate_traffic = 0;
  321. /* It's always a good idea to start with default values */
  322. zrtp_config_defaults(&cfg->zrtp);
  323. /* Set ZRTP client id */
  324. strcpy(cfg->zrtp.client_id, "zrtp-test-engine");
  325. cfg->zrtp.is_mitm = 0;
  326. cfg->zrtp.lic_mode = ZRTP_LICENSE_MODE_ACTIVE;
  327. cfg->zrtp.cb.event_cb.on_zrtp_secure = &on_zrtp_secure;
  328. cfg->zrtp.cb.event_cb.on_zrtp_security_event = &on_zrtp_event;
  329. cfg->zrtp.cb.event_cb.on_zrtp_protocol_event = &on_zrtp_event;
  330. cfg->zrtp.cb.misc_cb.on_send_packet = &on_send_packet;
  331. }
  332. zrtp_status_t zrtp_test_endpoint_create(zrtp_test_endpoint_cfg_t* cfg,
  333. const char *name,
  334. zrtp_test_id_t* id) {
  335. zrtp_status_t s;
  336. unsigned i;
  337. char cache_file_path[ZRTP_TEST_STR_LEN];
  338. zrtp_endpoint_t *new_endpoint;
  339. if (g_test_endpoints_count >= K_ZRTP_TEST_MAX_ENDPOINTS)
  340. return zrtp_status_alloc_fail;
  341. new_endpoint = &g_test_endpoints[g_test_endpoints_count++];
  342. zrtp_memset(new_endpoint, 0, sizeof(zrtp_endpoint_t));
  343. /* Copy configuration, we will use it later to clean up after ourselves */
  344. zrtp_memcpy(&new_endpoint->cfg, cfg, sizeof(zrtp_test_endpoint_cfg_t));
  345. /* Remember endpoint name */
  346. strcpy(new_endpoint->name, name);
  347. new_endpoint->id = g_endpoints_counter++;
  348. /* Adjust cache file path so each endpoint will use it's own file. */
  349. sprintf(cache_file_path, "./%s_cache.dat", name);
  350. zrtp_zstrcpyc(ZSTR_GV(new_endpoint->cfg.zrtp.def_cache_path), cache_file_path);
  351. /* Initialize libzrtp engine for this endpoint */
  352. s = zrtp_init(&new_endpoint->cfg.zrtp, &new_endpoint->zrtp);
  353. if (zrtp_status_ok == s) {
  354. *id = new_endpoint->id;
  355. /* Generate random ZID */
  356. zrtp_randstr(new_endpoint->zrtp, new_endpoint->zid, sizeof(new_endpoint->zid));
  357. }
  358. /* Create Input queue*/
  359. s = zrtp_test_queue_create(&new_endpoint->input_queue);
  360. if (zrtp_status_ok != s) {
  361. return s;
  362. }
  363. /* Start processing loop */
  364. new_endpoint->is_running = 1;
  365. for (i = 0; i<K_ZRTP_TEST_PROCESSORS_COUNT; i++) {
  366. if (0 != zrtp_thread_create(process_incoming, new_endpoint)) {
  367. return zrtp_status_fail;
  368. }
  369. if (cfg->generate_traffic) {
  370. if (0 != zrtp_thread_create(process_outgoing, new_endpoint)) {
  371. return zrtp_status_fail;
  372. }
  373. }
  374. }
  375. return s;
  376. }
  377. zrtp_status_t zrtp_test_endpoint_destroy(zrtp_test_id_t id) {
  378. unsigned i;
  379. zrtp_status_t s = zrtp_status_ok;
  380. zrtp_endpoint_t *endpoint = zrtp_test_endpoint_by_id(id);
  381. endpoint->is_running = 0;
  382. if (endpoint->input_queue) {
  383. /* Push faked element to the queue to unlock incoming threads */
  384. for (i=0; i<K_ZRTP_TEST_PROCESSORS_COUNT; i++) {
  385. zrtp_queue_elem_t *elem = malloc(sizeof(zrtp_queue_elem_t));
  386. elem->size = 0;
  387. zrtp_test_queue_push(endpoint->input_queue, elem);
  388. }
  389. zrtp_sleep(0.5*1000);
  390. zrtp_test_queue_destroy(endpoint->input_queue);
  391. }
  392. for (i=0; i<20; i++) zrtp_sleep(100);
  393. if (endpoint) {
  394. /* Shut down libzrtp */
  395. if (endpoint->zrtp)
  396. s = zrtp_down(endpoint->zrtp);
  397. /* Clean-up ZRTP cache after ourselves */
  398. remove(endpoint->cfg.zrtp.def_cache_path.buffer);
  399. } else {
  400. s = zrtp_status_fail;
  401. }
  402. return s;
  403. }
  404. zrtp_status_t zrtp_test_stream_get(zrtp_test_id_t id,
  405. zrtp_test_stream_info_t* info) {
  406. zrtp_test_stream_t *stream = zrtp_test_stream_by_id(id);
  407. if (stream) {
  408. zrtp_status_t s;
  409. zrtp_memset(info, 0, sizeof(zrtp_test_stream_info_t));
  410. zrtp_memcpy(info->zrtp_events_queueu, stream->zrtp_events_queueu, sizeof(info->zrtp_events_queueu));
  411. info->zrtp_events_count = stream->zrtp_events_count;
  412. s = zrtp_stream_get(stream->zrtp, &info->zrtp);
  413. return s;
  414. } else {
  415. return zrtp_status_bad_param;
  416. }
  417. }
  418. void zrtp_test_session_config_defaults(zrtp_test_session_cfg_t* cfg) {
  419. cfg->streams_count = 1;
  420. cfg->role = ZRTP_SIGNALING_ROLE_UNKNOWN;
  421. cfg->is_enrollment = 0;
  422. zrtp_profile_defaults(&cfg->zrtp, NULL);
  423. }
  424. zrtp_status_t zrtp_test_session_create(zrtp_test_id_t endpoint_id,
  425. zrtp_test_session_cfg_t* cfg,
  426. zrtp_test_id_t* id) {
  427. zrtp_status_t s;
  428. unsigned i;
  429. zrtp_test_session_t *the_session;
  430. zrtp_endpoint_t *the_endpoint = zrtp_test_endpoint_by_id(endpoint_id);
  431. if (!the_endpoint)
  432. return zrtp_status_fail;
  433. if (the_endpoint->sessions_count >= K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT)
  434. return zrtp_status_fail;
  435. the_session = &the_endpoint->sessions[the_endpoint->sessions_count++];
  436. zrtp_memset(the_session, 0, sizeof(zrtp_test_session_t));
  437. zrtp_memcpy(&the_session->cfg, cfg, sizeof(zrtp_test_session_cfg_t));
  438. the_session->id = g_sessions_counter++;
  439. the_session->endpoint_id = endpoint_id;
  440. s = zrtp_session_init(the_endpoint->zrtp,
  441. &cfg->zrtp,
  442. the_endpoint->zid,
  443. cfg->role,
  444. &the_session->zrtp);
  445. if (zrtp_status_ok == s) {
  446. zrtp_session_set_userdata(the_session->zrtp, &the_session->id);
  447. for (i=0; i<cfg->streams_count; i++) {
  448. zrtp_test_stream_t *the_stream = &the_session->streams[i];
  449. zrtp_memset(the_stream, 0, sizeof(zrtp_test_stream_t));
  450. the_stream->id = g_streams_counter++;
  451. the_stream->session_id = the_session->id;
  452. the_stream->endpoint_id = endpoint_id;
  453. s = zrtp_stream_attach(the_session->zrtp, &the_stream->zrtp);
  454. if (zrtp_status_ok == s) {
  455. zrtp_stream_set_userdata(the_stream->zrtp, &the_stream->id);
  456. the_session->streams_count++;
  457. } else {
  458. break;
  459. }
  460. }
  461. }
  462. if (zrtp_status_ok == s) {
  463. *id = the_session->id;
  464. }
  465. return s;
  466. }
  467. zrtp_status_t zrtp_test_session_destroy(zrtp_test_id_t id) {
  468. zrtp_test_session_t *session = zrtp_test_session_by_id(id);
  469. if (session) {
  470. /* NOTE: we don't release session slots here due to nature of testing
  471. * engine: test configuration constructed from scratch for every single test.
  472. */
  473. zrtp_session_down(session->zrtp);
  474. }
  475. return zrtp_status_ok;
  476. }
  477. zrtp_status_t zrtp_test_session_get(zrtp_test_id_t id, zrtp_test_session_info_t* info) {
  478. zrtp_status_t s;
  479. zrtp_test_session_t *session = zrtp_test_session_by_id(id);
  480. if (session) {
  481. s = zrtp_session_get(session->zrtp, &info->zrtp);
  482. if (zrtp_status_ok == s) {
  483. unsigned i;
  484. for (i=0; i<session->streams_count; i++) {
  485. s = zrtp_test_stream_get(session->streams[i].id, &info->streams[i]);
  486. if (zrtp_status_ok != s)
  487. break;
  488. }
  489. }
  490. return s;
  491. } else {
  492. return zrtp_status_bad_param;
  493. }
  494. }
  495. zrtp_status_t zrtp_test_channel_create(zrtp_test_id_t left_id, zrtp_test_id_t right_id, zrtp_test_id_t* id) {
  496. zrtp_test_channel_t *the_channel;
  497. zrtp_test_stream_t *left = zrtp_test_stream_by_id(left_id);
  498. zrtp_test_stream_t *right = zrtp_test_stream_by_id(right_id);
  499. if (!left || !right)
  500. return zrtp_status_bad_param;
  501. if (g_test_channels_count >= K_ZRTP_TEST_MAX_CHANNELS)
  502. return zrtp_status_bad_param;
  503. zrtp_endpoint_t *left_endpoint = zrtp_test_endpoint_by_id(left->endpoint_id);
  504. zrtp_endpoint_t *right_endpoint = zrtp_test_endpoint_by_id(right->endpoint_id);
  505. the_channel = &g_test_channels[g_test_channels_count++];
  506. zrtp_memset(the_channel, 0, sizeof(zrtp_test_channel_t));
  507. the_channel->id = g_channels_counter++;
  508. the_channel->left = left;
  509. the_channel->right = right;
  510. left->output = right_endpoint->input_queue;
  511. left->input = left_endpoint->input_queue;
  512. right->output = left_endpoint->input_queue;
  513. right->input = right_endpoint->input_queue;
  514. right->channel_id = the_channel->id;
  515. left->channel_id = the_channel->id;
  516. the_channel->is_attached = 1;
  517. *id = the_channel->id;
  518. return zrtp_status_ok;
  519. }
  520. zrtp_status_t zrtp_test_channel_create2(zrtp_test_id_t left_session,
  521. zrtp_test_id_t right_session,
  522. unsigned stream_idx,
  523. zrtp_test_id_t *id) {
  524. zrtp_test_session_t *left = zrtp_test_session_by_id(left_session);
  525. zrtp_test_session_t *right = zrtp_test_session_by_id(right_session);
  526. if (!left || !right)
  527. return zrtp_status_bad_param;
  528. if (left->streams_count <= stream_idx || right->streams_count <= stream_idx)
  529. return zrtp_status_bad_param;
  530. return zrtp_test_channel_create(left->streams[stream_idx].id, right->streams[stream_idx].id, id);
  531. }
  532. zrtp_status_t zrtp_test_channel_destroy(zrtp_test_id_t id) {
  533. zrtp_test_channel_t *channel = zrtp_test_channel_by_id(id);
  534. if (!channel)
  535. return zrtp_status_bad_param;
  536. return zrtp_status_ok;
  537. }
  538. zrtp_status_t zrtp_test_channel_start(zrtp_test_id_t id) {
  539. zrtp_status_t s1, s2;
  540. zrtp_test_channel_t *the_channel = zrtp_test_channel_by_id(id);
  541. zrtp_test_session_t *the_session;
  542. the_session = zrtp_test_session_by_id(the_channel->left->session_id);
  543. if (the_session->cfg.is_enrollment)
  544. s1 = zrtp_stream_registration_start(the_channel->left->zrtp, the_channel->left->id); /* use stream Id as ssrc */
  545. else
  546. s1 = zrtp_stream_start(the_channel->left->zrtp, the_channel->left->id); /* use stream Id as ssrc */
  547. if (s1 == zrtp_status_ok) {
  548. the_session = zrtp_test_session_by_id(the_channel->right->session_id);
  549. if (the_session->cfg.is_enrollment)
  550. s2 = zrtp_stream_registration_start(the_channel->right->zrtp, the_channel->right->id);
  551. else
  552. s2 = zrtp_stream_start(the_channel->right->zrtp, the_channel->right->id);
  553. } else {
  554. return s1;
  555. }
  556. return s2;
  557. }
  558. zrtp_status_t zrtp_test_channel_get(zrtp_test_id_t id,
  559. zrtp_test_channel_info_t* info) {
  560. zrtp_test_channel_t *channel = zrtp_test_channel_by_id(id);
  561. if (channel) {
  562. zrtp_status_t s;
  563. zrtp_memset(info, 0, sizeof(zrtp_test_channel_info_t));
  564. s = zrtp_test_stream_get(channel->left->id, &info->left);
  565. if (zrtp_status_ok == s) {
  566. s = zrtp_test_stream_get(channel->right->id, &info->right);
  567. if (zrtp_status_ok == s) {
  568. info->is_secure = channel->is_secure;
  569. }
  570. }
  571. return s;
  572. } else {
  573. return zrtp_status_bad_param;
  574. }
  575. }
  576. /******************************************************************************
  577. * Helpers
  578. */
  579. zrtp_endpoint_t *zrtp_test_endpoint_by_id(zrtp_test_id_t id) {
  580. int i;
  581. if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
  582. for (i=0; i<g_test_endpoints_count; i++) {
  583. if (g_test_endpoints[i].id == id) {
  584. return &g_test_endpoints[i];
  585. }
  586. }
  587. return NULL;
  588. }
  589. zrtp_test_session_t *zrtp_test_session_by_id(zrtp_test_id_t id) {
  590. int i, j;
  591. if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
  592. for (i=0; i<g_test_endpoints_count; i++) {
  593. zrtp_endpoint_t *endpoint = &g_test_endpoints[i];
  594. if (endpoint->id == ZRTP_TEST_UNKNOWN_ID)
  595. continue;
  596. for (j=0; j<endpoint->sessions_count; j++) {
  597. if (endpoint->sessions[j].id == id) {
  598. return &endpoint->sessions[j];
  599. }
  600. }
  601. }
  602. return NULL;
  603. }
  604. zrtp_test_stream_t *zrtp_test_stream_by_id(zrtp_test_id_t id) {
  605. int i, j, k;
  606. if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
  607. for (i=0; i<g_test_endpoints_count; i++) {
  608. zrtp_endpoint_t *endpoint = &g_test_endpoints[i];
  609. if (endpoint->id == ZRTP_TEST_UNKNOWN_ID)
  610. continue;
  611. for (j=0; j<endpoint->sessions_count; j++) {
  612. zrtp_test_session_t *session = &endpoint->sessions[j];
  613. if (session->id == ZRTP_TEST_UNKNOWN_ID)
  614. continue;
  615. for (k=0; k<session->streams_count; k++) {
  616. if (session->streams[k].id == id) {
  617. return &session->streams[k];
  618. }
  619. }
  620. }
  621. }
  622. return NULL;
  623. }
  624. zrtp_test_channel_t *zrtp_test_channel_by_id(zrtp_test_id_t id) {
  625. int i;
  626. zrtp_test_channel_t *channel = NULL;
  627. if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
  628. for (i=0; i<g_test_channels_count; i++) {
  629. if (g_test_channels[i].id != ZRTP_TEST_UNKNOWN_ID && g_test_channels[i].id == id) {
  630. channel = &g_test_channels[i];
  631. break;
  632. }
  633. }
  634. return channel;
  635. }
  636. zrtp_test_stream_t *zrtp_test_stream_by_peerid(zrtp_test_id_t id) {
  637. int i;
  638. if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
  639. for (i=0; i<g_test_channels_count; i++) {
  640. if (g_test_channels[i].id != ZRTP_TEST_UNKNOWN_ID) {
  641. if (g_test_channels[i].left->id == id)
  642. return g_test_channels[i].right;
  643. else if (g_test_channels[i].right->id == id)
  644. return g_test_channels[i].left;
  645. }
  646. }
  647. return NULL;
  648. }
  649. zrtp_test_id_t zrtp_test_session_get_stream_by_idx(zrtp_test_id_t session_id, unsigned idx) {
  650. zrtp_test_session_t *session = zrtp_test_session_by_id(session_id);
  651. if (session && session->streams_count > idx) {
  652. return session->streams[idx].id;
  653. } else {
  654. return ZRTP_TEST_UNKNOWN_ID;
  655. }
  656. }
  657. zrtp_stream_t *zrtp_stream_for_test_stream(zrtp_test_id_t stream_id) {
  658. zrtp_test_stream_t *stream = zrtp_test_stream_by_id(stream_id);
  659. if (stream) {
  660. return stream->zrtp;
  661. } else {
  662. return NULL;
  663. }
  664. }
  665. unsigned zrtp_stream_did_event_receive(zrtp_test_id_t stream_id, unsigned event) {
  666. unsigned i;
  667. zrtp_test_stream_info_t stream_info;
  668. zrtp_test_stream_get(stream_id, &stream_info);
  669. for (i=0; i<stream_info.zrtp_events_count; i++) {
  670. if (stream_info.zrtp_events_queueu[i] == event)
  671. break;
  672. }
  673. return (i != stream_info.zrtp_events_count);
  674. }