/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ /**@CFILE test_soa.c * @brief High-level tester for Sofia SDP Offer/Answer Engine * * @author Pekka Pessi * * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi */ #include "config.h" #include #include #include #include #if HAVE_ALARM #include #include #endif struct context; #define SOA_MAGIC_T struct context #include "sofia-sip/soa.h" #include "sofia-sip/soa_tag.h" #include "sofia-sip/soa_add.h" #include #include #include extern su_log_t soa_log[]; char const name[] = "test_soa"; int tstflags = 0; #define TSTFLAGS tstflags #include #if HAVE_FUNC #elif HAVE_FUNCTION #define __func__ __FUNCTION__ #else #define __func__ name #endif #define NONE ((void*)-1) struct context { su_home_t home[1]; su_root_t *root; struct { soa_session_t *a; soa_session_t *b; } asynch; soa_session_t *a; soa_session_t *b; soa_session_t *completed; }; int test_api_completed(struct context *arg, soa_session_t *session) { return 0; } int test_api_errors(struct context *ctx) { BEGIN(); char const *phrase = NULL; char const *null = NULL; TEST_1(!soa_create("default", NULL, NULL)); TEST_1(!soa_clone(NULL, NULL, NULL)); TEST_VOID(soa_destroy(NULL)); TEST_1(-1 == soa_set_params(NULL, TAG_END())); TEST_1(-1 == soa_get_params(NULL, TAG_END())); TEST_1(!soa_get_paramlist(NULL, TAG_END())); TEST(soa_error_as_sip_response(NULL, &phrase), 500); TEST_S(phrase, "Internal Server Error"); TEST_1(soa_error_as_sip_reason(NULL)); TEST_1(!soa_media_features(NULL, 0, NULL)); TEST_1(!soa_sip_require(NULL)); TEST_1(!soa_sip_supported(NULL)); TEST_1(-1 == soa_remote_sip_features(NULL, &null, &null)); TEST_1(soa_set_capability_sdp(NULL, NULL, NULL, -1) < 0); TEST_1(soa_set_remote_sdp(NULL, NULL, NULL, -1) < 0); TEST_1(soa_set_user_sdp(NULL, NULL, NULL, -1) < 0); TEST_1(soa_get_capability_sdp(NULL, NULL, NULL, NULL) < 0); TEST_1(soa_get_remote_sdp(NULL, NULL, NULL, NULL) < 0); TEST_1(soa_get_user_sdp(NULL, NULL, NULL, NULL) < 0); TEST_1(soa_get_local_sdp(NULL, NULL, NULL, NULL) < 0); TEST_1(-1 == soa_generate_offer(NULL, 0, test_api_completed)); TEST_1(-1 == soa_generate_answer(NULL, test_api_completed)); TEST_1(-1 == soa_process_answer(NULL, test_api_completed)); TEST_1(-1 == soa_process_reject(NULL, test_api_completed)); TEST(soa_activate(NULL, "both"), -1); TEST(soa_deactivate(NULL, "both"), -1); TEST_VOID(soa_terminate(NULL, "both")); TEST_1(!soa_is_complete(NULL)); TEST_1(!soa_init_offer_answer(NULL)); TEST(soa_is_audio_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_video_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_image_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_chat_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_audio_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_video_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_image_active(NULL), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_chat_active(NULL), SOA_ACTIVE_DISABLED); END(); } int test_soa_tags(struct context *ctx) { BEGIN(); su_home_t home[1] = { SU_HOME_INIT(home) }; tagi_t *t; tagi_t const soafilter[] = { { TAG_FILTER(soa_tag_filter) }, { TAG_NULL() } }; t = tl_filtered_tlist(home, soafilter, SIPTAG_FROM_STR("sip:my.domain"), SOATAG_USER_SDP_STR("v=0"), SOATAG_HOLD("*"), TAG_END()); TEST_1(t); TEST_P(t[0].t_tag, soatag_user_sdp_str); TEST_P(t[1].t_tag, soatag_hold); TEST_1(t[2].t_tag == NULL || t[2].t_tag == tag_null); su_home_deinit(home); END(); } int test_init(struct context *ctx, char *argv[]) { BEGIN(); int n; ctx->root = su_root_create(ctx); TEST_1(ctx->root); ctx->asynch.a = soa_create("asynch", ctx->root, ctx); TEST_1(!ctx->asynch.a); #if 0 TEST_1(!soa_find("asynch")); TEST_1(soa_find("default")); n = soa_add("asynch", &soa_asynch_actions); TEST(n, 0); TEST_1(soa_find("asynch")); ctx->asynch.a = soa_create("asynch", ctx->root, ctx); TEST_1(ctx->asynch.a); ctx->asynch.b = soa_create("asynch", ctx->root, ctx); TEST_1(ctx->asynch.b); #endif /* Create asynchronous endpoints */ ctx->a = soa_create("static", ctx->root, ctx); TEST_1(!ctx->a); TEST_1(!soa_find("static")); TEST_1(soa_find("default")); n = soa_add("static", &soa_default_actions); TEST(n, 0); TEST_1(soa_find("static")); ctx->a = soa_create("static", ctx->root, ctx); TEST_1(ctx->a); ctx->b = soa_create("static", ctx->root, ctx); TEST_1(ctx->b); END(); } int test_params(struct context *ctx) { BEGIN(); int n; int af; char const *address; char const *hold; int rtp_select, rtp_sort; int rtp_mismatch; int srtp_enable, srtp_confidentiality, srtp_integrity; soa_session_t *a = ctx->a, *b = ctx->b; n = soa_set_params(a, TAG_END()); TEST(n, 0); n = soa_set_params(b, TAG_END()); TEST(n, 0); af = -42; address = NONE; hold = NONE; rtp_select = -1, rtp_sort = -1, rtp_mismatch = -1; srtp_enable = -1, srtp_confidentiality = -1, srtp_integrity = -1; TEST(soa_get_params(a, SOATAG_AF_REF(af), SOATAG_ADDRESS_REF(address), SOATAG_HOLD_REF(hold), SOATAG_RTP_SELECT_REF(rtp_select), SOATAG_RTP_SORT_REF(rtp_sort), SOATAG_RTP_MISMATCH_REF(rtp_mismatch), SOATAG_SRTP_ENABLE_REF(srtp_enable), SOATAG_SRTP_CONFIDENTIALITY_REF(srtp_confidentiality), SOATAG_SRTP_INTEGRITY_REF(srtp_integrity), TAG_END()), 9); TEST(af, SOA_AF_ANY); TEST_P(address, 0); TEST_P(hold, 0); TEST(rtp_select, SOA_RTP_SELECT_SINGLE); TEST(rtp_sort, SOA_RTP_SORT_DEFAULT); TEST(rtp_mismatch, 0); TEST(srtp_enable, 0); TEST(srtp_confidentiality, 0); TEST(srtp_integrity, 0); TEST(soa_set_params(a, SOATAG_AF(SOA_AF_IP4_IP6), SOATAG_ADDRESS("127.0.0.1"), SOATAG_HOLD("audio"), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), SOATAG_RTP_SORT(SOA_RTP_SORT_LOCAL), SOATAG_RTP_MISMATCH(1), SOATAG_SRTP_ENABLE(1), SOATAG_SRTP_CONFIDENTIALITY(1), SOATAG_SRTP_INTEGRITY(1), TAG_END()), 9); TEST(soa_get_params(a, SOATAG_AF_REF(af), SOATAG_ADDRESS_REF(address), SOATAG_HOLD_REF(hold), SOATAG_RTP_SELECT_REF(rtp_select), SOATAG_RTP_SORT_REF(rtp_sort), SOATAG_RTP_MISMATCH_REF(rtp_mismatch), SOATAG_SRTP_ENABLE_REF(srtp_enable), SOATAG_SRTP_CONFIDENTIALITY_REF(srtp_confidentiality), SOATAG_SRTP_INTEGRITY_REF(srtp_integrity), TAG_END()), 9); TEST(af, SOA_AF_IP4_IP6); TEST_S(address, "127.0.0.1"); TEST_S(hold, "audio"); TEST(rtp_select, SOA_RTP_SELECT_ALL); TEST(rtp_sort, SOA_RTP_SORT_LOCAL); TEST(rtp_mismatch, 1); TEST(srtp_enable, 1); TEST(srtp_confidentiality, 1); TEST(srtp_integrity, 1); /* Restore defaults */ TEST(soa_set_params(a, SOATAG_AF(SOA_AF_IP4_IP6), SOATAG_ADDRESS(NULL), SOATAG_HOLD(NULL), SOATAG_RTP_SELECT(SOA_RTP_SELECT_SINGLE), SOATAG_RTP_SORT(SOA_RTP_SORT_DEFAULT), SOATAG_RTP_MISMATCH(0), SOATAG_SRTP_ENABLE(0), SOATAG_SRTP_CONFIDENTIALITY(0), SOATAG_SRTP_INTEGRITY(0), TAG_END()), 9); END(); } int test_completed(struct context *ctx, soa_session_t *session) { ctx->completed = session; su_root_break(ctx->root); return 0; } int test_static_offer_answer(struct context *ctx) { BEGIN(); int n; soa_session_t *a, *b; char const *caps = NONE, *offer = NONE, *answer = NONE; isize_t capslen = -1, offerlen = -1, answerlen = -1; su_home_t home[1] = { SU_HOME_INIT(home) }; char const a_caps[] = "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 0 RTP/AVP 0 8\r\n"; char const b_caps[] = "m=audio 5004 RTP/AVP 96 8\n" "m=rtpmap:96 GSM/8000\n"; TEST(soa_set_capability_sdp(ctx->a, 0, "m=audio 0 RTP/AVP 0 8", -1), 1); TEST(soa_set_capability_sdp(ctx->a, 0, a_caps, strlen(a_caps)), 1); TEST(soa_get_capability_sdp(ctx->a, NULL, &caps, &capslen), 1); TEST_1(caps != NULL && caps != NONE); TEST_1(capslen > 0); TEST(soa_set_user_sdp(ctx->b, 0, b_caps, strlen(b_caps)), 1); TEST(soa_get_capability_sdp(ctx->a, NULL, &caps, &capslen), 1); TEST_1(a = soa_clone(ctx->a, ctx->root, ctx)); TEST_1(b = soa_clone(ctx->b, ctx->root, ctx)); n = soa_get_local_sdp(a, NULL, &offer, &offerlen); TEST(n, 0); n = soa_set_user_sdp(a, 0, "m=audio 5004 RTP/AVP 0 8", -1); TEST(n, 1); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, NULL, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_get_local_sdp(b, NULL, &answer, &answerlen); TEST(n, 0); n = soa_set_params(b, SOATAG_LOCAL_SDP_STR("m=audio 5004 RTP/AVP 8"), SOATAG_AF(SOA_AF_IP4_ONLY), SOATAG_ADDRESS("1.2.3.4"), TAG_END()); n = soa_generate_answer(b, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); n = soa_get_local_sdp(b, NULL, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); TEST_1(strstr(answer, "c=IN IP4 1.2.3.4")); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_image_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_chat_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_video_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_image_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_chat_active(a), SOA_ACTIVE_DISABLED); /* 'A' will put call on hold */ offer = NONE; TEST(soa_set_params(a, SOATAG_HOLD("*"), TAG_END()), 1); TEST(soa_generate_offer(a, 1, test_completed), 0); TEST(soa_get_local_sdp(a, NULL, &offer, &offerlen), 1); TEST_1(offer != NULL && offer != NONE); TEST_1(strstr(offer, "a=sendonly")); TEST(soa_set_remote_sdp(b, 0, offer, offerlen), 1); TEST(soa_generate_answer(b, test_completed), 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1); TEST_1(answer != NULL && answer != NONE); TEST_1(strstr(answer, "a=recvonly")); TEST(soa_set_remote_sdp(a, 0, answer, -1), 1); TEST(soa_process_answer(a, test_completed), 0); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDONLY); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDONLY); /* 'A' will release hold. */ TEST(soa_set_params(a, SOATAG_HOLD(NULL), TAG_END()), 1); TEST(soa_generate_offer(a, 1, test_completed), 0); TEST(soa_get_local_sdp(a, NULL, &offer, &offerlen), 1); TEST_1(offer != NULL && offer != NONE); TEST_1(!strstr(offer, "a=sendonly")); TEST(soa_set_remote_sdp(b, 0, offer, offerlen), 1); TEST(soa_generate_answer(b, test_completed), 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1); TEST_1(answer != NULL && answer != NONE); TEST_1(!strstr(answer, "a=recvonly")); TEST(soa_set_remote_sdp(a, 0, answer, -1), 1); TEST(soa_process_answer(a, test_completed), 0); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); /* 'A' will put B on hold but this time with c=IN IP4 0.0.0.0 */ TEST(soa_set_params(a, SOATAG_HOLD("*"), TAG_END()), 1); TEST(soa_generate_offer(a, 1, test_completed), 0); { sdp_session_t const *o_sdp; sdp_session_t *sdp; sdp_printer_t *p; sdp_connection_t *c; TEST(soa_get_local_sdp(a, &o_sdp, NULL, NULL), 1); TEST_1(o_sdp != NULL && o_sdp != NONE); TEST_1(sdp = sdp_session_dup(home, o_sdp)); /* Remove mode, change c=, encode offer */ if (sdp->sdp_media->m_connections) c = sdp->sdp_media->m_connections; else c = sdp->sdp_connection; TEST_1(c); c->c_address = "0.0.0.0"; TEST_1(p = sdp_print(home, sdp, NULL, 0, sdp_f_realloc)); TEST_1(sdp_message(p)); offer = sdp_message(p); offerlen = strlen(offer); } TEST(soa_set_remote_sdp(b, 0, offer, -1), 1); TEST(soa_generate_answer(b, test_completed), 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1); TEST_1(answer != NULL && answer != NONE); TEST_1(strstr(answer, "a=recvonly")); TEST(soa_set_remote_sdp(a, 0, answer, -1), 1); TEST(soa_process_answer(a, test_completed), 0); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDONLY); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDONLY); TEST(soa_is_audio_active(b), SOA_ACTIVE_RECVONLY); TEST(soa_is_remote_audio_active(b), SOA_ACTIVE_RECVONLY); /* 'A' will propose adding video. */ /* 'B' will reject. */ TEST(soa_set_params(a, SOATAG_HOLD(NULL), /* 'A' will release hold. */ SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8\r\n" "m=video 5006 RTP/AVP 34\r\n"), TAG_END()), 2); TEST(soa_generate_offer(a, 1, test_completed), 0); TEST(soa_get_local_sdp(a, NULL, &offer, &offerlen), 1); TEST_1(offer != NULL && offer != NONE); TEST_1(!strstr(offer, "a=sendonly")); TEST_1(strstr(offer, "m=video")); TEST(soa_set_remote_sdp(b, 0, offer, offerlen), 1); TEST(soa_generate_answer(b, test_completed), 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST(soa_get_local_sdp(b, NULL, &answer, &answerlen), 1); TEST_1(answer != NULL && answer != NONE); TEST_1(!strstr(answer, "a=recvonly")); TEST_1(strstr(answer, "m=video")); TEST(soa_set_remote_sdp(a, 0, answer, -1), 1); TEST(soa_process_answer(a, test_completed), 0); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_REJECTED); { /* Test tags */ sdp_session_t const *l = NULL, *u = NULL, *r = NULL; sdp_media_t const *m; TEST(soa_get_params(b, SOATAG_LOCAL_SDP_REF(l), SOATAG_USER_SDP_REF(u), SOATAG_REMOTE_SDP_REF(r), TAG_END()), 3); TEST_1(l); TEST_1(u); TEST_1(r); TEST_1(m = l->sdp_media); TEST(m->m_type, sdp_media_audio); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST(m->m_type, sdp_media_video); TEST_1(m->m_rejected); } /* 'B' will now propose adding video. */ /* 'A' will accept. */ TEST(soa_set_params(b, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8\r\n" "m=video 5006 RTP/AVP 34\r\n"), TAG_END()), 1); TEST(soa_generate_offer(b, 1, test_completed), 0); TEST(soa_get_local_sdp(b, NULL, &offer, &offerlen), 1); TEST_1(offer != NULL && offer != NONE); TEST_1(!strstr(offer, "b=sendonly")); TEST_1(strstr(offer, "m=video")); TEST(soa_set_remote_sdp(a, 0, offer, offerlen), 1); TEST(soa_generate_answer(a, test_completed), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_get_local_sdp(a, NULL, &answer, &answerlen), 1); TEST_1(answer != NULL && answer != NONE); TEST_1(!strstr(answer, "b=recvonly")); TEST_1(strstr(answer, "m=video")); TEST(soa_set_remote_sdp(b, 0, answer, -1), 1); TEST(soa_process_answer(b, test_completed), 0); TEST(soa_activate(b, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_SENDRECV); TEST_VOID(soa_terminate(a, NULL)); TEST(soa_is_audio_active(a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_DISABLED); TEST_VOID(soa_terminate(b, NULL)); TEST_VOID(soa_destroy(a)); TEST_VOID(soa_destroy(b)); su_home_deinit(home); END(); } int test_codec_selection(struct context *ctx) { BEGIN(); int n; soa_session_t *a, *b; char const *offer = NONE, *answer = NONE; isize_t offerlen = -1, answerlen = -1; sdp_session_t const *a_sdp, *b_sdp; sdp_media_t const *m; sdp_rtpmap_t const *rm; char const a_caps[] = "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 97\r\n" "a=rtpmap:97 GSM/8000\n" ; char const b_caps[] = "m=audio 5004 RTP/AVP 96 97\n" "a=rtpmap:96 G7231/8000\n" "a=rtpmap:97 G729/8000\n"; TEST_1(a = soa_create("static", ctx->root, ctx)); TEST_1(b = soa_create("static", ctx->root, ctx)); TEST(soa_set_user_sdp(a, 0, a_caps, strlen(a_caps)), 1); TEST(soa_set_user_sdp(b, 0, b_caps, strlen(b_caps)), 1); TEST(soa_set_params(a, SOATAG_AUDIO_AUX("cn telephone-event"), TAG_END()), 1); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, NULL, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_get_local_sdp(b, NULL, &answer, &answerlen); TEST(n, 0); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_REJECTED); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_REJECTED); TEST_1(m = b_sdp->sdp_media); TEST_1(m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G7231"); /* Not using payload type 97 from offer */ TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 98); TEST_S(rm->rm_encoding, "G729"); TEST_1(!rm->rm_next); /* ---------------------------------------------------------------------- */ /* Re-O/A: A generates new SDP */ n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 0); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); /* Re-O/A: no-one regenerates new SDP */ n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 0); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 0); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); /* ---------------------------------------------------------------------- */ /* Re-O/A: accept media without common codecs */ /* Accept media without common codecs */ TEST_1(soa_set_params(a, SOATAG_RTP_MISMATCH(1), TAG_END())); TEST_1(soa_set_params(b, SOATAG_RTP_MISMATCH(1), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G7231"); /* Not using payload type 97 from offer */ TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 98); TEST_S(rm->rm_encoding, "G729"); TEST_1(!rm->rm_next); /* ---------------------------------------------------------------------- */ /* Re-O/A: add a common codec */ /* Accept media without common codecs */ TEST_1(soa_set_params(a, SOATAG_RTP_MISMATCH(0), SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 96 3 127\r\n" "a=rtpmap:96 G729/8000\n" "a=rtpmap:127 CN/8000\n" ), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_END())); TEST_1(soa_set_params(b, SOATAG_RTP_MISMATCH(0), SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5004 RTP/AVP 96 3 97 111\r\n" "a=rtpmap:96 G7231/8000\n" "a=rtpmap:97 G729/8000\n" "a=rtpmap:111 telephone-event/8000\n" "a=fmtp:111 0-15\n" ), SOATAG_AUDIO_AUX("cn telephone-event"), SOATAG_RTP_SORT(SOA_RTP_SORT_LOCAL), SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, NULL, NULL); TEST(n, 1); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 3); TEST_S(rm->rm_encoding, "GSM"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G729"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 0); TEST_S(rm->rm_encoding, "PCMU"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 8); TEST_S(rm->rm_encoding, "PCMA"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 127); TEST_S(rm->rm_encoding, "CN"); TEST_1(!rm->rm_next); TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 3); TEST_S(rm->rm_encoding, "GSM"); /* Using payload type 96 from offer */ TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G729"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 111); TEST_S(rm->rm_encoding, "telephone-event"); TEST_1(!rm->rm_next); /* ---------------------------------------------------------------------- */ /* Re-O/A: prune down to single codec. */ TEST_1(soa_set_params(a, SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 97 96 127\r\n" "a=rtpmap:96 G729/8000\n" "a=rtpmap:97 GSM/8000\n" "a=rtpmap:127 CN/8000\n" ), SOATAG_RTP_MISMATCH(0), SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON), TAG_END())); TEST_1(soa_set_params(b, SOATAG_RTP_MISMATCH(0), SOATAG_RTP_SORT(SOA_RTP_SORT_LOCAL), SOATAG_RTP_SELECT(SOA_RTP_SELECT_SINGLE), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 97); TEST_S(rm->rm_encoding, "GSM"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 127); TEST_S(rm->rm_encoding, "CN"); TEST_1(!rm->rm_next); /* Answering end matches payload types then sorts by local preference, then select best codec => GSM with pt 97 */ TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 97); TEST_S(rm->rm_encoding, "GSM"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 111); TEST_S(rm->rm_encoding, "telephone-event"); TEST_1(!rm->rm_next); /* ---------------------------------------------------------------------- */ /* Re-O/A: A generates new SDP offer with single codec only */ n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 97); TEST_S(rm->rm_encoding, "GSM"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 127); TEST_S(rm->rm_encoding, "CN"); TEST_1(!rm->rm_next); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); /* Answer from B is identical to previous one */ n = soa_generate_answer(b, test_completed); TEST(n, 0); n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 0); n = soa_process_answer(a, test_completed); TEST(n, 0); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); /* ---------------------------------------------------------------------- */ /* Add new media - without common codecs */ TEST_1(soa_set_params(a, SOATAG_RTP_MISMATCH(0), SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 96 3 127\r\n" "a=rtpmap:96 G729/8000\n" "a=rtpmap:127 CN/8000\n" "m=video 5010 RTP/AVP 31\r\n" "m=audio 6008 RTP/SAVP 3\n" ), TAG_END())); TEST_1(soa_set_params(b, SOATAG_RTP_MISMATCH(0), SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5004 RTP/AVP 96 3 97 111\r\n" "a=rtpmap:96 G7231/8000\n" "a=rtpmap:97 G729/8000\n" "a=rtpmap:111 telephone-event/8000\n" "a=fmtp:111 0-15\n" "m=audio 6004 RTP/SAVP 96\n" "a=rtpmap:96 G729/8000\n" "m=video 5006 RTP/AVP 34\n" ), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); /* Answer from B rejects video */ n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_REJECTED); TEST(soa_is_remote_video_active(a), SOA_ACTIVE_REJECTED); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(m->m_rejected); TEST_1(m = m->m_next); TEST_1(m->m_rejected); TEST_1(!m->m_next); TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(m->m_rejected); /* Rejected but tell what we support */ TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 34); TEST_S(rm->rm_encoding, "H263"); TEST_1(m = m->m_next); TEST_1(m->m_rejected); TEST_1(!m->m_next); /* ---------------------------------------------------------------------- */ /* A adds H.263 to video */ TEST_1(soa_set_params(a, SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 96 3 127\r\n" "a=rtpmap:96 G729/8000\n" "a=rtpmap:127 CN/8000\n" "m=video 5010 RTP/AVP 31 34\r\n" "m=audio 6008 RTP/SAVP 3\n" ), TAG_END())); /* B adds GSM to SRTP */ TEST_1(soa_set_params(b, SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5004 RTP/AVP 96 3 97 111\r\n" "a=rtpmap:96 G7231/8000\n" "a=rtpmap:97 G729/8000\n" "a=rtpmap:111 telephone-event/8000\n" "a=fmtp:111 0-15\n" "m=audio 6004 RTP/SAVP 96 3\n" "a=rtpmap:96 G729/8000\n" "m=video 5006 RTP/AVP 34\n" ), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); /* Answer from B now accepts video */ n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_video_active(a), SOA_ACTIVE_SENDRECV); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 34); TEST_S(rm->rm_encoding, "H263"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 34); TEST_S(rm->rm_encoding, "H263"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); /* ---------------------------------------------------------------------- */ /* A drops GSM support */ TEST_1(soa_set_params(a, SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5008 RTP/AVP 0 8 96 127\r\n" "a=rtpmap:96 G729/8000\n" "a=rtpmap:127 CN/8000\n" "m=video 5010 RTP/AVP 31 34\r\n" "m=audio 6008 RTP/SAVP 3\n" ), TAG_END())); /* B adds GSM to SRTP, changes IP address */ TEST_1(soa_set_params(b, SOATAG_USER_SDP_STR( "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.3\r\n" "m=audio 5004 RTP/AVP 96 3 97 111\r\n" "a=rtpmap:96 G7231/8000\n" "a=rtpmap:97 G729/8000\n" "a=rtpmap:111 telephone-event/8000\n" "a=fmtp:111 0-15\n" "m=audio 6004 RTP/SAVP 96 3\n" "a=rtpmap:96 G729/8000\n" "m=video 5006 RTP/AVP 34\n" ), TAG_END())); n = soa_generate_offer(a, 1, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(offer != NULL && offer != NONE); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); n = soa_set_remote_sdp(b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(b, test_completed); TEST(n, 0); /* Answer from B now accepts video */ n = soa_get_local_sdp(b, &b_sdp, &answer, &answerlen); TEST(n, 1); TEST_1(answer != NULL && answer != NONE); /* Check that updated c= line is propagated */ TEST_1(b_sdp->sdp_connection); TEST_S(b_sdp->sdp_connection->c_address, "127.0.0.3"); n = soa_set_remote_sdp(a, 0, answer, -1); TEST(n, 1); n = soa_process_answer(a, test_completed); TEST(n, 0); n = soa_get_local_sdp(a, &a_sdp, &offer, &offerlen); TEST(n, 1); TEST_1(soa_is_complete(b)); TEST(soa_activate(b, NULL), 0); TEST_1(soa_is_complete(a)); TEST(soa_activate(a, NULL), 0); TEST(soa_is_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_audio_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_video_active(a), SOA_ACTIVE_SENDRECV); TEST_1(m = a_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G729"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 127); TEST_S(rm->rm_encoding, "CN"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 34); TEST_S(rm->rm_encoding, "H263"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); TEST_1(m = b_sdp->sdp_media); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 96); TEST_S(rm->rm_encoding, "G729"); TEST_1(rm = rm->rm_next); TEST(rm->rm_pt, 111); TEST_S(rm->rm_encoding, "telephone-event"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(rm = m->m_rtpmaps); TEST(rm->rm_pt, 34); TEST_S(rm->rm_encoding, "H263"); TEST_1(m = m->m_next); TEST_1(!m->m_rejected); TEST_1(!m->m_next); /* ---------------------------------------------------------------------- */ TEST_VOID(soa_terminate(a, NULL)); TEST_VOID(soa_terminate(b, NULL)); TEST_VOID(soa_destroy(a)); TEST_VOID(soa_destroy(b)); END(); } int test_asynch_offer_answer(struct context *ctx) { BEGIN(); #if 0 int n; char const *caps = NONE, *offer = NONE, *answer = NONE; isize_t capslen = -1, offerlen = -1, answerlen = -1; char const a[] = "v=0\r\n" "o=left 219498671 2 IN IP4 127.0.0.2\r\n" "c=IN IP4 127.0.0.2\r\n" "m=audio 5004 RTP/AVP 0 8\r\n"; char const b[] = "v=0\n" "o=right 93298573265 321974 IN IP4 127.0.0.3\n" "c=IN IP4 127.0.0.3\n" "m=audio 5006 RTP/AVP 96\n" "m=rtpmap:96 GSM/8000\n"; n = soa_set_capability_sdp(ctx->asynch.a, 0, "m=audio 5004 RTP/AVP 0 8", -1); TEST(n, 1); n = soa_set_capability_sdp(ctx->asynch.a, 0, a, strlen(a)); TEST(n, 1); n = soa_get_capability_sdp(ctx->asynch.a, 0, &caps, &capslen); TEST(n, 1); TEST_1(caps != NULL && caps != NONE); TEST_1(capslen > 0); n = soa_set_capability_sdp(ctx->asynch.b, 0, b, strlen(b)); TEST(n, 1); n = soa_generate_offer(ctx->asynch.a, 1, test_completed); TEST(n, 1); su_root_run(ctx->root); TEST(ctx->completed, ctx->asynch.a); ctx->completed = NULL; n = soa_get_local_sdp(ctx->asynch.a, 0, &offer, &offerlen); TEST(n, 1); n = soa_set_remote_sdp(ctx->asynch.b, 0, offer, offerlen); TEST(n, 1); n = soa_generate_answer(ctx->asynch.b, test_completed); TEST(n, 1); su_root_run(ctx->root); TEST(ctx->completed, ctx->asynch.b); ctx->completed = NULL; TEST_1(soa_is_complete(ctx->asynch.b)); TEST(soa_activate(ctx->asynch.b, NULL), 0); n = soa_get_local_sdp(ctx->asynch.b, 0, &answer, &answerlen); TEST(n, 1); n = soa_set_remote_sdp(ctx->asynch.a, 0, answer, answerlen); TEST(n, 1); n = soa_process_answer(ctx->asynch.a, test_completed); TEST(n, 1); su_root_run(ctx->root); TEST(ctx->completed, ctx->asynch.a); ctx->completed = NULL; TEST_1(soa_is_complete(ctx->asynch.a)); TEST(soa_activate(ctx->asynch.a, NULL), 0); TEST(soa_is_audio_active(ctx->asynch.a), SOA_ACTIVE_SENDRECV); TEST(soa_is_video_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_image_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_chat_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_audio_active(ctx->asynch.a), SOA_ACTIVE_SENDRECV); TEST(soa_is_remote_video_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_image_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_chat_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_deactivate(ctx->asynch.a, NULL), 0); TEST(soa_deactivate(ctx->asynch.b, NULL), 0); TEST_VOID(soa_terminate(ctx->asynch.a, NULL)); TEST(soa_is_audio_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST(soa_is_remote_audio_active(ctx->asynch.a), SOA_ACTIVE_DISABLED); TEST_VOID(soa_terminate(ctx->asynch.b, NULL)); #endif END(); } int test_deinit(struct context *ctx) { BEGIN(); END(); } #if HAVE_ALARM static RETSIGTYPE sig_alarm(int s) { fprintf(stderr, "%s: FAIL! test timeout!\n", name); exit(1); } #endif void usage(void) { fprintf(stderr, "usage: %s [-v|-q] [-l level] [-p outbound-proxy-uri]\n", name); exit(1); } int main(int argc, char *argv[]) { int retval = 0, quit_on_single_failure = 0; int i, o_attach = 0, o_alarm = 1; struct context ctx[1] = {{{ SU_HOME_INIT(ctx) }}}; for (i = 1; argv[i]; i++) { if (strcmp(argv[i], "-v") == 0) tstflags |= tst_verbatim; else if (strcmp(argv[i], "-q") == 0) tstflags &= ~tst_verbatim; else if (strcmp(argv[i], "-1") == 0) quit_on_single_failure = 1; else if (strncmp(argv[i], "-l", 2) == 0) { int level = 3; char *rest = NULL; if (argv[i][2]) level = strtol(argv[i] + 2, &rest, 10); else if (argv[i + 1]) level = strtol(argv[i + 1], &rest, 10), i++; else level = 3, rest = ""; if (rest == NULL || *rest) usage(); su_log_set_level(soa_log, level); } else if (strcmp(argv[i], "--attach") == 0) { o_attach = 1; } else if (strcmp(argv[i], "--no-alarm") == 0) { o_alarm = 0; } else if (strcmp(argv[i], "-") == 0) { i++; break; } else if (argv[i][0] != '-') { break; } else usage(); } if (o_attach) { char line[10]; printf("%s: pid %u\n", name, getpid()); printf("\n"); fgets(line, sizeof line, stdin); } #if HAVE_ALARM else if (o_alarm) { alarm(60); signal(SIGALRM, sig_alarm); } #endif su_init(); if (!(TSTFLAGS & tst_verbatim)) { su_log_soft_set_level(soa_log, 0); } #define SINGLE_FAILURE_CHECK() \ do { fflush(stdout); \ if (retval && quit_on_single_failure) { su_deinit(); return retval; } \ } while(0) retval |= test_api_errors(ctx); SINGLE_FAILURE_CHECK(); retval |= test_soa_tags(ctx); SINGLE_FAILURE_CHECK(); retval |= test_init(ctx, argv + i); SINGLE_FAILURE_CHECK(); if (retval == 0) { retval |= test_params(ctx); SINGLE_FAILURE_CHECK(); retval |= test_static_offer_answer(ctx); SINGLE_FAILURE_CHECK(); retval |= test_codec_selection(ctx); SINGLE_FAILURE_CHECK(); retval |= test_asynch_offer_answer(ctx); SINGLE_FAILURE_CHECK(); } retval |= test_deinit(ctx); SINGLE_FAILURE_CHECK(); su_deinit(); return retval; }