On 9/5/06, Pekka Pessi <[EMAIL PROTECTED]> wrote:
On 9/5/06, Legostayev Denis <[EMAIL PROTECTED]> wrote: > 2. Using SOA_RTP_SELECT_SINGLE brings to removing "telephone-event" > from rtp payloads in SDP answer.
I think there are also other codecs that could be selected along with single codec, like CN codec. Perhaps a list of codecs, specified by yet an another tag.
I added SOATAG_AUDIO_AUX() for that purpose. Denis, could you test the attached patch (against 1.12.1)? -- Pekka.Pessi mail at nokia.com
soa-codec.darcs
Description: Binary data
Wed Sep 6 00:07:17 EEST 2006 [EMAIL PROTECTED] * test_soa.c: testing codec negotiation when new codecs are added to previously rejected media. Wed Sep 6 00:05:40 EEST 2006 [EMAIL PROTECTED] * test_soa.c: testing SOATAG_AUDIO_AUX(). Wed Sep 6 00:04:54 EEST 2006 [EMAIL PROTECTED] * soa_static.c: added new tag SOATAG_AUDIO_AUX() for listing auxiliary codecs. Auxiliary codecs are now included in m=line even if there is no matching codec at remote end. They are also ignored when selecting common codecs. Wed Sep 6 00:03:10 EEST 2006 [EMAIL PROTECTED] * soa_tag.h, soa_tag.c: added SOATAG_AUDIO_AUX(). Tue Sep 5 21:50:18 EEST 2006 [EMAIL PROTECTED] * soa_static.c: always upgrade answer if offer has changed. sdp.c: fixed sdp_media_cmp() - now include m_mode in comparison. Based on bug report and initial patch submitted by Legostayev Denis. --- old-sofia-sip/libsofia-sip-ua/soa/soa_static.c 2006-09-06 00:23:22.000000000 +0300 +++ new-sofia-sip/libsofia-sip-ua/soa/soa_static.c 2006-09-06 00:23:22.000000000 +0300 @@ -1,7 +1,7 @@ /* * This file is part of the Sofia-SIP package * - * Copyright (C) 2005 Nokia Corporation. + * Copyright (C) 2006 Nokia Corporation. * * Contact: Pekka Pessi <[EMAIL PROTECTED]> * @@ -62,6 +62,8 @@ #include <sofia-sip/su_tag_class.h> #include <sofia-sip/su_tagarg.h> #include <sofia-sip/su_strlst.h> +#include <sofia-sip/string0.h> +#include <sofia-sip/bnf.h> #include "sofia-sip/soa.h" #include <sofia-sip/sdp.h> @@ -70,7 +72,6 @@ #define NONE ((void *)-1) #define XXX assert(!"implemented") -#define str0cmp(a, b) strcmp(a ? a : "", b ? b : "") #if !HAVE_STRCASESTR char *strcasestr(const char *haystack, const char *needle); #endif @@ -78,6 +79,7 @@ typedef struct soa_static_session { soa_session_t sss_session[1]; + char *sss_audio_aux; } soa_static_session_t; @@ -148,25 +150,66 @@ static int soa_static_set_params(soa_session_t *ss, tagi_t const *tags) { - return soa_base_set_params(ss, tags); + soa_static_session_t *sss = (soa_static_session_t *)ss; + char const *audio_aux = sss->sss_audio_aux; + int n, m; + + n = tl_gets(tags, + SOATAG_AUDIO_AUX_REF(audio_aux), + TAG_END()); + if (n < 0) + return n; + + if (str0casecmp(audio_aux, sss->sss_audio_aux)) { + char *s = su_strdup(ss->ss_home, audio_aux), *tbf = sss->sss_audio_aux; + if (s == NULL && audio_aux != NULL) + return -1; + sss->sss_audio_aux = s; + if (tbf) + su_free(ss->ss_home, tbf); + } + + m = soa_base_set_params(ss, tags); + if (m < 0) + return m; + + return n + m; } static int soa_static_get_params(soa_session_t const *ss, tagi_t *tags) { - - return soa_base_get_params(ss, tags); + soa_static_session_t *sss = (soa_static_session_t *)ss; + + int n, m; + + n = tl_tgets(tags, + SOATAG_AUDIO_AUX(sss->sss_audio_aux), + TAG_END()); + if (n < 0) + return n; + + m = soa_base_get_params(ss, tags); + if (m < 0) + return m; + + return n + m; } static tagi_t *soa_static_get_paramlist(soa_session_t const *ss, tag_type_t tag, tag_value_t value, ...) { + soa_static_session_t *sss = (soa_static_session_t *)ss; + ta_list ta; tagi_t *tl; ta_start(ta, tag, value); - tl = soa_base_get_paramlist(ss, TAG_NEXT(ta_args(ta))); + tl = soa_base_get_paramlist(ss, + TAG_IF(sss->sss_audio_aux, + SOATAG_AUDIO_AUX(sss->sss_audio_aux)), + TAG_NEXT(ta_args(ta))); ta_end(ta); @@ -273,6 +316,37 @@ return rm != NULL; } +/** Check if codec is in auxiliary list */ +int soa_sdp_is_auxiliary_codec(sdp_rtpmap_t const *rm, char const *auxiliary) +{ + char const *codec; + size_t clen, alen; + char const *match; + + if (!rm || !rm->rm_encoding || !auxiliary) + return 0; + + codec = rm->rm_encoding; + + clen = strlen(codec), alen = strlen(auxiliary); + + if (clen > alen) + return 0; + + for (match = auxiliary; + (match = strcasestr(match, codec)); + match = match + 1) { + if (IS_ALPHANUM(match[clen]) || match[clen] == '-') + continue; + if (match != auxiliary && + (IS_ALPHANUM(match[-1]) || match[-1] == '-')) + continue; + return 1; + } + + return 0; +} + /** Find first matching media in table. */ sdp_media_t *soa_sdp_matching(soa_session_t *ss, @@ -283,6 +357,14 @@ int i, j = -1; sdp_media_t *m; sdp_rtpmap_t const *rm; + soa_static_session_t *sss = (soa_static_session_t *)ss; + char const *auxiliary; + + auxiliary = with->m_type == sdp_media_audio ? sss->sss_audio_aux : NULL; + + /* Looking for a single codec */ + if (with->m_rtpmaps && with->m_rtpmaps->rm_next == NULL) + auxiliary = NULL; for (i = 0; mm[i]; i++) { if (!sdp_media_match_with(mm[i], with)) @@ -296,6 +378,10 @@ /* Check also rtpmaps */ for (rm = mm[i]->m_rtpmaps; rm; rm = rm->rm_next) { + /* Ignore auxiliary codecs */ + if (auxiliary && soa_sdp_is_auxiliary_codec(rm, auxiliary)) + continue; + if (sdp_rtpmap_find_matching(with->m_rtpmaps, rm)) break; } @@ -426,14 +512,16 @@ } -/** Sort rtpmaps in @a l_m according to the values in @a r_m. +/** Sort rtpmaps in @a inout_list according to the values in @a rrm. * * @return Number of common codecs */ int soa_sdp_sort_rtpmap(sdp_rtpmap_t **inout_list, - sdp_rtpmap_t const *rrm) + sdp_rtpmap_t const *rrm, + char const *auxiliary) { sdp_rtpmap_t *sorted = NULL, **next = &sorted, **left; + sdp_rtpmap_t *aux = NULL, **next_aux = &aux; int common_codecs = 0; @@ -441,6 +529,10 @@ if (!inout_list) return 0; + /* If remote has only single codec, ignore list of auxiliary codecs */ + if (rrm && !rrm->rm_next) + auxiliary = NULL; + /* Insertion sort from *inout_list to sorted */ for (; rrm && *inout_list; rrm = rrm->rm_next) { for (left = inout_list; *left; left = &(*left)->rm_next) { @@ -449,11 +541,21 @@ } if (!*left) continue; - common_codecs++; - *next = *left; next = &(*next)->rm_next; + + if (auxiliary && soa_sdp_is_auxiliary_codec(rrm, auxiliary)) { + *next_aux = *left, next_aux = &(*next_aux)->rm_next; + } + else { + common_codecs++; + *next = *left; next = &(*next)->rm_next; + } *left = (*left)->rm_next; } + /* Append common auxiliary codecs */ + if (aux) + *next = aux, next = next_aux; + /* Append leftover codecs */ *next = *inout_list; @@ -463,14 +565,17 @@ } -/** Select rtpmaps in @a l_m according to the values in @a r_m. +/** Select rtpmaps in @a inout_list according to the values in @a rrm. * * @return Number of common codecs */ int soa_sdp_select_rtpmap(sdp_rtpmap_t **inout_list, - sdp_rtpmap_t const *rrm) + sdp_rtpmap_t const *rrm, + char const *auxiliary, + int select_single) { sdp_rtpmap_t **left; + sdp_rtpmap_t *aux = NULL, **next_aux = &aux; int common_codecs = 0; @@ -479,7 +584,12 @@ return 0; for (left = inout_list; *left; ) { - if (sdp_rtpmap_find_matching(rrm, (*left))) + if (auxiliary && soa_sdp_is_auxiliary_codec(*left, auxiliary)) + /* Insert into list of auxiliary codecs */ + *next_aux = *left, *left = (*left)->rm_next, + next_aux = &(*next_aux)->rm_next; + else if (!(select_single && common_codecs > 0) + && sdp_rtpmap_find_matching(rrm, (*left))) /* Select */ left = &(*left)->rm_next, common_codecs++; else @@ -487,6 +597,8 @@ *left = (*left)->rm_next; } + *left = aux, *next_aux = NULL; + return common_codecs; } @@ -495,6 +607,7 @@ sdp_session_t *session, sdp_session_t const *remote) { + soa_static_session_t *sss = (soa_static_session_t *)ss; sdp_media_t *sm; sdp_media_t const *rm; @@ -506,20 +619,22 @@ if (sdp_media_uses_rtp(sm)) { int common_codecs = soa_sdp_set_rtpmap_pt(sm, rm); + char const *auxiliary = + rm->m_type == sdp_media_audio ? sss->sss_audio_aux : NULL; + if (ss->ss_rtp_sort == SOA_RTP_SORT_REMOTE || (ss->ss_rtp_sort == SOA_RTP_SORT_DEFAULT && rm->m_mode == sdp_recvonly)) { - soa_sdp_sort_rtpmap(&sm->m_rtpmaps, rm->m_rtpmaps); + soa_sdp_sort_rtpmap(&sm->m_rtpmaps, rm->m_rtpmaps, auxiliary); } if (common_codecs == 0) ; else if (ss->ss_rtp_select == SOA_RTP_SELECT_SINGLE) { - if (sm->m_rtpmaps) - sm->m_rtpmaps->rm_next = NULL; + soa_sdp_select_rtpmap(&sm->m_rtpmaps, rm->m_rtpmaps, auxiliary, 1); } else if (ss->ss_rtp_select == SOA_RTP_SELECT_COMMON) { - soa_sdp_select_rtpmap(&sm->m_rtpmaps, rm->m_rtpmaps); + soa_sdp_select_rtpmap(&sm->m_rtpmaps, rm->m_rtpmaps, auxiliary, 0); } } } @@ -535,6 +650,8 @@ sdp_session_t const *caps, sdp_session_t const *upgrader) { + soa_static_session_t *sss = (soa_static_session_t *)ss; + int Ns, Nc, Nu, size, i, j; sdp_media_t *m, **mm, *cm; sdp_media_t **s_media, **o_media, **c_media; @@ -583,6 +700,9 @@ } else if (sdp_media_uses_rtp(m)) { /* Process rtpmaps */ + char const *auxiliary = + m->m_type == sdp_media_audio ? sss->sss_audio_aux : NULL; + if (!common_codecs && !ss->ss_rtp_mismatch) m = soa_sdp_make_rejected_media(home, m, session, 1); soa_sdp_set_rtpmap_pt(m, u_media[i]); @@ -590,17 +710,14 @@ if (ss->ss_rtp_sort == SOA_RTP_SORT_REMOTE || (ss->ss_rtp_sort == SOA_RTP_SORT_DEFAULT && u_media[i]->m_mode == sdp_recvonly)) { - soa_sdp_sort_rtpmap(&m->m_rtpmaps, u_media[i]->m_rtpmaps); + soa_sdp_sort_rtpmap(&m->m_rtpmaps, u_media[i]->m_rtpmaps, auxiliary); } if (common_codecs && (ss->ss_rtp_select == SOA_RTP_SELECT_SINGLE || ss->ss_rtp_select == SOA_RTP_SELECT_COMMON)) { - soa_sdp_select_rtpmap(&m->m_rtpmaps, u_media[i]->m_rtpmaps); - if (ss->ss_rtp_select == SOA_RTP_SELECT_SINGLE) { - if (m->m_rtpmaps) - m->m_rtpmaps->rm_next = NULL; - } + soa_sdp_select_rtpmap(&m->m_rtpmaps, u_media[i]->m_rtpmaps, auxiliary, + ss->ss_rtp_select == SOA_RTP_SELECT_SINGLE); } } @@ -948,6 +1065,7 @@ /* Step E: Upgrade codecs */ switch (action) { case process_answer: + case generate_answer: /* Upgrade local SDP based on remote SDP */ if (ss->ss_local_remote_version == remote_version) break; @@ -962,14 +1080,14 @@ } break; case generate_offer: - case generate_answer: default: break; } soa_description_free(ss, ss->ss_previous); - if (local == local0) { + if (ss->ss_local->ssd_sdp != local && + sdp_session_cmp(ss->ss_local->ssd_sdp, local)) { /* We have modfied local session: update origin-line */ if (local->sdp_origin != o) *o = *local->sdp_origin, local->sdp_origin = o; --- old-sofia-sip/libsofia-sip-ua/soa/soa_tag.c 2006-09-06 00:23:22.000000000 +0300 +++ new-sofia-sip/libsofia-sip-ua/soa/soa_tag.c 2006-09-06 00:23:22.000000000 +0300 @@ -235,7 +235,7 @@ * IPv4 address, or IPv6 address. * * Corresponding tag taking reference parameter is SOATAG_ADDRESS_REF() -*/ + */ tag_typedef_t soatag_address = STRTAG_TYPEDEF(address); @@ -266,17 +266,47 @@ * line is rejected, too, unless SOATAG_RTP_MISMATCH(1) has been used. * * Corresponding tag taking a reference parameter is SOATAG_RTP_SELECT_REF() -*/ + */ tag_typedef_t soatag_rtp_select = UINTTAG_TYPEDEF(rtp_select); +/[EMAIL PROTECTED] SOATAG_AUDIO_AUX(x) + * + * The named audio codecs are considered auxiliary, that is, they are + * considered as common codec only when they are the only codec listed on + * the media line. + * + * When generating answer or second offer soa includes auxiliary audio codecs in + * the list of codecs even if it is selecting only one codec or common + * codecs. + * + * @par Used with + * nua_set_params() \n + * nua_get_params() \n + * nua_invite() \n + * nua_update() \n + * nua_respond() \n + * + * @par Parameter type + * A string with whitespace separated list of codec names. + * + * @par Values + * E.g., "telephone-event cn". + * + * By default, there are no auxiliary audio codecs. + * + * Corresponding tag taking a reference parameter is + * SOATAG_AUDIO_AUX_REF() + */ +tag_typedef_t soatag_audio_aux = STRTAG_TYPEDEF(audio_aux); + /[EMAIL PROTECTED] SOATAG_RTP_SORT(x) * * When selecting the common codecs, soa can either select first local codec * supported by remote end, or first remote codec supported by local codecs. * The preference is indicated with ordering: the preferred codec is * first and so on. - + * * @par Used with * nua_set_params() \n * nua_get_params() \n diff: old-sofia-sip/libsofia-sip-ua/soa/soa_tag_ref.c: No such file or directory diff: new-sofia-sip/libsofia-sip-ua/soa/soa_tag_ref.c: No such file or directory --- old-sofia-sip/libsofia-sip-ua/soa/test_soa.c 2006-09-06 00:23:22.000000000 +0300 +++ new-sofia-sip/libsofia-sip-ua/soa/test_soa.c 2006-09-06 00:23:22.000000000 +0300 @@ -608,6 +608,8 @@ 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); @@ -717,8 +719,9 @@ "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\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), @@ -728,10 +731,13 @@ "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\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())); @@ -765,6 +771,8 @@ 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); @@ -773,6 +781,8 @@ /* 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); /* ---------------------------------------------------------------------- */ @@ -783,9 +793,10 @@ "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\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), @@ -819,14 +830,18 @@ 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 9 */ + 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); /* ---------------------------------------------------------------------- */ @@ -837,6 +852,8 @@ 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 */ @@ -852,6 +869,151 @@ 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); TEST_VOID(soa_terminate(a, NULL)); TEST_VOID(soa_terminate(b, NULL)); --- old-sofia-sip/libsofia-sip-ua/soa/sofia-sip/soa_tag.h 2006-09-06 00:23:22.000000000 +0300 +++ new-sofia-sip/libsofia-sip-ua/soa/sofia-sip/soa_tag.h 2006-09-06 00:23:22.000000000 +0300 @@ -164,6 +164,11 @@ enum { SOA_RTP_SELECT_SINGLE, SOA_RTP_SELECT_COMMON, SOA_RTP_SELECT_ALL }; +#define SOATAG_AUDIO_AUX(x) soatag_audio_aux, tag_str_v(x) +SOFIAPUBVAR tag_typedef_t soatag_audio_aux; +#define SOATAG_AUDIO_AUX_REF(x) soatag_audio_aux_ref, tag_str_vr(&(x)) +SOFIAPUBVAR tag_typedef_t soatag_audio_aux_ref; + #define SOATAG_RTP_SORT(x) soatag_rtp_sort, tag_uint_v(x) SOFIAPUBVAR tag_typedef_t soatag_rtp_sort; #define SOATAG_RTP_SORT_REF(x) soatag_rtp_sort_ref, tag_uint_vr(&(x)) --- old-sofia-sip/libsofia-sip-ua/sdp/sdp.c 2006-09-06 00:23:22.000000000 +0300 +++ new-sofia-sip/libsofia-sip-ua/sdp/sdp.c 2006-09-06 00:23:22.000000000 +0300 @@ -1442,6 +1442,9 @@ if ((rv = str0cmp(a->m_proto_name, b->m_proto_name))) return rv; + if ((rv = a->m_mode - b->m_mode)) + return rv; + for (arm = a->m_rtpmaps, brm = b->m_rtpmaps; arm || brm; arm = arm->rm_next, brm = brm->rm_next)
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Sofia-sip-devel mailing list Sofia-sip-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel