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

Author: Stefan Sayer <[email protected]>
Committer: Václav Kubart <[email protected]>
Date:   Tue Apr 24 11:27:40 2012 +0200

b/f: T38 streams in SBC/B2B (udptl transport); proper media direction 
passthrough

Applied patch 8c10653865e5f0b446f8783a30b67b062f897dcb

Conflicts:
        core/AmSdp.cpp
        core/AmSdp.h

---

 core/AmSdp.cpp |  146 ++++++++++++++++++++++++++++++++++---------------------
 core/AmSdp.h   |   10 ++--
 2 files changed, 96 insertions(+), 60 deletions(-)

diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp
index 7165242..73493ca 100644
--- a/core/AmSdp.cpp
+++ b/core/AmSdp.cpp
@@ -23,6 +23,9 @@
 using std::string;
 using std::map;
 
+#include <cctype>
+#include <algorithm>
+
 // Not on Solaris!
 #if !defined (__SVR4) && !defined (__sun)
 #include "strings.h"
@@ -42,8 +45,8 @@ 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);
 
-static int media_type(std::string media);
-static int transport_type(std::string transport);
+static MediaType media_type(std::string media);
+static TransProt transport_type(std::string transport);
 static bool attr_check(std::string attr);
 
 enum parse_st {SDP_DESCR, SDP_MEDIA};
@@ -81,6 +84,7 @@ inline string media_t_2_str(int mt)
   case MT_APPLICATION: return "application";
   case MT_TEXT: return "text";
   case MT_MESSAGE: return "message";
+  case MT_IMAGE: return "image";
   default: return "<unknown media type>";
   }
 }
@@ -91,6 +95,7 @@ inline string transport_p_2_str(int tp)
   case TP_RTPAVP: return "RTP/AVP";
   case TP_UDP: return "udp";
   case TP_RTPSAVP: return "RTP/SAVP";
+  case TP_UDPTL: return "udptl";
   default: return "<unknown media type>";
   }
 }
@@ -260,9 +265,10 @@ void AmSdp::print(string& body) const
       
       out_buf += "m=" + media_t_2_str(media_it->type) + " " + 
int2str(media_it->port) + " " + transport_p_2_str(media_it->transport);
 
-      string options;
-      for(std::vector<SdpPayload>::const_iterator pl_it = 
media_it->payloads.begin();
-         pl_it != media_it->payloads.end(); pl_it++) {
+      if (media_it->transport == TP_RTPAVP || media_it->transport == 
TP_RTPSAVP) {
+       string options;
+       for(std::vector<SdpPayload>::const_iterator pl_it = 
media_it->payloads.begin();
+           pl_it != media_it->payloads.end(); pl_it++) {
 
          out_buf += " " + int2str(pl_it->payload_type);
 
@@ -280,11 +286,11 @@ void AmSdp::print(string& body) const
          
          // "a=fmtp:" line
          if(pl_it->sdp_format_parameters.size()){
-             options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
-                 + pl_it->sdp_format_parameters + "\r\n";
+           options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
+             + pl_it->sdp_format_parameters + "\r\n";
          }
          
-      }
+       }
 
       if (!media_it->conn.address.empty())
         out_buf += "\r\nc=IN IP4 "+media_it->conn.address;
@@ -324,6 +330,16 @@ void AmSdp::print(string& body) const
        out_buf += a_it->print();
       }
 
+      switch (media_it->dir) {
+      case SdpMedia::DirActive:  out_buf += "a=direction:active\r\n"; break;
+      case SdpMedia::DirPassive: out_buf += "a=direction:passive\r\n"; break;
+      case SdpMedia::DirBoth:  out_buf += "a=direction:both\r\n"; break;
+      case SdpMedia::DirUndefined: break;
+      }
+    } else {
+        // for other transports (UDP/UDPTL) just print out fmt
+        out_buf += " " + media_it->fmt + "\r\n";
+      }
   }
 
   body = out_buf;
@@ -417,6 +433,9 @@ void SdpMedia::calcAnswer(const AmPayloadProvider* 
payload_prov,
   case SdpMedia::DirPassive:
     answer.dir = SdpMedia::DirActive;
     break;
+  case SdpMedia::DirUndefined:
+    answer.dir = SdpMedia::DirUndefined;
+    break;
   }
 
   // Calculate the intersection with the offered set of payloads
@@ -718,7 +737,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
       if (next > media_line)
        media = string(media_line, int(next-media_line)-1);
       m.type = media_type(media);
-      if(m.type < 0) {
+      if(m.type == MT_NONE) {
        ERROR("parse_sdp_media: Unknown media type\n");
       }
       media_line = next;
@@ -767,7 +786,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
        //   break;
        // }
        m.transport = transport_type(proto);
-       if(m.transport < 0){
+       if(m.transport == TP_NONE){
          DBG("Unknown transport protocol: %s\n",proto.c_str());
        }
        media_line = next;
@@ -776,41 +795,49 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
       }
     case FMT:
       {
-       if (contains(media_line, line_end, ' ')) {
-         next = parse_until(media_line, ' ');
-         string value;
-         if (next > media_line)
-           value = string(media_line, int(next-media_line)-1);
-
-         if (!value.empty()) {
-           payload.type = m.type;
-           str2i(value, payload_type);
-           payload.payload_type = payload_type;
-           m.payloads.push_back(payload);
-         }
-
-         media_line = next;
-         state = FMT;
-       } else {
-         string last_value;
-         if (line_end>media_line) {
-           if (*line_end == '\0') {
-             // last line in message
-             last_value = string(media_line, int(line_end-media_line));
-           } else {
-             last_value = string(media_line, int(line_end-media_line)-1);
+       if (m.transport == TP_RTPAVP || m.transport == TP_RTPSAVP) {
+         if (contains(media_line, line_end, ' ')) {
+           next = parse_until(media_line, ' ');
+           string value;
+           if (next > media_line)
+             value = string(media_line, int(next-media_line)-1);
+
+           if (!value.empty()) {
+             payload.type = m.type;
+             str2i(value, payload_type);
+             payload.payload_type = payload_type;
+             m.payloads.push_back(payload);
            }
+           media_line = next;
+         } else {
+           string last_value;
+           if (line_end>media_line) {
+             if (*line_end == '\0') {
+               // last line in message
+               last_value = string(media_line, int(line_end-media_line));
+             } else {
+               last_value = string(media_line, int(line_end-media_line)-1);
+             }
+           }
+           if (!last_value.empty()) {
+             payload.type = m.type;
+             str2i(last_value, payload_type);
+             payload.payload_type = payload_type;
+             m.payloads.push_back(payload);
+           }
+           parsing = 0;
          }
-         if (!last_value.empty()) {
-           payload.type = m.type;
-           str2i(last_value, payload_type);
-           payload.payload_type = payload_type;
-           m.payloads.push_back(payload);
-         }
+       } else {
+         line_end--;
+         while (line_end > media_line &&
+                (*line_end == '\r' || *line_end == '\n'))
+           line_end--;
+         if (line_end>media_line)
+           m.fmt = string(media_line, line_end-media_line+1);
+         DBG("set media fmt to '%s'\n", m.fmt.c_str());
          parsing = 0;
        }
-       break;
-      }
+      } break;
     }
   }
   sdp_msg->media.push_back(m);
@@ -1253,32 +1280,39 @@ inline char* get_next_line(char* s)
 /*
  *Check if known media type is used
  */
-static int media_type(std::string media)
+static MediaType media_type(std::string media)
 {
   if(media == "audio")
-    return 1;
+    return MT_AUDIO;
   else if(media == "video")
-    return 2;
+    return MT_VIDEO;
   else if(media == "application")
-    return 3;
+    return MT_APPLICATION;
   else if(media == "text")
-    return 4;
+    return MT_TEXT;
   else if(media == "message")
-    return 5;
+    return MT_MESSAGE;
+  else if(media == "image")
+    return MT_IMAGE;
   else 
-    return -1;
+    return MT_NONE;
 }
 
-static int transport_type(std::string transport)
+static TransProt transport_type(string transport)
 {
-  if(transport == "RTP/AVP")
-    return 1;
-  else if(transport == "UDP")
-    return 2;
-  else if(transport == "RTP/SAVP")
-    return 3;
+  string transport_uc = transport;
+  std::transform(transport_uc.begin(), transport_uc.end(), 
transport_uc.begin(), toupper);
+
+  if(transport_uc == "RTP/AVP")
+    return TP_RTPAVP;
+  else if(transport_uc == "UDP")
+    return TP_UDP;
+  else if(transport_uc == "RTP/SAVP")
+    return TP_RTPSAVP;
+  else if(transport_uc == "UDPTL")
+    return TP_UDPTL;
   else 
-    return -1;
+    return TP_NONE;
 }
 
 /*
diff --git a/core/AmSdp.h b/core/AmSdp.h
index 2ee43c9..678d5ea 100644
--- a/core/AmSdp.h
+++ b/core/AmSdp.h
@@ -53,9 +53,9 @@ enum NetworkType { NT_OTHER=0, NT_IN };
 /** address type */
 enum AddressType { AT_NONE=0, AT_V4, AT_V6 }; 
 /** media type */
-enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, 
MT_MESSAGE };
+enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, 
MT_MESSAGE, MT_IMAGE };
 /** transport protocol */
-enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP };
+enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP, TP_UDPTL };
 
 /** \brief c=... line in SDP*/
 struct SdpConnection
@@ -167,7 +167,8 @@ struct SdpMedia
   enum Direction {
     DirBoth=0,
     DirActive=1,
-    DirPassive=2
+    DirPassive=2,
+    DirUndefined=3
   };
 
   int           type;
@@ -176,6 +177,7 @@ struct SdpMedia
   int           transport;
   SdpConnection conn; // c=
   Direction     dir;  // a=direction
+  string        fmt;  // format in case proto != RTP/AVP or RTP/SAVP
 
   // sendrecv|sendonly|recvonly|inactive
   bool          send;
@@ -187,7 +189,7 @@ struct SdpMedia
 
   bool operator == (const SdpMedia& other) const;
 
-  SdpMedia() : conn(),send(true),recv(true) {}
+  SdpMedia() : conn(), dir(DirUndefined), type(MT_NONE), transport(TP_NONE), 
send(true), recv(true) {}
 
   /** pretty print */
   string debugPrint() const;

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

Reply via email to