123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854 |
- /*
- * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
- * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
- * Contact: http://philzimmermann.com
- * For licensing and other legal details, see the file zrtp_legal.c.
- *
- * Viktor Krykun <v.krikun at zfoneproject.com>
- */
- #include <stdio.h> /* for sprintf(), remove() */
- #include <string.h> /* for string operations */
- #include "test_engine.h"
- #include "queue.h"
- #define _ZTU_ "test engine"
- #define K_ZRTP_TEST_MAX_ENDPOINTS 10
- #define K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT 100
- #define K_ZRTP_TEST_MAX_CHANNELS (K_ZRTP_TEST_MAX_ENDPOINTS * K_ZRTP_TEST_MAX_ENDPOINTS * ZRTP_MAX_STREAMS_PER_SESSION)
- #define K_ZRTP_TEST_PROCESSORS_COUNT 2
- #define K_ZRTP_TEST_RTP_RATE 200
- extern uint8_t hash_word_list_odd[256][12];
- extern uint8_t hash_word_list_even[256][10];
- typedef struct {
- zrtp_test_id_t id;
- zrtp_test_id_t session_id;
- zrtp_test_id_t channel_id;
- zrtp_test_id_t endpoint_id;
- zrtp_stream_t *zrtp;
- uint16_t seq;
- zrtp_queue_t *input;
- zrtp_queue_t *output;
- unsigned zrtp_events_queueu[128];
- unsigned zrtp_events_count;
- } zrtp_test_stream_t;
- typedef struct {
- zrtp_test_id_t id;
- zrtp_test_id_t endpoint_id;
- zrtp_test_session_cfg_t cfg;
- zrtp_session_t *zrtp;
- zrtp_test_stream_t streams[ZRTP_MAX_STREAMS_PER_SESSION];
- unsigned streams_count;
- } zrtp_test_session_t;
- typedef struct {
- zrtp_test_id_t id;
- char name[ZRTP_TEST_STR_LEN];
- zrtp_zid_t zid;
- zrtp_test_endpoint_cfg_t cfg;
- zrtp_test_session_t sessions[K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT];
- unsigned sessions_count;
- zrtp_global_t *zrtp;
- unsigned is_running;
- zrtp_queue_t *input_queue;
- } zrtp_endpoint_t;
- typedef struct {
- zrtp_test_id_t id;
- zrtp_test_stream_t *left;
- zrtp_test_stream_t *right;
- unsigned is_attached;
- unsigned is_secure;
- } zrtp_test_channel_t;
- typedef struct zrtp_test_packet {
- uint32_t is_rtp; /*! Defines is packet RTP or RTCP */
- uint32_t length; /*! Packet Length in bytes */
- char body[1024]; /*! Packet body */
- } zrtp_test_packet_t;
- static zrtp_endpoint_t g_test_endpoints[K_ZRTP_TEST_MAX_ENDPOINTS];
- static unsigned g_test_endpoints_count = 0;
- static zrtp_test_channel_t g_test_channels[K_ZRTP_TEST_MAX_CHANNELS];
- static unsigned g_test_channels_count = 0;
- static int g_endpoints_counter = 7;
- static int g_channels_counter = 7;
- static int g_sessions_counter = 7;
- static int g_streams_counter = 7;
- zrtp_endpoint_t *zrtp_test_endpoint_by_id(zrtp_test_id_t id);
- zrtp_test_stream_t *zrtp_test_stream_by_id(zrtp_test_id_t id);
- zrtp_test_stream_t *zrtp_test_stream_by_peerid(zrtp_test_id_t id);
- zrtp_test_session_t *zrtp_test_session_by_id(zrtp_test_id_t id);
- zrtp_test_channel_t *zrtp_test_channel_by_id(zrtp_test_id_t id);
- /******************************************************************************
- * libzrtp interface implementation
- */
- static void on_zrtp_event(zrtp_stream_t *ctx, zrtp_protocol_event_t event) {
- zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
- zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
- stream->zrtp_events_queueu[stream->zrtp_events_count++] = event;
- }
- static void on_zrtp_secure(zrtp_stream_t *ctx) {
- zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
- zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
- zrtp_test_channel_t *channel = zrtp_test_channel_by_id(stream->channel_id);
- zrtp_test_stream_t *remote_stream = (channel->left == stream) ? channel->right : channel->left;
- if (stream->zrtp->state == ZRTP_STATE_SECURE &&
- remote_stream->zrtp->state == ZRTP_STATE_SECURE) {
- channel->is_secure = 1;
- }
- }
- static int on_send_packet(const zrtp_stream_t* ctx, char* message, unsigned int length) {
- zrtp_queue_elem_t* elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
- if (elem) {
- zrtp_test_packet_t* packet = (zrtp_test_packet_t*) elem->data;
- elem->size = length;
- packet->is_rtp = 1;
- packet->length = length;
- zrtp_memcpy(packet->body, message, length);
- zrtp_test_id_t *stream_id = zrtp_stream_get_userdata(ctx);
- zrtp_test_stream_t *stream = zrtp_test_stream_by_id(*stream_id);
- if (stream) {
- zrtp_test_queue_push(stream->output, elem);
- return zrtp_status_ok;
- } else {
- return zrtp_status_fail;
- }
- } else {
- return zrtp_status_alloc_fail;
- }
- }
- /******************************************************************************
- * Processing Loop
- */
- static zrtp_test_stream_t *get_stream_to_process_(zrtp_endpoint_t *endpoint) {
- zrtp_test_id_t all_streams[K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT*ZRTP_MAX_STREAMS_PER_SESSION];
- unsigned streams_count = 0;
- unsigned i, j;
- for (i=0; i<endpoint->sessions_count; i++) {
- for (j=0; j<endpoint->sessions[i].streams_count; j++) {
- zrtp_test_stream_t *stream = &endpoint->sessions[i].streams[j];
- if (stream->input && stream->output)
- all_streams[streams_count++] = stream->id;
- }
- }
- if (0 == streams_count)
- return NULL;
- zrtp_randstr(endpoint->zrtp, (unsigned char*)&i, sizeof(i));
- j = (unsigned)i;
- j = j % streams_count;
- //printf("trace>>> CHOOSE stream Endpoint=%u IDX=%u ID=%u\n", endpoint->id, j, all_streams[j]);
- return zrtp_test_stream_by_id(all_streams[j]);
- }
- #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
- DWORD WINAPI process_incoming(void *param)
- #else
- void *process_incoming(void *param)
- #endif
- {
- zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;
- while (the_endpoint->is_running) {
- zrtp_test_packet_t* packet = NULL;
- zrtp_queue_elem_t* elem = NULL;
- zrtp_status_t s = zrtp_status_fail;
- zrtp_test_stream_t *stream;
- int is_protocol = 0;
- // TODO: use peak to not to block processing if queue for this stream is empty
- elem = zrtp_test_queue_pop(the_endpoint->input_queue);
- if (!elem || elem->size <= 0) {
- if (elem) zrtp_sys_free(elem);
- break;
- }
- packet = (zrtp_test_packet_t*) elem->data;
- zrtp_test_id_t stream_id;
- {
- if (packet->is_rtp) {
- ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
- stream_id = zrtp_ntoh32(rtp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
- } else {
- ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
- stream_id = zrtp_ntoh32(rtcp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
- }
- stream = zrtp_test_stream_by_peerid(stream_id);
- }
- /*
- * Process incoming packet by libzrtp. Is this a RTP media packet - copy it to the buffer
- * to print out later.
- */
- if (packet->is_rtp) {
- s = zrtp_process_srtp(stream->zrtp, packet->body, &packet->length);
- } else {
- s = zrtp_process_srtcp(stream->zrtp, packet->body, &packet->length);
- }
- if (!is_protocol) {
- char *body;
- if (packet->is_rtp) {
- body = packet->body + sizeof(zrtp_rtp_hdr_t);
- body[packet->length - sizeof(zrtp_rtp_hdr_t)] = 0;
- } else {
- body = packet->body + sizeof(zrtp_rtcp_hdr_t);
- body[packet->length - sizeof(zrtp_rtcp_hdr_t)] = 0;
- }
- switch (s)
- {
- case zrtp_status_ok: {
- ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] OK. <%s> decrypted %d bytes.\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body, packet->length));
- } break;
- case zrtp_status_drop: {
- ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DROPPED. <%s>\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
- } break;
- case zrtp_status_fail: {
- ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DECRYPT FAILED. <%s>\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
- } break;
- default:
- break;
- }
- }
- zrtp_sys_free(elem);
- /*
- * When zrtp_stream is in the pending clear state and other side wants to send plain
- * traffic. We have to call zrtp_clear_stream().
- */
- if (stream->zrtp->state == ZRTP_STATE_PENDINGCLEAR) {
- zrtp_stream_clear(stream->zrtp);
- }
- }
- #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
- return 0;
- #else
- return NULL;
- #endif
- }
- #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
- DWORD WINAPI process_outgoing(void *param)
- #else
- void *process_outgoing(void *param)
- #endif
- {
- unsigned packets_counter = 0;
- zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;
- while (the_endpoint->is_running) {
- zrtp_test_stream_t* stream = NULL;
- unsigned i;
- zrtp_status_t s = zrtp_status_fail;
- zrtp_test_packet_t* packet;
- zrtp_queue_elem_t* elem;
- char* word = NULL;
- zrtp_sleep(K_ZRTP_TEST_RTP_RATE);
- /* Get random channel to operate with and select random peer */
- stream = get_stream_to_process_(the_endpoint);
- if (!stream) {
- continue;
- }
- elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
- if (!elem) {
- break;
- }
- packet = (zrtp_test_packet_t*) elem->data;
- packet->is_rtp = (packets_counter++ % 20); /* Every 20-th packet is RTCP */
- /*
- * Construct RTP/RTCP Packet
- */
- if (packet->is_rtp)
- {
- ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
- /* Fill RTP Header according to the specification */
- zrtp_memset(rtp_hdr, 0, sizeof(zrtp_rtp_hdr_t));
- rtp_hdr->version = 2; /* Current RTP version 2 */
- rtp_hdr->pt = 0; /* PCMU padding type */
- rtp_hdr->ssrc = zrtp_hton32(stream->id); /* Use stream Identifier as it's SSRC */
- if (stream->seq >= 0xFFFF) {
- stream->seq = 0;
- }
- rtp_hdr->seq = zrtp_hton16(stream->seq++);
- rtp_hdr->ts = zrtp_hton32((uint32_t)(zrtp_time_now()/1000));
- /* Get RTP body from PGP words lists */
- word = (char*)(i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
- zrtp_memcpy(packet->body + sizeof(zrtp_rtp_hdr_t), word, (uint32_t)strlen(word));
- packet->length = sizeof(zrtp_rtp_hdr_t) + (uint32_t)strlen(word);
- /* Process RTP media with libzrtp */
- s = zrtp_process_rtp(stream->zrtp, packet->body, &packet->length);
- }
- else {
- ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
- /* Fill RTCP Header according to the specification */
- rtcp_hdr->rc = 0;
- rtcp_hdr->version = 2;
- rtcp_hdr->ssrc = stream->id;
- /* Get RTP body from PGP words lists. Put RTCP marker at the beginning */
- zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t), "RTCP", 4);
- word = (char*)( i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
- zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t) + 4, word, (uint32_t)strlen(word));
- packet->length = sizeof(zrtp_rtcp_hdr_t) + (uint32_t)strlen(word) + 4;
- /* RTCP packets sould be 32 byes aligned */
- packet->length += (packet->length % 4) ? (4 - packet->length % 4) : 0;
- /* Process RTCP control with libzrtp */
- s = zrtp_process_rtcp(stream->zrtp, packet->body, &packet->length);
- }
- elem->size = packet->length;
- /* Handle zrtp_process_xxx() instructions */
- switch (s) {
- /* Put the packet to the queue ==> send packet to the other side pear */
- case zrtp_status_ok: {
- ZRTP_LOG(3, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] OK. <%s%s> encrypted %d bytes.\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, packet->is_rtp ? "" : "RTCP", word, packet->length));
- zrtp_test_queue_push(stream->output, elem);
- } break;
- case zrtp_status_drop: {
- ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] DROPPED.\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
- } break;
- case zrtp_status_fail: {
- ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] ENCRYPT FAILED.\n",
- zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
- } break;
- default:
- break;
- }
- if (zrtp_status_ok != s) {
- zrtp_sys_free(packet);
- }
- }
- #if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
- return 0;
- #else
- return NULL;
- #endif
- }
- /******************************************************************************
- * Test Engine Public API
- */
- void zrtp_test_endpoint_config_defaults(zrtp_test_endpoint_cfg_t* cfg) {
- zrtp_memset(cfg, 0, sizeof(zrtp_test_endpoint_cfg_t));
- cfg->generate_traffic = 0;
- /* It's always a good idea to start with default values */
- zrtp_config_defaults(&cfg->zrtp);
- /* Set ZRTP client id */
- strcpy(cfg->zrtp.client_id, "zrtp-test-engine");
- cfg->zrtp.is_mitm = 0;
- cfg->zrtp.lic_mode = ZRTP_LICENSE_MODE_ACTIVE;
- cfg->zrtp.cb.event_cb.on_zrtp_secure = &on_zrtp_secure;
- cfg->zrtp.cb.event_cb.on_zrtp_security_event = &on_zrtp_event;
- cfg->zrtp.cb.event_cb.on_zrtp_protocol_event = &on_zrtp_event;
- cfg->zrtp.cb.misc_cb.on_send_packet = &on_send_packet;
- }
- zrtp_status_t zrtp_test_endpoint_create(zrtp_test_endpoint_cfg_t* cfg,
- const char *name,
- zrtp_test_id_t* id) {
- zrtp_status_t s;
- unsigned i;
- char cache_file_path[ZRTP_TEST_STR_LEN];
- zrtp_endpoint_t *new_endpoint;
- if (g_test_endpoints_count >= K_ZRTP_TEST_MAX_ENDPOINTS)
- return zrtp_status_alloc_fail;
- new_endpoint = &g_test_endpoints[g_test_endpoints_count++];
- zrtp_memset(new_endpoint, 0, sizeof(zrtp_endpoint_t));
- /* Copy configuration, we will use it later to clean up after ourselves */
- zrtp_memcpy(&new_endpoint->cfg, cfg, sizeof(zrtp_test_endpoint_cfg_t));
- /* Remember endpoint name */
- strcpy(new_endpoint->name, name);
- new_endpoint->id = g_endpoints_counter++;
- /* Adjust cache file path so each endpoint will use it's own file. */
- sprintf(cache_file_path, "./%s_cache.dat", name);
- zrtp_zstrcpyc(ZSTR_GV(new_endpoint->cfg.zrtp.def_cache_path), cache_file_path);
- /* Initialize libzrtp engine for this endpoint */
- s = zrtp_init(&new_endpoint->cfg.zrtp, &new_endpoint->zrtp);
- if (zrtp_status_ok == s) {
- *id = new_endpoint->id;
- /* Generate random ZID */
- zrtp_randstr(new_endpoint->zrtp, new_endpoint->zid, sizeof(new_endpoint->zid));
- }
- /* Create Input queue*/
- s = zrtp_test_queue_create(&new_endpoint->input_queue);
- if (zrtp_status_ok != s) {
- return s;
- }
- /* Start processing loop */
- new_endpoint->is_running = 1;
- for (i = 0; i<K_ZRTP_TEST_PROCESSORS_COUNT; i++) {
- if (0 != zrtp_thread_create(process_incoming, new_endpoint)) {
- return zrtp_status_fail;
- }
- if (cfg->generate_traffic) {
- if (0 != zrtp_thread_create(process_outgoing, new_endpoint)) {
- return zrtp_status_fail;
- }
- }
- }
- return s;
- }
- zrtp_status_t zrtp_test_endpoint_destroy(zrtp_test_id_t id) {
- unsigned i;
- zrtp_status_t s = zrtp_status_ok;
- zrtp_endpoint_t *endpoint = zrtp_test_endpoint_by_id(id);
- endpoint->is_running = 0;
- if (endpoint->input_queue) {
- /* Push faked element to the queue to unlock incoming threads */
- for (i=0; i<K_ZRTP_TEST_PROCESSORS_COUNT; i++) {
- zrtp_queue_elem_t *elem = malloc(sizeof(zrtp_queue_elem_t));
- elem->size = 0;
- zrtp_test_queue_push(endpoint->input_queue, elem);
- }
- zrtp_sleep(0.5*1000);
- zrtp_test_queue_destroy(endpoint->input_queue);
- }
- for (i=0; i<20; i++) zrtp_sleep(100);
- if (endpoint) {
- /* Shut down libzrtp */
- if (endpoint->zrtp)
- s = zrtp_down(endpoint->zrtp);
- /* Clean-up ZRTP cache after ourselves */
- remove(endpoint->cfg.zrtp.def_cache_path.buffer);
- } else {
- s = zrtp_status_fail;
- }
- return s;
- }
- zrtp_status_t zrtp_test_stream_get(zrtp_test_id_t id,
- zrtp_test_stream_info_t* info) {
- zrtp_test_stream_t *stream = zrtp_test_stream_by_id(id);
- if (stream) {
- zrtp_status_t s;
- zrtp_memset(info, 0, sizeof(zrtp_test_stream_info_t));
- zrtp_memcpy(info->zrtp_events_queueu, stream->zrtp_events_queueu, sizeof(info->zrtp_events_queueu));
- info->zrtp_events_count = stream->zrtp_events_count;
- s = zrtp_stream_get(stream->zrtp, &info->zrtp);
- return s;
- } else {
- return zrtp_status_bad_param;
- }
- }
- void zrtp_test_session_config_defaults(zrtp_test_session_cfg_t* cfg) {
- cfg->streams_count = 1;
- cfg->role = ZRTP_SIGNALING_ROLE_UNKNOWN;
- cfg->is_enrollment = 0;
- zrtp_profile_defaults(&cfg->zrtp, NULL);
- }
- zrtp_status_t zrtp_test_session_create(zrtp_test_id_t endpoint_id,
- zrtp_test_session_cfg_t* cfg,
- zrtp_test_id_t* id) {
- zrtp_status_t s;
- unsigned i;
- zrtp_test_session_t *the_session;
- zrtp_endpoint_t *the_endpoint = zrtp_test_endpoint_by_id(endpoint_id);
- if (!the_endpoint)
- return zrtp_status_fail;
- if (the_endpoint->sessions_count >= K_ZRTP_TEST_MAX_SESSIONS_PER_ENDPOINT)
- return zrtp_status_fail;
- the_session = &the_endpoint->sessions[the_endpoint->sessions_count++];
- zrtp_memset(the_session, 0, sizeof(zrtp_test_session_t));
- zrtp_memcpy(&the_session->cfg, cfg, sizeof(zrtp_test_session_cfg_t));
- the_session->id = g_sessions_counter++;
- the_session->endpoint_id = endpoint_id;
- s = zrtp_session_init(the_endpoint->zrtp,
- &cfg->zrtp,
- the_endpoint->zid,
- cfg->role,
- &the_session->zrtp);
- if (zrtp_status_ok == s) {
- zrtp_session_set_userdata(the_session->zrtp, &the_session->id);
- for (i=0; i<cfg->streams_count; i++) {
- zrtp_test_stream_t *the_stream = &the_session->streams[i];
- zrtp_memset(the_stream, 0, sizeof(zrtp_test_stream_t));
- the_stream->id = g_streams_counter++;
- the_stream->session_id = the_session->id;
- the_stream->endpoint_id = endpoint_id;
- s = zrtp_stream_attach(the_session->zrtp, &the_stream->zrtp);
- if (zrtp_status_ok == s) {
- zrtp_stream_set_userdata(the_stream->zrtp, &the_stream->id);
- the_session->streams_count++;
- } else {
- break;
- }
- }
- }
- if (zrtp_status_ok == s) {
- *id = the_session->id;
- }
- return s;
- }
- zrtp_status_t zrtp_test_session_destroy(zrtp_test_id_t id) {
- zrtp_test_session_t *session = zrtp_test_session_by_id(id);
- if (session) {
- /* NOTE: we don't release session slots here due to nature of testing
- * engine: test configuration constructed from scratch for every single test.
- */
- zrtp_session_down(session->zrtp);
- }
- return zrtp_status_ok;
- }
- zrtp_status_t zrtp_test_session_get(zrtp_test_id_t id, zrtp_test_session_info_t* info) {
- zrtp_status_t s;
- zrtp_test_session_t *session = zrtp_test_session_by_id(id);
- if (session) {
- s = zrtp_session_get(session->zrtp, &info->zrtp);
- if (zrtp_status_ok == s) {
- unsigned i;
- for (i=0; i<session->streams_count; i++) {
- s = zrtp_test_stream_get(session->streams[i].id, &info->streams[i]);
- if (zrtp_status_ok != s)
- break;
- }
- }
- return s;
- } else {
- return zrtp_status_bad_param;
- }
- }
- zrtp_status_t zrtp_test_channel_create(zrtp_test_id_t left_id, zrtp_test_id_t right_id, zrtp_test_id_t* id) {
- zrtp_test_channel_t *the_channel;
- zrtp_test_stream_t *left = zrtp_test_stream_by_id(left_id);
- zrtp_test_stream_t *right = zrtp_test_stream_by_id(right_id);
- if (!left || !right)
- return zrtp_status_bad_param;
- if (g_test_channels_count >= K_ZRTP_TEST_MAX_CHANNELS)
- return zrtp_status_bad_param;
- zrtp_endpoint_t *left_endpoint = zrtp_test_endpoint_by_id(left->endpoint_id);
- zrtp_endpoint_t *right_endpoint = zrtp_test_endpoint_by_id(right->endpoint_id);
- the_channel = &g_test_channels[g_test_channels_count++];
- zrtp_memset(the_channel, 0, sizeof(zrtp_test_channel_t));
- the_channel->id = g_channels_counter++;
- the_channel->left = left;
- the_channel->right = right;
- left->output = right_endpoint->input_queue;
- left->input = left_endpoint->input_queue;
- right->output = left_endpoint->input_queue;
- right->input = right_endpoint->input_queue;
- right->channel_id = the_channel->id;
- left->channel_id = the_channel->id;
- the_channel->is_attached = 1;
- *id = the_channel->id;
- return zrtp_status_ok;
- }
- zrtp_status_t zrtp_test_channel_create2(zrtp_test_id_t left_session,
- zrtp_test_id_t right_session,
- unsigned stream_idx,
- zrtp_test_id_t *id) {
- zrtp_test_session_t *left = zrtp_test_session_by_id(left_session);
- zrtp_test_session_t *right = zrtp_test_session_by_id(right_session);
- if (!left || !right)
- return zrtp_status_bad_param;
- if (left->streams_count <= stream_idx || right->streams_count <= stream_idx)
- return zrtp_status_bad_param;
- return zrtp_test_channel_create(left->streams[stream_idx].id, right->streams[stream_idx].id, id);
- }
- zrtp_status_t zrtp_test_channel_destroy(zrtp_test_id_t id) {
- zrtp_test_channel_t *channel = zrtp_test_channel_by_id(id);
- if (!channel)
- return zrtp_status_bad_param;
- return zrtp_status_ok;
- }
- zrtp_status_t zrtp_test_channel_start(zrtp_test_id_t id) {
- zrtp_status_t s1, s2;
- zrtp_test_channel_t *the_channel = zrtp_test_channel_by_id(id);
- zrtp_test_session_t *the_session;
- the_session = zrtp_test_session_by_id(the_channel->left->session_id);
- if (the_session->cfg.is_enrollment)
- s1 = zrtp_stream_registration_start(the_channel->left->zrtp, the_channel->left->id); /* use stream Id as ssrc */
- else
- s1 = zrtp_stream_start(the_channel->left->zrtp, the_channel->left->id); /* use stream Id as ssrc */
- if (s1 == zrtp_status_ok) {
- the_session = zrtp_test_session_by_id(the_channel->right->session_id);
- if (the_session->cfg.is_enrollment)
- s2 = zrtp_stream_registration_start(the_channel->right->zrtp, the_channel->right->id);
- else
- s2 = zrtp_stream_start(the_channel->right->zrtp, the_channel->right->id);
- } else {
- return s1;
- }
- return s2;
- }
- zrtp_status_t zrtp_test_channel_get(zrtp_test_id_t id,
- zrtp_test_channel_info_t* info) {
- zrtp_test_channel_t *channel = zrtp_test_channel_by_id(id);
- if (channel) {
- zrtp_status_t s;
- zrtp_memset(info, 0, sizeof(zrtp_test_channel_info_t));
- s = zrtp_test_stream_get(channel->left->id, &info->left);
- if (zrtp_status_ok == s) {
- s = zrtp_test_stream_get(channel->right->id, &info->right);
- if (zrtp_status_ok == s) {
- info->is_secure = channel->is_secure;
- }
- }
- return s;
- } else {
- return zrtp_status_bad_param;
- }
- }
- /******************************************************************************
- * Helpers
- */
- zrtp_endpoint_t *zrtp_test_endpoint_by_id(zrtp_test_id_t id) {
- int i;
- if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
- for (i=0; i<g_test_endpoints_count; i++) {
- if (g_test_endpoints[i].id == id) {
- return &g_test_endpoints[i];
- }
- }
- return NULL;
- }
- zrtp_test_session_t *zrtp_test_session_by_id(zrtp_test_id_t id) {
- int i, j;
- if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
- for (i=0; i<g_test_endpoints_count; i++) {
- zrtp_endpoint_t *endpoint = &g_test_endpoints[i];
- if (endpoint->id == ZRTP_TEST_UNKNOWN_ID)
- continue;
- for (j=0; j<endpoint->sessions_count; j++) {
- if (endpoint->sessions[j].id == id) {
- return &endpoint->sessions[j];
- }
- }
- }
- return NULL;
- }
- zrtp_test_stream_t *zrtp_test_stream_by_id(zrtp_test_id_t id) {
- int i, j, k;
- if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
- for (i=0; i<g_test_endpoints_count; i++) {
- zrtp_endpoint_t *endpoint = &g_test_endpoints[i];
- if (endpoint->id == ZRTP_TEST_UNKNOWN_ID)
- continue;
- for (j=0; j<endpoint->sessions_count; j++) {
- zrtp_test_session_t *session = &endpoint->sessions[j];
- if (session->id == ZRTP_TEST_UNKNOWN_ID)
- continue;
- for (k=0; k<session->streams_count; k++) {
- if (session->streams[k].id == id) {
- return &session->streams[k];
- }
- }
- }
- }
- return NULL;
- }
- zrtp_test_channel_t *zrtp_test_channel_by_id(zrtp_test_id_t id) {
- int i;
- zrtp_test_channel_t *channel = NULL;
- if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
- for (i=0; i<g_test_channels_count; i++) {
- if (g_test_channels[i].id != ZRTP_TEST_UNKNOWN_ID && g_test_channels[i].id == id) {
- channel = &g_test_channels[i];
- break;
- }
- }
- return channel;
- }
- zrtp_test_stream_t *zrtp_test_stream_by_peerid(zrtp_test_id_t id) {
- int i;
- if (ZRTP_TEST_UNKNOWN_ID == id) return NULL;
- for (i=0; i<g_test_channels_count; i++) {
- if (g_test_channels[i].id != ZRTP_TEST_UNKNOWN_ID) {
- if (g_test_channels[i].left->id == id)
- return g_test_channels[i].right;
- else if (g_test_channels[i].right->id == id)
- return g_test_channels[i].left;
- }
- }
- return NULL;
- }
- zrtp_test_id_t zrtp_test_session_get_stream_by_idx(zrtp_test_id_t session_id, unsigned idx) {
- zrtp_test_session_t *session = zrtp_test_session_by_id(session_id);
- if (session && session->streams_count > idx) {
- return session->streams[idx].id;
- } else {
- return ZRTP_TEST_UNKNOWN_ID;
- }
- }
- zrtp_stream_t *zrtp_stream_for_test_stream(zrtp_test_id_t stream_id) {
- zrtp_test_stream_t *stream = zrtp_test_stream_by_id(stream_id);
- if (stream) {
- return stream->zrtp;
- } else {
- return NULL;
- }
- }
- unsigned zrtp_stream_did_event_receive(zrtp_test_id_t stream_id, unsigned event) {
- unsigned i;
- zrtp_test_stream_info_t stream_info;
- zrtp_test_stream_get(stream_id, &stream_info);
- for (i=0; i<stream_info.zrtp_events_count; i++) {
- if (stream_info.zrtp_events_queueu[i] == event)
- break;
- }
- return (i != stream_info.zrtp_events_count);
- }
|