Browse code

sdpops: added new function sdp_remove_line_by_prefix(string)

- removes lines from SDP body that matches the prefix
- patch by Mikko Lehto

Daniel-Constantin Mierla authored on 02/10/2012 14:05:38
Showing 3 changed files
... ...
@@ -28,27 +28,29 @@ Daniel-Constantin Mierla
28 28
 
29 29
               4.1. sdp_remove_codecs_by_id(list)
30 30
               4.2. sdp_remove_codecs_by_name(list)
31
-              4.3. sdp_keep_codecs_by_id(list [, mtype])
32
-              4.4. sdp_keep_codecs_by_name(list [, mtype])
33
-              4.5. sdp_with_media(type)
34
-              4.6. sdp_remove_media(type)
35
-              4.7. sdp_with_codecs_by_id(list)
36
-              4.8. sdp_with_codecs_by_name(list)
37
-              4.9. sdp_print(level)
38
-              4.10. sdp_get(avpvar)
31
+              4.3. sdp_remove_line_by_prefix(string)
32
+              4.4. sdp_keep_codecs_by_id(list [, mtype])
33
+              4.5. sdp_keep_codecs_by_name(list [, mtype])
34
+              4.6. sdp_with_media(type)
35
+              4.7. sdp_remove_media(type)
36
+              4.8. sdp_with_codecs_by_id(list)
37
+              4.9. sdp_with_codecs_by_name(list)
38
+              4.10. sdp_print(level)
39
+              4.11. sdp_get(avpvar)
39 40
 
40 41
    List of Examples
41 42
 
42 43
    1.1. sdp_remove_codecs_by_id usage
43 44
    1.2. sdp_remove_codecs_by_name usage
44
-   1.3. sdp_keep_codecs_by_id usage
45
-   1.4. sdp_keep_codecs_by_name usage
46
-   1.5. sdp_with_media usage
47
-   1.6. sdp_remove_media usage
48
-   1.7. sdp_with_codecs_by_id usage
49
-   1.8. sdp_with_codecs_by_name usage
50
-   1.9. sdp_print usage
51
-   1.10. sdp_get usage
45
+   1.3. sdp_remove_line_by_prefix usage
46
+   1.4. sdp_keep_codecs_by_id usage
47
+   1.5. sdp_keep_codecs_by_name usage
48
+   1.6. sdp_with_media usage
49
+   1.7. sdp_remove_media usage
50
+   1.8. sdp_with_codecs_by_id usage
51
+   1.9. sdp_with_codecs_by_name usage
52
+   1.10. sdp_print usage
53
+   1.11. sdp_get usage
52 54
 
53 55
 Chapter 1. Admin Guide
54 56
 
... ...
@@ -65,14 +67,15 @@ Chapter 1. Admin Guide
65 67
 
66 68
         4.1. sdp_remove_codecs_by_id(list)
67 69
         4.2. sdp_remove_codecs_by_name(list)
68
-        4.3. sdp_keep_codecs_by_id(list [, mtype])
69
-        4.4. sdp_keep_codecs_by_name(list [, mtype])
70
-        4.5. sdp_with_media(type)
71
-        4.6. sdp_remove_media(type)
72
-        4.7. sdp_with_codecs_by_id(list)
73
-        4.8. sdp_with_codecs_by_name(list)
74
-        4.9. sdp_print(level)
75
-        4.10. sdp_get(avpvar)
70
+        4.3. sdp_remove_line_by_prefix(string)
71
+        4.4. sdp_keep_codecs_by_id(list [, mtype])
72
+        4.5. sdp_keep_codecs_by_name(list [, mtype])
73
+        4.6. sdp_with_media(type)
74
+        4.7. sdp_remove_media(type)
75
+        4.8. sdp_with_codecs_by_id(list)
76
+        4.9. sdp_with_codecs_by_name(list)
77
+        4.10. sdp_print(level)
78
+        4.11. sdp_get(avpvar)
76 79
 
77 80
 1. Overview
78 81
 
... ...
@@ -108,14 +111,15 @@ Chapter 1. Admin Guide
108 111
 
109 112
    4.1. sdp_remove_codecs_by_id(list)
110 113
    4.2. sdp_remove_codecs_by_name(list)
111
-   4.3. sdp_keep_codecs_by_id(list [, mtype])
112
-   4.4. sdp_keep_codecs_by_name(list [, mtype])
113
-   4.5. sdp_with_media(type)
114
-   4.6. sdp_remove_media(type)
115
-   4.7. sdp_with_codecs_by_id(list)
116
-   4.8. sdp_with_codecs_by_name(list)
117
-   4.9. sdp_print(level)
118
-   4.10. sdp_get(avpvar)
114
+   4.3. sdp_remove_line_by_prefix(string)
115
+   4.4. sdp_keep_codecs_by_id(list [, mtype])
116
+   4.5. sdp_keep_codecs_by_name(list [, mtype])
117
+   4.6. sdp_with_media(type)
118
+   4.7. sdp_remove_media(type)
119
+   4.8. sdp_with_codecs_by_id(list)
120
+   4.9. sdp_with_codecs_by_name(list)
121
+   4.10. sdp_print(level)
122
+   4.11. sdp_get(avpvar)
119 123
 
120 124
 4.1. sdp_remove_codecs_by_id(list)
121 125
 
... ...
@@ -151,7 +155,25 @@ sdp_remove_codecs_by_name("PCMU");
151 155
 sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
152 156
 ...
153 157
 
154
-4.3. sdp_keep_codecs_by_id(list [, mtype])
158
+4.3. sdp_remove_line_by_prefix(string)
159
+
160
+   Remove all SDP attribute lines beginning with 'string'.
161
+
162
+   This function can be used from ANY_ROUTE.
163
+
164
+   Example 1.3. sdp_remove_line_by_prefix usage
165
+...
166
+if ($si == "1080::8:800:200C:417A"
167
+        and ( has_body("application/sdp") or has_body("multipart/mixed")))
168
+{
169
+    xlog("L_INFO", "Cleaning ugly SDP from $si\n");
170
+    sdp_remove_codecs_by_name("X-NSE");
171
+    sdp_remove_line_by_prefix("a=X-");
172
+}
173
+
174
+...
175
+
176
+4.4. sdp_keep_codecs_by_id(list [, mtype])
155 177
 
156 178
    Keep only the codecs provided in the parameter 'list' from all media
157 179
    streams found in SDP payload. The parameter 'list' must be one or a
... ...
@@ -163,7 +185,7 @@ sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
163 185
 
164 186
    This function can be used from ANY_ROUTE.
165 187
 
166
-   Example 1.3. sdp_keep_codecs_by_id usage
188
+   Example 1.4. sdp_keep_codecs_by_id usage
167 189
 ...
168 190
 # keep only PCMU
169 191
 sdp_keep_codecs_by_id("0");
... ...
@@ -171,7 +193,7 @@ sdp_keep_codecs_by_id("0");
171 193
 sdp_keep_codecs_by_id("0,8,3", "audio");
172 194
 ...
173 195
 
174
-4.4. sdp_keep_codecs_by_name(list [, mtype])
196
+4.5. sdp_keep_codecs_by_name(list [, mtype])
175 197
 
176 198
    Keep only the codecs provided in the parameter 'list' from all media
177 199
    streams found in SDP payload. The parameter 'list' must be one or a
... ...
@@ -183,7 +205,7 @@ sdp_keep_codecs_by_id("0,8,3", "audio");
183 205
 
184 206
    This function can be used from ANY_ROUTE.
185 207
 
186
-   Example 1.4. sdp_keep_codecs_by_name usage
208
+   Example 1.5. sdp_keep_codecs_by_name usage
187 209
 ...
188 210
 # keep only PCMU
189 211
 sdp_keep_codecs_by_name("PCMU");
... ...
@@ -191,7 +213,7 @@ sdp_keep_codecs_by_name("PCMU");
191 213
 sdp_keep_codecs_by_name("PCMU,PCMA,GSM");
192 214
 ...
193 215
 
194
-4.5. sdp_with_media(type)
216
+4.6. sdp_with_media(type)
195 217
 
196 218
    Return true of the SDP has 'media=type ...' line. Useful to check the
197 219
    content of the RTP sessions, such as 'audio' or 'video'. The parameter
... ...
@@ -199,7 +221,7 @@ sdp_keep_codecs_by_name("PCMU,PCMA,GSM");
199 221
 
200 222
    This function can be used from ANY_ROUTE.
201 223
 
202
-   Example 1.5. sdp_with_media usage
224
+   Example 1.6. sdp_with_media usage
203 225
 ...
204 226
 # check for video stream
205 227
 if(sdp_with_media("video"))
... ...
@@ -208,20 +230,20 @@ if(sdp_with_media("video"))
208 230
 }
209 231
 ...
210 232
 
211
-4.6. sdp_remove_media(type)
233
+4.7. sdp_remove_media(type)
212 234
 
213 235
    Remove the streams that match on 'm=type ...' line. The parameter can
214 236
    be static string or variable holding the media type.
215 237
 
216 238
    This function can be used from ANY_ROUTE.
217 239
 
218
-   Example 1.6. sdp_remove_media usage
240
+   Example 1.7. sdp_remove_media usage
219 241
 ...
220 242
 # remove video stream
221 243
 sdp_remove_media("video");
222 244
 ...
223 245
 
224
-4.7. sdp_with_codecs_by_id(list)
246
+4.8. sdp_with_codecs_by_id(list)
225 247
 
226 248
    Returns true if any of the codecs provided in the parameter 'list' from
227 249
    all media streams is found in SDP payload. The parameter 'list' must be
... ...
@@ -230,7 +252,7 @@ sdp_remove_media("video");
230 252
 
231 253
    This function can be used from ANY_ROUTE.
232 254
 
233
-   Example 1.7. sdp_with_codecs_by_id usage
255
+   Example 1.8. sdp_with_codecs_by_id usage
234 256
 ...
235 257
 # test for PCMU
236 258
 if(sdp_with_codecs_by_id("0")) { ... }
... ...
@@ -238,7 +260,7 @@ if(sdp_with_codecs_by_id("0")) { ... }
238 260
 if(sdp_with_codecs_by_id("0,8,3")) { ... }
239 261
 ...
240 262
 
241
-4.8. sdp_with_codecs_by_name(list)
263
+4.9. sdp_with_codecs_by_name(list)
242 264
 
243 265
    Returns true if any of the codecs provided in the parameter 'list' from
244 266
    all media streams is found in SDP payload. The parameter 'list' must be
... ...
@@ -247,7 +269,7 @@ if(sdp_with_codecs_by_id("0,8,3")) { ... }
247 269
 
248 270
    This function can be used from ANY_ROUTE.
249 271
 
250
-   Example 1.8. sdp_with_codecs_by_name usage
272
+   Example 1.9. sdp_with_codecs_by_name usage
251 273
 ...
252 274
 # test for PCMU
253 275
 if(sdp_with_codecs_by_id("PCMU")) { ... }
... ...
@@ -255,27 +277,27 @@ if(sdp_with_codecs_by_id("PCMU")) { ... }
255 277
 if(sdp_with_codecs_by_id("PCMU,PCMA,GSM")) { ... }
256 278
 ...
257 279
 
258
-4.9. sdp_print(level)
280
+4.10. sdp_print(level)
259 281
 
260 282
    Print the SDP internal structure to log 'level'. The parameter can be
261 283
    static integer or variable holding the integer value of the log level.
262 284
 
263 285
    This function can be used from ANY_ROUTE.
264 286
 
265
-   Example 1.9. sdp_print usage
287
+   Example 1.10. sdp_print usage
266 288
 ...
267 289
 # print the SDP
268 290
 sdp_print("1");
269 291
 ...
270 292
 
271
-4.10. sdp_get(avpvar)
293
+4.11. sdp_get(avpvar)
272 294
 
273 295
    Store the SDP part of message body in an AVP. Return 1 if SDP is found,
274 296
    -1 on error and -2 if there is no SDP part in the message body.
275 297
 
276 298
    This function can be used from ANY_ROUTE.
277 299
 
278
-   Example 1.10. sdp_get usage
300
+   Example 1.11. sdp_get usage
279 301
 ...
280 302
 sdp_get("$avp(sdp)");
281 303
 ...
... ...
@@ -119,6 +119,32 @@ sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
119 119
 </programlisting>
120 120
 	    </example>
121 121
 	</section>
122
+	<section>
123
+	<title>
124
+		<function moreinfo="none">sdp_remove_line_by_prefix(string)</function>
125
+	</title>
126
+	<para>
127
+			Remove all SDP attribute lines beginning with 'string'.
128
+	</para>
129
+	<para>
130
+			This function can be used from ANY_ROUTE.
131
+	</para>
132
+	<example>
133
+	<title><function>sdp_remove_line_by_prefix</function> usage</title>
134
+	<programlisting format="linespecific">
135
+...
136
+if ($si == "1080::8:800:200C:417A"
137
+        and ( has_body("application/sdp") or has_body("multipart/mixed")))
138
+{
139
+    xlog("L_INFO", "Cleaning ugly SDP from $si\n");
140
+    sdp_remove_codecs_by_name("X-NSE");
141
+    sdp_remove_line_by_prefix("a=X-");
142
+}
143
+
144
+...
145
+</programlisting>
146
+	</example>
147
+        </section>
122 148
 	<section>
123 149
 	    <title>
124 150
 		<function moreinfo="none">sdp_keep_codecs_by_id(list [, mtype])</function>
... ...
@@ -31,6 +31,7 @@
31 31
 #include "../../mod_fix.h"
32 32
 #include "../../pvar.h"
33 33
 #include "../../parser/sdp/sdp.h"
34
+#include "../../parser/sdp/sdp_helpr_funcs.h"
34 35
 #include "../../trim.h"
35 36
 #include "../../data_lump.h"
36 37
 
... ...
@@ -39,6 +40,7 @@
39 40
 
40 41
 MODULE_VERSION
41 42
 
43
+static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* bar);
42 44
 static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar);
43 45
 static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char *bar);
44 46
 static int w_sdp_keep_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar);
... ...
@@ -53,6 +55,8 @@ static int w_get_sdp(sip_msg_t* msg, char *bar);
53 55
 static int mod_init(void);
54 56
 
55 57
 static cmd_export_t cmds[] = {
58
+	{"sdp_remove_line_by_prefix",  (cmd_function)w_sdp_remove_line_by_prefix,
59
+		1, fixup_spve_null,  0, ANY_ROUTE},
56 60
 	{"sdp_remove_codecs_by_id",    (cmd_function)w_sdp_remove_codecs_by_id,
57 61
 		1, fixup_spve_null,  0, ANY_ROUTE},
58 62
 	{"sdp_remove_codecs_by_name",  (cmd_function)w_sdp_remove_codecs_by_name,
... ...
@@ -338,6 +342,121 @@ int sdp_remove_codecs_by_id(sip_msg_t* msg, str* codecs)
338 342
 	return 0;
339 343
 }
340 344
 
345
+// removes consecutive blocks of SDP lines that begin with script provided prefix
346
+int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix)
347
+{
348
+	str body = {NULL, 0};
349
+	str remove = {NULL, 0};
350
+	str line = {NULL, 0};
351
+	char* del_lump_start = NULL;
352
+	char* del_lump_end = NULL;
353
+	int del_lump_flag = 0;
354
+	struct lump *anchor;
355
+	char* p = NULL;
356
+
357
+	if(parse_sdp(msg) < 0) {
358
+		LM_ERR("Unable to parse sdp\n");
359
+		return -1;
360
+	}
361
+
362
+	body.s = ((sdp_info_t*)msg->body)->raw_sdp.s;
363
+	body.len = ((sdp_info_t*)msg->body)->raw_sdp.len;
364
+
365
+	if (body.s==NULL) {
366
+		LM_ERR("failed to get the message body\n");
367
+		return -1;
368
+	}
369
+	body.len = msg->len - (body.s - msg->buf);
370
+	if (body.len==0) {
371
+		LM_DBG("message body has zero length\n");
372
+		return -1;
373
+	}
374
+
375
+	p = find_sdp_line(body.s, body.s+body.len, prefix->s[0]);
376
+	while (p != NULL)
377
+	{
378
+		if (sdp_locate_line(msg, p, &line) != 0)
379
+		{
380
+			LM_ERR("sdp_locate_line fail\n");
381
+			return -1;
382
+		}
383
+
384
+		//LM_DBG("line.s: %.*s\n", line.len, line.s);
385
+
386
+		if (extract_field(&line, &remove, *prefix) == 0)
387
+		{
388
+			//LM_DBG("line range: %d - %d\n", line.s - body.s, line.s + line.len - body.s);
389
+
390
+			if (del_lump_start == NULL)
391
+			{
392
+				del_lump_start = line.s;
393
+				del_lump_end = line.s + line.len;
394
+				//LM_DBG("first match, prepare new lump  (len=%d)\n", line.len);
395
+			}
396
+			else if ( p == del_lump_end )  // current line is same as del_lump_end
397
+			{
398
+				del_lump_end = line.s + line.len;
399
+				//LM_DBG("cont. match, made lump longer  (len+=%d)\n", line.len);
400
+			}
401
+
402
+			if (del_lump_end >= body.s + body.len)
403
+			{
404
+				//LM_DBG("end of buffer, delete lump\n");
405
+				del_lump_flag = 1;
406
+			}
407
+			//LM_DBG("lump pos: %d - %d\n", del_lump_start - body.s, del_lump_end - body.s);
408
+		}
409
+		else if ( del_lump_end != NULL)
410
+		{
411
+			//LM_DBG("line does not start with search pattern, delete current lump\n");
412
+			del_lump_flag = 1;
413
+		}
414
+
415
+		if (del_lump_flag && del_lump_start && del_lump_end)
416
+		{
417
+			LM_DBG("del_lump range: %d - %d  len: %d\n", (int)(del_lump_start - body.s),
418
+					(int)(del_lump_end - body.s), (int)(del_lump_end - del_lump_start));
419
+
420
+			anchor = del_lump(msg, del_lump_start - msg->buf, del_lump_end - del_lump_start, HDR_OTHER_T);
421
+			if (anchor == NULL)
422
+			{
423
+				LM_ERR("failed to remove lump\n");
424
+				return -1;
425
+			}
426
+
427
+			del_lump_start = NULL;
428
+			del_lump_end = NULL;
429
+			del_lump_flag = 0;
430
+			//LM_DBG("succesful lump deletion\n");
431
+		}
432
+
433
+		p = find_sdp_line(line.s + line.len, body.s + body.len, prefix->s[0]);
434
+	}
435
+	return 0;
436
+}
437
+
438
+static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* bar)
439
+{
440
+	str prfx = {NULL, 0};
441
+
442
+	if(prefix==0)
443
+	{
444
+		LM_ERR("invalid parameters\n");
445
+		return -1;
446
+	}
447
+
448
+	if (get_str_fparam(&prfx, msg, (fparam_t*)prefix))
449
+	{
450
+		LM_ERR("unable to determine prefix\n");
451
+		return -1;
452
+	}
453
+	LM_DBG("Removing SDP lines with prefix: %.*s\n", prfx.len, prfx.s);
454
+
455
+	if(sdp_remove_line_by_prefix(msg, &prfx)<0)
456
+		return -1;
457
+	return 1;
458
+}
459
+
341 460
 /**
342 461
  *
343 462
  */