Module: sems
Branch: master
Commit: 10ba13bf80f5210d61feedbd8fe7fb312af92e5e
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=10ba13bf80f5210d61feedbd8fe7fb312af92e5e

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Wed Nov  3 18:36:20 2010 +0100

add unknown attributes (a=) parsing

both session and media level

---

 core/AmSdp.cpp |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 core/AmSdp.h   |   21 ++++++++++++++++
 2 files changed, 91 insertions(+), 1 deletions(-)

diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp
index ddfd365..cbac63b 100644
--- a/core/AmSdp.cpp
+++ b/core/AmSdp.cpp
@@ -28,6 +28,7 @@ using std::map;
 #include "strings.h"
 #endif
 
+static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next);
 static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s);
 static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t);
 static void parse_sdp_media(AmSdp* sdp_msg, char* s);
@@ -37,6 +38,7 @@ static void parse_sdp_origin(AmSdp* sdp_masg, char* s);
 inline char* get_next_line(char* s);
 static char* is_eql_next(char* s);
 static char* parse_until(char* s, char end);
+static char* parse_until(char* s, char* end, char c);
 static bool contains(char* s, char* next_line, char c);
 static bool is_wsp(char s);
 
@@ -99,6 +101,13 @@ bool SdpPayload::operator == (int r)
   return payload_type == r;
 }
 
+string SdpAttribute::print() const {
+  if (value.empty())
+    return "a="+attribute+CRLF;
+  else
+    return "a="+attribute+":"+value+CRLF;
+}
+
 //
 // class AmSdp: Methods
 //
@@ -167,6 +176,12 @@ void AmSdp::print(string& body) const
       "c=IN IP4 "+conn.address+"\r\n"
       "t=0 0\r\n";
 
+  // add attributes (session level)
+  for (std::vector<SdpAttribute>::const_iterator a_it=
+        attributes.begin(); a_it != attributes.end(); a_it++) {
+    out_buf += a_it->print();
+  }
+
   for(std::vector<SdpMedia>::const_iterator media_it = media.begin();
       media_it != media.end(); media_it++) {
       
@@ -200,6 +215,13 @@ void AmSdp::print(string& body) const
 
       if(remote_active /* dir == SdpMedia::DirActive */)
          out_buf += "a=direction:passive\r\n";
+
+      // add attributes (media level)
+      for (std::vector<SdpAttribute>::const_iterator a_it=
+            media_it->attributes.begin(); a_it != media_it->attributes.end(); 
a_it++) {
+       out_buf += a_it->print();
+      }
+
   }
 
   body = out_buf;
@@ -508,7 +530,8 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s)
       case 'a':
          DBG("parse_sdp_line_ex: found attributes\n");
        s = is_eql_next(s);
-       next = get_next_line(s);
+       parse_session_attr(sdp_msg, s, &next);
+         // next = get_next_line(s);
        //      parse_sdp_attr(sdp_msg, s);
        s = next;
        state = SDP_DESCR;
@@ -776,6 +799,40 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
   return;
 }
 
+static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) {
+  *next = get_next_line(s);
+  if (*next == s) {
+    WARN("premature end of SDP in session attr\n");
+    while (**next != '\0') (*next)++;
+    return;
+  }
+  char* attr_end = *next-1;
+  while (attr_end >= s &&
+        ((*attr_end == 10) || (*attr_end == 13)))
+    attr_end--;
+
+  if (*attr_end == ':') {
+    WARN("incorrect SDP: value attrib without value: '%s'\n",
+        string(s, attr_end-s+1).c_str());
+    return;
+  }
+
+  char* col = parse_until(s, attr_end, ':');
+
+  if (col == attr_end) {
+    // property attribute
+    sdp_msg->attributes.push_back(SdpAttribute(string(s, attr_end-s+1)));
+    DBG("got session attribute '%.*s\n", attr_end-s+1, s);
+  } else {
+    // value attribute
+    sdp_msg->attributes.push_back(SdpAttribute(string(s, col-s-1),
+                                              string(col, attr_end-col+1)));
+    DBG("got session attribute '%.*s:%.*s'\n", col-s-1, s, attr_end-col+1, 
col);
+
+  }
+
+}
+
 static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
 {
  
@@ -960,6 +1017,7 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
          string value(attr_line, int(next-attr_line)-1);
          DBG("found media attr '%s' value '%s'\n",
              (char*)attr.c_str(), (char*)value.c_str());
+         media.attributes.push_back(SdpAttribute(attr, value));
       } else {
          DBG("found media attr '%s', but value is not followed by cr\n",
              (char *)attr.c_str());
@@ -973,6 +1031,7 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
          string attr(attr_line, int(next-attr_line)-1);
          attr_check(attr);
          DBG("found media attr '%s'\n", (char*)attr.c_str());
+         media.attributes.push_back(SdpAttribute(attr));
       } else {
          DBG("found media attr line '%s', which is not followed by cr\n",
              attr_line);
@@ -1120,6 +1179,16 @@ static char* parse_until(char* s, char end)
   return line;
 }
 
+static char* parse_until(char* s, char* end, char c)
+{
+  char* line=s;
+  while(line<end && *line && *line != c ){
+    line++;
+  }
+  if (line<end)
+    line++;
+  return line;
+}
 
 static char* is_eql_next(char* s)
 {
diff --git a/core/AmSdp.h b/core/AmSdp.h
index 79967ab..7c01083 100644
--- a/core/AmSdp.h
+++ b/core/AmSdp.h
@@ -106,6 +106,23 @@ struct SdpPayload
   bool operator == (int r);
 };
 
+/** \brief a=... line in SDP */
+struct SdpAttribute
+{
+  string attribute;
+  string value;
+
+  // property attribute
+  SdpAttribute(const string& attribute,
+              const string& value)
+    : attribute(attribute), value(value) { }
+
+  // value attribute
+  SdpAttribute(const string& attribute)
+    : attribute(attribute) { }
+
+  string print() const;
+};
 
 /** \brief m=... line in SDP */
 struct SdpMedia
@@ -125,6 +142,8 @@ struct SdpMedia
 
   std::vector<SdpPayload> payloads;
 
+  std::vector<SdpAttribute> attributes; // unknown attributes
+
   SdpMedia() : conn() {}
 };
 
@@ -152,6 +171,8 @@ public:
   string           sessionName; // s= 
   string           uri;          // u=
   SdpConnection    conn;        // c=
+  std::vector<SdpAttribute> attributes; // unknown session level attributes
+
   std::vector<SdpMedia> media;  // m= ... [a=rtpmap:...]+
 
   // Supported payloads

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to