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

Attachment: 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

Reply via email to