Browse code

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

Applied patch 8c10653865e5f0b446f8783a30b67b062f897dcb

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

Stefan Sayer authored on 24/04/2012 09:27:40 • Václav Kubart committed on 22/06/2012 13:43:10
Showing 2 changed files
... ...
@@ -23,6 +23,9 @@
23 23
 using std::string;
24 24
 using std::map;
25 25
 
26
+#include <cctype>
27
+#include <algorithm>
28
+
26 29
 // Not on Solaris!
27 30
 #if !defined (__SVR4) && !defined (__sun)
28 31
 #include "strings.h"
... ...
@@ -42,8 +45,8 @@ static char* parse_until(char* s, char* end, char c);
42 45
 static bool contains(char* s, char* next_line, char c);
43 46
 static bool is_wsp(char s);
44 47
 
45
-static int media_type(std::string media);
46
-static int transport_type(std::string transport);
48
+static MediaType media_type(std::string media);
49
+static TransProt transport_type(std::string transport);
47 50
 static bool attr_check(std::string attr);
48 51
 
49 52
 enum parse_st {SDP_DESCR, SDP_MEDIA};
... ...
@@ -81,6 +84,7 @@ inline string media_t_2_str(int mt)
81 84
   case MT_APPLICATION: return "application";
82 85
   case MT_TEXT: return "text";
83 86
   case MT_MESSAGE: return "message";
87
+  case MT_IMAGE: return "image";
84 88
   default: return "<unknown media type>";
85 89
   }
86 90
 }
... ...
@@ -91,6 +95,7 @@ inline string transport_p_2_str(int tp)
91 95
   case TP_RTPAVP: return "RTP/AVP";
92 96
   case TP_UDP: return "udp";
93 97
   case TP_RTPSAVP: return "RTP/SAVP";
98
+  case TP_UDPTL: return "udptl";
94 99
   default: return "<unknown media type>";
95 100
   }
96 101
 }
... ...
@@ -260,9 +265,10 @@ void AmSdp::print(string& body) const
260 265
       
261 266
       out_buf += "m=" + media_t_2_str(media_it->type) + " " + int2str(media_it->port) + " " + transport_p_2_str(media_it->transport);
262 267
 
263
-      string options;
264
-      for(std::vector<SdpPayload>::const_iterator pl_it = media_it->payloads.begin();
265
-	  pl_it != media_it->payloads.end(); pl_it++) {
268
+      if (media_it->transport == TP_RTPAVP || media_it->transport == TP_RTPSAVP) {
269
+	string options;
270
+	for(std::vector<SdpPayload>::const_iterator pl_it = media_it->payloads.begin();
271
+	    pl_it != media_it->payloads.end(); pl_it++) {
266 272
 
267 273
 	  out_buf += " " + int2str(pl_it->payload_type);
268 274
 
... ...
@@ -280,11 +286,11 @@ void AmSdp::print(string& body) const
280 286
 	  
281 287
 	  // "a=fmtp:" line
282 288
 	  if(pl_it->sdp_format_parameters.size()){
283
-	      options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
284
-		  + pl_it->sdp_format_parameters + "\r\n";
289
+	    options += "a=fmtp:" + int2str(pl_it->payload_type) + " "
290
+	      + pl_it->sdp_format_parameters + "\r\n";
285 291
 	  }
286 292
 	  
287
-      }
293
+	}
288 294
 
289 295
       if (!media_it->conn.address.empty())
290 296
         out_buf += "\r\nc=IN IP4 "+media_it->conn.address;
... ...
@@ -324,6 +330,16 @@ void AmSdp::print(string& body) const
324 330
 	out_buf += a_it->print();
325 331
       }
326 332
 
333
+      switch (media_it->dir) {
334
+      case SdpMedia::DirActive:  out_buf += "a=direction:active\r\n"; break;
335
+      case SdpMedia::DirPassive: out_buf += "a=direction:passive\r\n"; break;
336
+      case SdpMedia::DirBoth:  out_buf += "a=direction:both\r\n"; break;
337
+      case SdpMedia::DirUndefined: break;
338
+      }
339
+    } else {
340
+        // for other transports (UDP/UDPTL) just print out fmt
341
+        out_buf += " " + media_it->fmt + "\r\n";
342
+      }
327 343
   }
328 344
 
329 345
   body = out_buf;
... ...
@@ -417,6 +433,9 @@ void SdpMedia::calcAnswer(const AmPayloadProvider* payload_prov,
417 433
   case SdpMedia::DirPassive:
418 434
     answer.dir = SdpMedia::DirActive;
419 435
     break;
436
+  case SdpMedia::DirUndefined:
437
+    answer.dir = SdpMedia::DirUndefined;
438
+    break;
420 439
   }
421 440
 
422 441
   // Calculate the intersection with the offered set of payloads
... ...
@@ -718,7 +737,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
718 737
       if (next > media_line)
719 738
 	media = string(media_line, int(next-media_line)-1);
720 739
       m.type = media_type(media);
721
-      if(m.type < 0) {
740
+      if(m.type == MT_NONE) {
722 741
 	ERROR("parse_sdp_media: Unknown media type\n");
723 742
       }
724 743
       media_line = next;
... ...
@@ -767,7 +786,7 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
767 786
 	//   break;
768 787
 	// }
769 788
 	m.transport = transport_type(proto);
770
-	if(m.transport < 0){
789
+	if(m.transport == TP_NONE){
771 790
 	  DBG("Unknown transport protocol: %s\n",proto.c_str());
772 791
 	}
773 792
 	media_line = next;
... ...
@@ -776,41 +795,49 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
776 795
       }
777 796
     case FMT:
778 797
       {
779
-	if (contains(media_line, line_end, ' ')) {
780
-	  next = parse_until(media_line, ' ');
781
-	  string value;
782
-	  if (next > media_line)
783
-	    value = string(media_line, int(next-media_line)-1);
784
-
785
-	  if (!value.empty()) {
786
-	    payload.type = m.type;
787
-	    str2i(value, payload_type);
788
-	    payload.payload_type = payload_type;
789
-	    m.payloads.push_back(payload);
790
-	  }
791
-
792
-	  media_line = next;
793
-	  state = FMT;
794
-	} else {
795
-	  string last_value;
796
-	  if (line_end>media_line) {
797
-	    if (*line_end == '\0') {
798
-	      // last line in message
799
-	      last_value = string(media_line, int(line_end-media_line));
800
-	    } else {
801
-	      last_value = string(media_line, int(line_end-media_line)-1);
798
+	if (m.transport == TP_RTPAVP || m.transport == TP_RTPSAVP) {
799
+	  if (contains(media_line, line_end, ' ')) {
800
+	    next = parse_until(media_line, ' ');
801
+	    string value;
802
+	    if (next > media_line)
803
+	      value = string(media_line, int(next-media_line)-1);
804
+
805
+	    if (!value.empty()) {
806
+	      payload.type = m.type;
807
+	      str2i(value, payload_type);
808
+	      payload.payload_type = payload_type;
809
+	      m.payloads.push_back(payload);
802 810
 	    }
811
+	    media_line = next;
812
+	  } else {
813
+	    string last_value;
814
+	    if (line_end>media_line) {
815
+	      if (*line_end == '\0') {
816
+		// last line in message
817
+		last_value = string(media_line, int(line_end-media_line));
818
+	      } else {
819
+		last_value = string(media_line, int(line_end-media_line)-1);
820
+	      }
821
+	    }
822
+	    if (!last_value.empty()) {
823
+	      payload.type = m.type;
824
+	      str2i(last_value, payload_type);
825
+	      payload.payload_type = payload_type;
826
+	      m.payloads.push_back(payload);
827
+	    }
828
+	    parsing = 0;
803 829
 	  }
804
-	  if (!last_value.empty()) {
805
-	    payload.type = m.type;
806
-	    str2i(last_value, payload_type);
807
-	    payload.payload_type = payload_type;
808
-	    m.payloads.push_back(payload);
809
-	  }
830
+	} else {
831
+	  line_end--;
832
+	  while (line_end > media_line &&
833
+		 (*line_end == '\r' || *line_end == '\n'))
834
+	    line_end--;
835
+	  if (line_end>media_line)
836
+	    m.fmt = string(media_line, line_end-media_line+1);
837
+	  DBG("set media fmt to '%s'\n", m.fmt.c_str());
810 838
 	  parsing = 0;
811 839
 	}
812
-	break;
813
-      }
840
+      } break;
814 841
     }
815 842
   }
816 843
   sdp_msg->media.push_back(m);
... ...
@@ -1253,32 +1280,39 @@ inline char* get_next_line(char* s)
1253 1280
 /*
1254 1281
  *Check if known media type is used
1255 1282
  */
1256
-static int media_type(std::string media)
1283
+static MediaType media_type(std::string media)
1257 1284
 {
1258 1285
   if(media == "audio")
1259
-    return 1;
1286
+    return MT_AUDIO;
1260 1287
   else if(media == "video")
1261
-    return 2;
1288
+    return MT_VIDEO;
1262 1289
   else if(media == "application")
1263
-    return 3;
1290
+    return MT_APPLICATION;
1264 1291
   else if(media == "text")
1265
-    return 4;
1292
+    return MT_TEXT;
1266 1293
   else if(media == "message")
1267
-    return 5;
1294
+    return MT_MESSAGE;
1295
+  else if(media == "image")
1296
+    return MT_IMAGE;
1268 1297
   else 
1269
-    return -1;
1298
+    return MT_NONE;
1270 1299
 }
1271 1300
 
1272
-static int transport_type(std::string transport)
1301
+static TransProt transport_type(string transport)
1273 1302
 {
1274
-  if(transport == "RTP/AVP")
1275
-    return 1;
1276
-  else if(transport == "UDP")
1277
-    return 2;
1278
-  else if(transport == "RTP/SAVP")
1279
-    return 3;
1303
+  string transport_uc = transport;
1304
+  std::transform(transport_uc.begin(), transport_uc.end(), transport_uc.begin(), toupper);
1305
+
1306
+  if(transport_uc == "RTP/AVP")
1307
+    return TP_RTPAVP;
1308
+  else if(transport_uc == "UDP")
1309
+    return TP_UDP;
1310
+  else if(transport_uc == "RTP/SAVP")
1311
+    return TP_RTPSAVP;
1312
+  else if(transport_uc == "UDPTL")
1313
+    return TP_UDPTL;
1280 1314
   else 
1281
-    return -1;
1315
+    return TP_NONE;
1282 1316
 }
1283 1317
 
1284 1318
 /*
... ...
@@ -53,9 +53,9 @@ enum NetworkType { NT_OTHER=0, NT_IN };
53 53
 /** address type */
54 54
 enum AddressType { AT_NONE=0, AT_V4, AT_V6 }; 
55 55
 /** media type */
56
-enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, MT_MESSAGE };
56
+enum MediaType { MT_NONE=0, MT_AUDIO, MT_VIDEO, MT_APPLICATION, MT_TEXT, MT_MESSAGE, MT_IMAGE };
57 57
 /** transport protocol */
58
-enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP };
58
+enum TransProt { TP_NONE=0, TP_RTPAVP, TP_UDP, TP_RTPSAVP, TP_UDPTL };
59 59
 
60 60
 /** \brief c=... line in SDP*/
61 61
 struct SdpConnection
... ...
@@ -167,7 +167,8 @@ struct SdpMedia
167 167
   enum Direction {
168 168
     DirBoth=0,
169 169
     DirActive=1,
170
-    DirPassive=2
170
+    DirPassive=2,
171
+    DirUndefined=3
171 172
   };
172 173
 
173 174
   int           type;
... ...
@@ -176,6 +177,7 @@ struct SdpMedia
176 177
   int           transport;
177 178
   SdpConnection conn; // c=
178 179
   Direction     dir;  // a=direction
180
+  string        fmt;  // format in case proto != RTP/AVP or RTP/SAVP
179 181
 
180 182
   // sendrecv|sendonly|recvonly|inactive
181 183
   bool          send;
... ...
@@ -187,7 +189,7 @@ struct SdpMedia
187 189
 
188 190
   bool operator == (const SdpMedia& other) const;
189 191
 
190
-  SdpMedia() : conn(),send(true),recv(true) {}
192
+  SdpMedia() : conn(), dir(DirUndefined), type(MT_NONE), transport(TP_NONE), send(true), recv(true) {}
191 193
 
192 194
   /** pretty print */
193 195
   string debugPrint() const;