Browse code

rtpengine: add block_media and unblock_media function calls

Richard Fuchs authored on 24/09/2018 13:46:19
Showing 3 changed files
... ...
@@ -2592,7 +2592,17 @@ stop_recording();
2592 2592
 		&rtp; proxy, but they won't be forwarded to the receiving peer.
2593 2593
 		</para>
2594 2594
 		<para>
2595
-		The call-id flag can be used to stop recording for a different call.
2595
+		The call-id flag can be used to block DTMF for a different call.
2596
+		</para>
2597
+		<para>
2598
+		Without any flags given, DTMF events will be blocked for the entire call.
2599
+		It's possible to block DTMF directionally only for individual participants.
2600
+		If the <quote>directional</quote> flag is given, DTMF events will be
2601
+		blocked for the UA with the currently matching <quote>From</quote> tag.
2602
+		Events can be blocked for a different UA either by specifying an alternative
2603
+		<quote>from-tag=...</quote>, or by matching UAs against the media address
2604
+		they advertised in the &sdp; using the <quote>address=...</quote> flag
2605
+		(which can contain either an IPv4 or IPv6 address).
2596 2606
 		</para>
2597 2607
 		<para>
2598 2608
 		This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
... ...
@@ -2602,6 +2612,8 @@ stop_recording();
2602 2612
 		<programlisting format="linespecific">
2603 2613
 ...
2604 2614
 block_dtmf();
2615
+block_dtmf("directional");
2616
+block_dtmf("address=192.168.42.42");
2605 2617
 ...
2606 2618
 		</programlisting>
2607 2619
 		</example>
... ...
@@ -2613,12 +2625,65 @@ block_dtmf();
2613 2625
 		</title>
2614 2626
 		<para>
2615 2627
 		Reverses the effects of a previously issued <function>block_dtmf</function> call.
2628
+		See above for a description of which flags can be used.
2629
+		</para>
2630
+		<para>
2631
+		If DTMF events were previously blocked for individual UAs, then unblocking DTMF
2632
+		events for the entire call (i.e. no flags given) will not remove these blocks.
2633
+		The flag <quote>all</quote> can be used to achieve this.
2616 2634
 		</para>
2617 2635
 		<example>
2618 2636
 		<title><function>unblock_dtmf</function> usage</title>
2619 2637
 		<programlisting format="linespecific">
2620 2638
 ...
2621 2639
 unblock_dtmf();
2640
+unblock_dtmf("all");
2641
+...
2642
+		</programlisting>
2643
+		</example>
2644
+	</section>
2645
+
2646
+	<section id="rtpengine.f.block_media">
2647
+		<title>
2648
+		<function moreinfo="none">block_media([flags])</function>
2649
+		</title>
2650
+		<para>
2651
+		Analogous to <quote>block_dtmf</quote>, but blocks media &rtp; packets
2652
+		instead of DTMF events. When media is blocked, DTMF events still pass
2653
+		through the &rtp; proxy.
2654
+		</para>
2655
+		<para>
2656
+		See <quote>block_dtmf</quote> for a description of the flags that can be used.
2657
+		</para>
2658
+		<example>
2659
+		<title><function>block_media</function> usage</title>
2660
+		<programlisting format="linespecific">
2661
+...
2662
+block_media();
2663
+block_media("directional");
2664
+block_media("address=192.168.42.42");
2665
+...
2666
+		</programlisting>
2667
+		</example>
2668
+	</section>
2669
+
2670
+	<section id="rtpengine.f.unblock_media">
2671
+		<title>
2672
+		<function moreinfo="none">unblock_media([flags])</function>
2673
+		</title>
2674
+		<para>
2675
+		Analogous to <quote>unblock_dtmf</quote>, but applies to media &rtp; packets instead
2676
+		of DTMF events.
2677
+		</para>
2678
+		<para>
2679
+		See <quote>unblock_dtmf</quote> for a description of the flags that can be used.
2680
+		</para>
2681
+		<example>
2682
+		<title><function>unblock_media</function> usage</title>
2683
+		<programlisting format="linespecific">
2684
+...
2685
+unblock_media();
2686
+unblock_media("all");
2622 2687
 ...
2623 2688
 		</programlisting>
2624 2689
 		</example>
... ...
@@ -114,7 +114,7 @@ enum {
114 114
 #define	CPORT					"22222"
115 115
 
116 116
 struct ng_flags_parse {
117
-	int via, to, packetize, transport;
117
+	int via, to, packetize, transport, directional;
118 118
 	bencode_item_t *dict, *flags, *direction, *replace, *rtcp_mux, *sdes,
119 119
 		       *codec, *codec_strip, *codec_offer, *codec_transcode, *codec_mask;
120 120
 	str call_id, from_tag, to_tag;
... ...
@@ -130,6 +130,8 @@ static const char *command_strings[] = {
130 130
 	[OP_STOP_RECORDING]	= "stop recording",
131 131
 	[OP_BLOCK_DTMF]		= "block DTMF",
132 132
 	[OP_UNBLOCK_DTMF]	= "unblock DTMF",
133
+	[OP_BLOCK_MEDIA]	= "block media",
134
+	[OP_UNBLOCK_MEDIA]	= "unblock media",
133 135
 };
134 136
 
135 137
 struct minmax_mos_stats {
... ...
@@ -173,6 +175,8 @@ static int start_recording_f(struct sip_msg *, char *, char *);
173 175
 static int stop_recording_f(struct sip_msg *, char *, char *);
174 176
 static int block_dtmf_f(struct sip_msg *, char *, char *);
175 177
 static int unblock_dtmf_f(struct sip_msg *, char *, char *);
178
+static int block_media_f(struct sip_msg *, char *, char *);
179
+static int unblock_media_f(struct sip_msg *, char *, char *);
176 180
 static int rtpengine_answer1_f(struct sip_msg *, char *, char *);
177 181
 static int rtpengine_offer1_f(struct sip_msg *, char *, char *);
178 182
 static int rtpengine_delete1_f(struct sip_msg *, char *, char *);
... ...
@@ -305,6 +309,24 @@ static cmd_export_t cmds[] = {
305 309
 	{"unblock_dtmf",	(cmd_function)unblock_dtmf_f, 		0,
306 310
 		0, 0,
307 311
 		ANY_ROUTE},
312
+	{"block_media",		(cmd_function)block_media_f,	 	0,
313
+		0, 0,
314
+		ANY_ROUTE },
315
+	{"unblock_media",	(cmd_function)unblock_media_f, 		0,
316
+		0, 0,
317
+		ANY_ROUTE},
318
+	{"block_dtmf",		(cmd_function)block_dtmf_f,	 	1,
319
+		fixup_spve_null, 0,
320
+		ANY_ROUTE },
321
+	{"unblock_dtmf",	(cmd_function)unblock_dtmf_f, 		1,
322
+		fixup_spve_null, 0,
323
+		ANY_ROUTE},
324
+	{"block_media",		(cmd_function)block_media_f,	 	1,
325
+		fixup_spve_null, 0,
326
+		ANY_ROUTE },
327
+	{"unblock_media",	(cmd_function)unblock_media_f, 		1,
328
+		fixup_spve_null, 0,
329
+		ANY_ROUTE},
308 330
 	{"rtpengine_offer",	(cmd_function)rtpengine_offer1_f,	0,
309 331
 		0, 0,
310 332
 		ANY_ROUTE},
... ...
@@ -2076,6 +2098,7 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
2076 2098
 					if (!val.s)
2077 2099
 						goto error;
2078 2100
 					ng_flags->from_tag = val;
2101
+					ng_flags->directional = 1;
2079 2102
 				}
2080 2103
 				else
2081 2104
 					goto generic;
... ...
@@ -2125,8 +2148,12 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enu
2125 2148
 					if (!ng_flags->packetize)
2126 2149
 						goto error;
2127 2150
 					bencode_dictionary_add_integer(ng_flags->dict, "repacketize", ng_flags->packetize);
2128
-					goto next;
2129 2151
 				}
2152
+				else if (str_eq(&key, "directional"))
2153
+					ng_flags->directional = 1;
2154
+				else
2155
+					goto generic;
2156
+				goto next;
2130 2157
 				break;
2131 2158
 
2132 2159
 			case 12:
... ...
@@ -2242,6 +2269,11 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
2242 2269
 		else
2243 2270
 			bencode_dictionary_add_str(ng_flags.dict, "sdp", &body);
2244 2271
 	}
2272
+	else if (op == OP_BLOCK_DTMF || op == OP_BLOCK_MEDIA || op == OP_UNBLOCK_DTMF
2273
+			|| op == OP_UNBLOCK_MEDIA)
2274
+	{
2275
+		ng_flags.flags = bencode_list(bencbuf);
2276
+	}
2245 2277
 
2246 2278
 	/*** parse flags & build dictionary ***/
2247 2279
 
... ...
@@ -2291,7 +2323,13 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_
2291 2323
 	) );
2292 2324
 	bencode_list_add_string(item, ip_addr2a(&msg->rcv.src_ip));
2293 2325
 
2294
-	if ((msg->first_line.type == SIP_REQUEST && op != OP_ANSWER)
2326
+	if (op == OP_BLOCK_DTMF || op == OP_BLOCK_MEDIA || op == OP_UNBLOCK_DTMF
2327
+			|| op == OP_UNBLOCK_MEDIA)
2328
+	{
2329
+		if (ng_flags.directional)
2330
+			bencode_dictionary_add_str(ng_flags.dict, "from-tag", &ng_flags.from_tag);
2331
+	}
2332
+	else if ((msg->first_line.type == SIP_REQUEST && op != OP_ANSWER)
2295 2333
 		|| (msg->first_line.type == SIP_REPLY && op == OP_DELETE)
2296 2334
 		|| (msg->first_line.type == SIP_REPLY && op == OP_ANSWER))
2297 2335
 	{
... ...
@@ -3552,13 +3590,69 @@ static int rtpengine_unblock_dtmf_wrap(struct sip_msg *msg, void *d, int more) {
3552 3590
 static int
3553 3591
 block_dtmf_f(struct sip_msg* msg, char *str1, char *str2)
3554 3592
 {
3555
-	return rtpengine_rtpp_set_wrap(msg, rtpengine_block_dtmf_wrap, NULL, 1);
3593
+	str flags;
3594
+	flags.s = NULL;
3595
+	if (str1) {
3596
+		if (get_str_fparam(&flags, msg, (fparam_t *) str1)) {
3597
+			LM_ERR("Error getting string parameter\n");
3598
+			return -1;
3599
+		}
3600
+	}
3601
+
3602
+	return rtpengine_rtpp_set_wrap(msg, rtpengine_block_dtmf_wrap, flags.s, 1);
3556 3603
 }
3557 3604
 
3558 3605
 static int
3559 3606
 unblock_dtmf_f(struct sip_msg* msg, char *str1, char *str2)
3560 3607
 {
3561
-	return rtpengine_rtpp_set_wrap(msg, rtpengine_unblock_dtmf_wrap, NULL, 1);
3608
+	str flags;
3609
+	flags.s = NULL;
3610
+	if (str1) {
3611
+		if (get_str_fparam(&flags, msg, (fparam_t *) str1)) {
3612
+			LM_ERR("Error getting string parameter\n");
3613
+			return -1;
3614
+		}
3615
+	}
3616
+
3617
+	return rtpengine_rtpp_set_wrap(msg, rtpengine_unblock_dtmf_wrap, flags.s, 1);
3618
+}
3619
+
3620
+static int rtpengine_block_media_wrap(struct sip_msg *msg, void *d, int more) {
3621
+	return rtpp_function_call_simple(msg, OP_BLOCK_MEDIA, d);
3622
+}
3623
+
3624
+static int rtpengine_unblock_media_wrap(struct sip_msg *msg, void *d, int more) {
3625
+	return rtpp_function_call_simple(msg, OP_UNBLOCK_MEDIA, d);
3626
+}
3627
+
3628
+static int
3629
+block_media_f(struct sip_msg* msg, char *str1, char *str2)
3630
+{
3631
+	str flags;
3632
+	flags.s = NULL;
3633
+	if (str1) {
3634
+		if (get_str_fparam(&flags, msg, (fparam_t *) str1)) {
3635
+			LM_ERR("Error getting string parameter\n");
3636
+			return -1;
3637
+		}
3638
+	}
3639
+
3640
+	return rtpengine_rtpp_set_wrap(msg, rtpengine_block_media_wrap, flags.s, 1);
3641
+}
3642
+
3643
+static int
3644
+unblock_media_f(struct sip_msg* msg, char *str1, char *str2)
3645
+{
3646
+	str flags;
3647
+	flags.s = NULL;
3648
+	if (str1) {
3649
+		if (get_str_fparam(&flags, msg, (fparam_t *) str1)) {
3650
+			LM_ERR("Error getting string parameter\n");
3651
+			return -1;
3652
+		}
3653
+	}
3654
+
3655
+	return rtpengine_rtpp_set_wrap(msg, rtpengine_unblock_media_wrap, flags.s, 1);
3562 3656
 }
3563 3657
 
3564 3658
 static int rtpengine_rtpstat_wrap(struct sip_msg *msg, void *d, int more) {
... ...
@@ -40,6 +40,8 @@ enum rtpe_operation {
40 40
         OP_PING,
41 41
         OP_BLOCK_DTMF,
42 42
         OP_UNBLOCK_DTMF,
43
+        OP_BLOCK_MEDIA,
44
+        OP_UNBLOCK_MEDIA,
43 45
 };
44 46
 
45 47
 struct rtpp_node {