... | ... |
@@ -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) { |