Skip to content

Commit ee9eef4

Browse files
InterLinked1Friendly Automation
authored and
Friendly Automation
committed
app_mf: Add full tech-agnostic MF support
Adds tech-agnostic support for MF signaling by adding MF sender and receiver applications as well as Dial integration. ASTERISK-29496-mf #do-not-close Change-Id: I61962b359b8ec4cfd05df877ddf9f5b8f71927a4
1 parent 67c4661 commit ee9eef4

File tree

7 files changed

+588
-144
lines changed

7 files changed

+588
-144
lines changed

apps/app_dial.c

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,24 @@
156156
<argument name="called" />
157157
<argument name="calling" />
158158
<argument name="progress" />
159+
<argument name="mfprogress" />
160+
<argument name="mfwink" />
159161
<para>Send the specified DTMF strings <emphasis>after</emphasis> the called
160162
party has answered, but before the call gets bridged. The
161163
<replaceable>called</replaceable> DTMF string is sent to the called party, and the
162164
<replaceable>calling</replaceable> DTMF string is sent to the calling party. Both arguments
163165
can be used alone. If <replaceable>progress</replaceable> is specified, its DTMF is sent
164166
to the called party immediately after receiving a <literal>PROGRESS</literal> message.</para>
165167
<para>See <literal>SendDTMF</literal> for valid digits.</para>
168+
<para>If <replaceable>mfprogress</replaceable> is specified, its MF is sent
169+
to the called party immediately after receiving a <literal>PROGRESS</literal> message.
170+
If <replaceable>mfwink</replaceable> is specified, its MF is sent
171+
to the called party immediately after receiving a <literal>WINK</literal> message.</para>
172+
<para>See <literal>SendMF</literal> for valid digits.</para>
173+
</option>
174+
<option name="E">
175+
<para>Enable echoing of sent MF or SF digits back to caller (e.g. "hearpulsing").
176+
Used in conjunction with the D option.</para>
166177
</option>
167178
<option name="e">
168179
<para>Execute the <literal>h</literal> extension for peer after the call ends</para>
@@ -499,7 +510,6 @@
499510
answered, if it has not already been answered. These two channels will then
500511
be active in a bridged call. All other channels that were requested will then
501512
be hung up.</para>
502-
503513
<para>Unless there is a timeout specified, the Dial application will wait
504514
indefinitely until one of the called channels answers, the user hangs up, or
505515
if all of the called channels are busy or unavailable. Dialplan execution will
@@ -512,7 +522,6 @@
512522
If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
513523
application will be put into that group (as in <literal>Set(GROUP()=...</literal>). Unlike <variable>OUTBOUND_GROUP</variable>,
514524
however, the variable will be unset after use.</para>
515-
516525
<example title="Dial with 30 second timeout">
517526
same => n,Dial(PJSIP/alice,30)
518527
</example>
@@ -534,28 +543,22 @@
534543
</example>
535544
<example title="Dial with pre-dial subroutines">
536545
[default]
537-
538546
exten => callee_channel,1,NoOp(ARG1=${ARG1} ARG2=${ARG2})
539547
same => n,Log(NOTICE, I'm called on channel ${CHANNEL} prior to it starting the dial attempt)
540548
same => n,Return()
541-
542549
exten => called_channel,1,NoOp(ARG1=${ARG1} ARG2=${ARG2})
543550
same => n,Log(NOTICE, I'm called on outbound channel ${CHANNEL} prior to it being used to dial someone)
544551
same => n,Return()
545-
546552
exten => _X.,1,NoOp()
547553
same => n,Dial(PJSIP/alice,,b(default^called_channel^1(my_gosub_arg1^my_gosub_arg2))B(default^callee_channel^1(my_gosub_arg1^my_gosub_arg2)))
548554
same => n,Hangup()
549555
</example>
550556
<example title="Dial with post-answer subroutine executed on outbound channel">
551557
[my_gosub_routine]
552-
553558
exten => s,1,NoOp(ARG1=${ARG1} ARG2=${ARG2})
554559
same => n,Playback(hello)
555560
same => n,Return()
556-
557561
[default]
558-
559562
exten => _X.,1,NoOp()
560563
same => n,Dial(PJSIP/alice,,U(my_gosub_routine^my_gosub_arg1^my_gosub_arg2))
561564
same => n,Hangup()
@@ -717,6 +720,7 @@ enum {
717720
#define OPT_PREDIAL_CALLER (1LLU << 42)
718721
#define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
719722
#define OPT_HANGUPCAUSE (1LLU << 44)
723+
#define OPT_HEARPULSING (1LLU << 45)
720724

721725
enum {
722726
OPT_ARG_ANNOUNCE = 0,
@@ -752,6 +756,7 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
752756
AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
753757
AST_APP_OPTION('d', OPT_DTMF_EXIT),
754758
AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
759+
AST_APP_OPTION('E', OPT_HEARPULSING),
755760
AST_APP_OPTION('e', OPT_PEER_H),
756761
AST_APP_OPTION_ARG('f', OPT_FORCECLID, OPT_ARG_FORCECLID),
757762
AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
@@ -1208,6 +1213,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
12081213
char *opt_args[],
12091214
struct privacy_args *pa,
12101215
const struct cause_args *num_in, int *result, char *dtmf_progress,
1216+
char *mf_progress, char *mf_wink,
1217+
const int hearpulsing,
12111218
const int ignore_cc,
12121219
struct ast_party_id *forced_clid, struct ast_party_id *stored_clid,
12131220
struct ast_bridge_config *config)
@@ -1227,7 +1234,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
12271234
int cc_frame_received = 0;
12281235
int num_ringing = 0;
12291236
int sent_ring = 0;
1230-
int sent_progress = 0;
1237+
int sent_progress = 0, sent_wink = 0;
12311238
struct timeval start = ast_tvnow();
12321239
SCOPE_ENTER(3, "%s\n", ast_channel_name(in));
12331240

@@ -1565,6 +1572,14 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
15651572
ast_channel_unlock(in);
15661573
sent_progress = 1;
15671574

1575+
if (!ast_strlen_zero(mf_progress)) {
1576+
ast_verb(3,
1577+
"Sending MF '%s' to %s as result of "
1578+
"receiving a PROGRESS message.\n",
1579+
mf_progress, hearpulsing ? "parties" : "called party");
1580+
ast_mf_stream(c, (hearpulsing ? NULL : in),
1581+
(hearpulsing ? in : NULL), mf_progress, 50, 55, 120, 65, 0);
1582+
}
15681583
if (!ast_strlen_zero(dtmf_progress)) {
15691584
ast_verb(3,
15701585
"Sending DTMF '%s' to the called party as result of "
@@ -1575,6 +1590,20 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
15751590
}
15761591
ast_channel_publish_dial(in, c, NULL, "PROGRESS");
15771592
break;
1593+
case AST_CONTROL_WINK:
1594+
ast_verb(3, "%s winked, passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1595+
if (!sent_wink) {
1596+
sent_wink = 1;
1597+
if (!ast_strlen_zero(mf_wink)) {
1598+
ast_verb(3,
1599+
"Sending MF '%s' to %s as result of "
1600+
"receiving a WINK message.\n",
1601+
mf_wink, (hearpulsing ? "parties" : "called party"));
1602+
ast_mf_stream(c, (hearpulsing ? NULL : in),
1603+
(hearpulsing ? in : NULL), mf_wink, 50, 55, 120, 65, 0);
1604+
}
1605+
}
1606+
break;
15781607
case AST_CONTROL_VIDUPDATE:
15791608
case AST_CONTROL_SRCUPDATE:
15801609
case AST_CONTROL_SRCCHANGE:
@@ -2132,9 +2161,7 @@ static int setup_privacy_args(struct privacy_args *pa,
21322161
/* the file doesn't exist yet. Let the caller submit his
21332162
vocal intro for posterity */
21342163
/* priv-recordintro script:
2135-
21362164
"At the tone, please say your name:"
2137-
21382165
*/
21392166
int silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
21402167
ast_answer(chan);
@@ -2249,7 +2276,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
22492276

22502277
struct ast_bridge_config config = { { 0, } };
22512278
struct timeval calldurationlimit = { 0, };
2252-
char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
2279+
char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress = NULL;
2280+
char *mf_progress = NULL, *mf_wink = NULL;
22532281
struct privacy_args pa = {
22542282
.sentringing = 0,
22552283
.privdb_val = 0,
@@ -2385,9 +2413,11 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
23852413
}
23862414

23872415
if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2388-
dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
2389-
dtmfcalled = strsep(&dtmf_progress, ":");
2390-
dtmfcalling = strsep(&dtmf_progress, ":");
2416+
mf_wink = opt_args[OPT_ARG_SENDDTMF];
2417+
dtmfcalled = strsep(&mf_wink, ":");
2418+
dtmfcalling = strsep(&mf_wink, ":");
2419+
dtmf_progress = strsep(&mf_wink, ":");
2420+
mf_progress = strsep(&mf_wink, ":");
23912421
}
23922422

23932423
if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
@@ -2864,7 +2894,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
28642894
}
28652895

28662896
peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2867-
dtmf_progress, ignore_cc, &forced_clid, &stored_clid, &config);
2897+
dtmf_progress, mf_progress, mf_wink, (ast_test_flag64(&opts, OPT_HEARPULSING) ? 1 : 0),
2898+
ignore_cc, &forced_clid, &stored_clid, &config);
28682899

28692900
if (!peer) {
28702901
if (result) {
@@ -3542,4 +3573,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Dialing Application",
35423573
.load = load_module,
35433574
.unload = unload_module,
35443575
.requires = "ccss",
3545-
);
3576+
);

0 commit comments

Comments
 (0)