Browse code

SBC: cleaner handling of filtering errors

Václav Kubart authored on 02/08/2012 08:12:40
Showing 3 changed files
... ...
@@ -22,17 +22,6 @@ using namespace std;
22 22
 
23 23
 // helper functions
24 24
 
25
-/** count active and inactive media streams in given SDP */
26
-static void countStreams(const AmSdp &sdp, int &active, int &inactive)
27
-{
28
-  active = 0;
29
-  inactive = 0;
30
-  for (vector<SdpMedia>::const_iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
31
-    if (m->port == 0) inactive++;
32
-    else active++;
33
-  }
34
-}
35
-
36 25
 static const SdpPayload *findPayload(const std::vector<SdpPayload>& payloads, const SdpPayload &payload)
37 26
 {
38 27
   string pname = payload.encoding_name;
... ...
@@ -1143,11 +1132,27 @@ void SBCCallLeg::CCEnd(const CCInterfaceListIteratorT& end_interface) {
1143 1132
 //////////////////////////////////////////////////////////////////////////////////////////
1144 1133
 // body filtering
1145 1134
 
1146
-// do the filtering, returns true if SDP was changed
1147
-bool SBCCallLeg::doFiltering(AmSdp &sdp)
1135
+int SBCCallLeg::filterSdp(AmMimeBody &body, const string &method)
1148 1136
 {
1149
-  bool changed = false;
1137
+  DBG("filtering body\n");
1138
+
1139
+  AmMimeBody* sdp_body = body.hasContentType(SIP_APPLICATION_SDP);
1140
+  if (!sdp_body) return 0;
1141
+
1142
+  // filter body for given methods only
1143
+  if (!(method == SIP_METH_INVITE ||
1144
+       method == SIP_METH_UPDATE ||
1145
+       method == SIP_METH_PRACK ||
1146
+       method == SIP_METH_ACK)) return 0;
1150 1147
 
1148
+  AmSdp sdp;
1149
+  int res = sdp.parse((const char *)sdp_body->getPayload());
1150
+  if (0 != res) {
1151
+    DBG("SDP parsing failed during body filtering!\n");
1152
+    return res;
1153
+  }
1154
+
1155
+  bool changed = false;
1151 1156
   bool prefer_existing_codecs = call_profile.codec_prefs.preferExistingCodecs(a_leg);
1152 1157
 
1153 1158
   if (prefer_existing_codecs) {
... ...
@@ -1192,7 +1197,7 @@ bool SBCCallLeg::doFiltering(AmSdp &sdp)
1192 1197
     if (!changed) // otherwise already normalized
1193 1198
       normalizeSDP(sdp, call_profile.anonymize_sdp);
1194 1199
     if (isActiveFilter(call_profile.sdpfilter)) {
1195
-      filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list);
1200
+      res = filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list);
1196 1201
     }
1197 1202
     changed = true;
1198 1203
   }
... ...
@@ -1203,46 +1208,13 @@ bool SBCCallLeg::doFiltering(AmSdp &sdp)
1203 1208
     changed = true;
1204 1209
   }
1205 1210
 
1206
-  return changed;
1207
-}
1208
-
1209
-int SBCCallLeg::filterSdp(AmMimeBody &body, const string &method)
1210
-{
1211
-  AmMimeBody* sdp_body = body.hasContentType(SIP_APPLICATION_SDP);
1212
-
1213
-  DBG("filtering body\n");
1214
-  if (sdp_body &&
1215
-      (method == SIP_METH_INVITE ||
1216
-       method == SIP_METH_UPDATE ||
1217
-       method == SIP_METH_PRACK ||
1218
-       method == SIP_METH_ACK))
1219
-  {
1220
-    AmSdp sdp;
1221
-    int res = sdp.parse((const char *)sdp_body->getPayload());
1222
-    if (0 != res) {
1223
-      DBG("SDP parsing failed!\n");
1224
-      return res;
1225
-    }
1226
-
1227
-    if (doFiltering(sdp)) {
1228
-      string n_body;
1229
-      sdp.print(n_body);
1230
-      sdp_body->setPayload((const unsigned char*)n_body.c_str(), n_body.length());
1231
-    }
1232
-
1233
-    // temporary hack - will be migrated deeper inside
1234
-    int active, inactive;
1235
-    countStreams(sdp, active, inactive);
1236
-    if ((inactive > 0) && (active == 0)) {
1237
-      // no active streams remaining => reply 488 (FIXME: does it matter if we
1238
-      // filtered them out or they were already inactive?)
1239
-
1240
-      DBG("all streams are marked as inactive, reply 488 "
1241
-          SIP_REPLY_NOT_ACCEPTABLE_HERE"\n");
1242
-      return -488;
1243
-    }
1211
+  if (changed) {
1212
+    string n_body;
1213
+    sdp.print(n_body);
1214
+    sdp_body->setPayload((const unsigned char*)n_body.c_str(), n_body.length());
1244 1215
   }
1245
-  return 0;
1216
+
1217
+  return res;
1246 1218
 }
1247 1219
 
1248 1220
 void SBCCallLeg::appendTranscoderCodecs(AmSdp &sdp)
... ...
@@ -88,7 +88,6 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
88 88
   void CCEnd(const CCInterfaceListIteratorT& end_interface);
89 89
 
90 90
   void connectCallee(const string& remote_party, const string& remote_uri, const string &from, const AmSipRequest &invite_req);
91
-  bool doFiltering(AmSdp &sdp);
92 91
   int filterSdp(AmMimeBody &body, const string &method);
93 92
   void appendTranscoderCodecs(AmSdp &sdp);
94 93
   void savePayloadIDs(AmSdp &sdp);
... ...
@@ -34,6 +34,9 @@ int filterSDP(AmSdp& sdp, FilterType sdpfilter, const std::set<string>& sdpfilte
34 34
   if (!isActiveFilter(sdpfilter))
35 35
     return 0;
36 36
 
37
+  bool media_line_filtered_out = false;
38
+  bool media_line_left = false;
39
+
37 40
   for (std::vector<SdpMedia>::iterator m_it =
38 41
 	 sdp.media.begin(); m_it != sdp.media.end(); m_it++) {
39 42
     SdpMedia& media = *m_it;
... ...
@@ -59,10 +62,18 @@ int filterSDP(AmSdp& sdp, FilterType sdpfilter, const std::set<string>& sdpfilte
59 62
       // we should just reject the stream by setting port to 0 (at least one
60 63
       // format must be given; see RFC 3264, sect. 6)
61 64
       media.port = 0;
62
-      if (media.payloads.size() > 1) 
65
+      media_line_filtered_out = true;
66
+      if (media.payloads.size() > 1)
63 67
         media.payloads.erase(media.payloads.begin() + 1, media.payloads.end());
64 68
     }
65
-    else media.payloads = new_pl;    
69
+    else {
70
+      media.payloads = new_pl;
71
+      media_line_left = true;
72
+    }
73
+  }
74
+  if ((!media_line_left) && media_line_filtered_out) {
75
+    DBG("all streams were marked as inactive\n");
76
+    return -488;
66 77
   }
67 78
 
68 79
   return 0;