pjproject: sync patches with asterisk 18.7.1
[feed/telephony.git] / net / asterisk / patches / 090-app_dial-expanded-A-option-to-add-caller-announcement.patch
1 From 1e5a2cfe3037823b17dd4ac47b071f02d6f9825f Mon Sep 17 00:00:00 2001
2 From: Naveen Albert <mail@interlinked.x10host.com>
3 Date: Fri, 21 May 2021 20:08:58 -0400
4 Subject: [PATCH] app_dial: Expanded A option to add caller announcement
5
6 Hitherto, the A option has made it possible to play
7 audio upon answer to the called party only. This option
8 is expanded to allow for playback of an audio file to
9 the caller instead of or in addition to the audio
10 played to the answerer.
11
12 ASTERISK-29442
13
14 Change-Id: If6eed3ff5c341dc8c588c8210987f2571e891e5e
15 ---
16 apps/app_dial.c | 79 +++++++++++++++----
17 doc/CHANGES-staging/app_dial_announcement.txt | 6 ++
18 2 files changed, 68 insertions(+), 17 deletions(-)
19 create mode 100644 doc/CHANGES-staging/app_dial_announcement.txt
20
21 --- a/apps/app_dial.c
22 +++ b/apps/app_dial.c
23 @@ -93,11 +93,17 @@
24 </parameter>
25 <parameter name="options" required="false">
26 <optionlist>
27 - <option name="A">
28 - <argument name="x" required="true">
29 + <option name="A" argsep=":">
30 + <argument name="x">
31 <para>The file to play to the called party</para>
32 </argument>
33 - <para>Play an announcement to the called party, where <replaceable>x</replaceable> is the prompt to be played</para>
34 + <argument name="y">
35 + <para>The file to play to the calling party</para>
36 + </argument>
37 + <para>Play an announcement to the called and/or calling parties, where <replaceable>x</replaceable>
38 + is the prompt to be played to the called party and <replaceable>y</replaceable> is the prompt
39 + to be played to the caller. The files may be different and will be played to each party
40 + simultaneously.</para>
41 </option>
42 <option name="a">
43 <para>Immediately answer the calling channel when the called channel answers in
44 @@ -2941,33 +2947,71 @@ static int dial_exec_full(struct ast_cha
45 int digit = 0;
46 struct ast_channel *chans[2];
47 struct ast_channel *active_chan;
48 + char *calledfile = NULL, *callerfile = NULL;
49 + int calledstream = 0, callerstream = 0;
50
51 chans[0] = chan;
52 chans[1] = peer;
53
54 - /* we need to stream the announcement to the called party when the OPT_ARG_ANNOUNCE (-A) is setted */
55 -
56 - /* stream the file */
57 - res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], ast_channel_language(peer));
58 - if (res) {
59 - res = 0;
60 - ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
61 + /* we need to stream the announcement(s) when the OPT_ARG_ANNOUNCE (-A) is set */
62 + callerfile = opt_args[OPT_ARG_ANNOUNCE];
63 + calledfile = strsep(&callerfile, ":");
64 +
65 + /* stream the file(s) */
66 + if (!ast_strlen_zero(calledfile)) {
67 + res = ast_streamfile(peer, calledfile, ast_channel_language(peer));
68 + if (res) {
69 + res = 0;
70 + ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", calledfile);
71 + } else {
72 + calledstream = 1;
73 + }
74 + }
75 + if (!ast_strlen_zero(callerfile)) {
76 + res = ast_streamfile(chan, callerfile, ast_channel_language(chan));
77 + if (res) {
78 + res = 0;
79 + ast_log(LOG_ERROR, "error streaming file '%s' to caller\n", callerfile);
80 + } else {
81 + callerstream = 1;
82 + }
83 }
84
85 + /* can't use ast_waitstream, because we're streaming two files at once, and can't block
86 + We'll need to handle both channels at once. */
87 +
88 ast_channel_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
89 - while (ast_channel_stream(peer)) {
90 - int ms;
91 + while (ast_channel_stream(peer) || ast_channel_stream(chan)) {
92 + int mspeer, mschan;
93
94 - ms = ast_sched_wait(ast_channel_sched(peer));
95 + mspeer = ast_sched_wait(ast_channel_sched(peer));
96 + mschan = ast_sched_wait(ast_channel_sched(chan));
97
98 - if (ms < 0 && !ast_channel_timingfunc(peer)) {
99 - ast_stopstream(peer);
100 + if (calledstream) {
101 + if (mspeer < 0 && !ast_channel_timingfunc(peer)) {
102 + ast_stopstream(peer);
103 + calledstream = 0;
104 + }
105 + }
106 + if (callerstream) {
107 + if (mschan < 0 && !ast_channel_timingfunc(chan)) {
108 + ast_stopstream(chan);
109 + callerstream = 0;
110 + }
111 + }
112 +
113 + if (!calledstream && !callerstream) {
114 break;
115 }
116 - if (ms < 0)
117 - ms = 1000;
118
119 - active_chan = ast_waitfor_n(chans, 2, &ms);
120 + if (mspeer < 0)
121 + mspeer = 1000;
122 +
123 + if (mschan < 0)
124 + mschan = 1000;
125 +
126 + /* wait for the lowest maximum of the two */
127 + active_chan = ast_waitfor_n(chans, 2, (mspeer > mschan ? &mschan : &mspeer));
128 if (active_chan) {
129 struct ast_channel *other_chan;
130 struct ast_frame *fr = ast_read(active_chan);
131 @@ -3017,6 +3061,7 @@ static int dial_exec_full(struct ast_cha
132 ast_frfree(fr);
133 }
134 ast_sched_runq(ast_channel_sched(peer));
135 + ast_sched_runq(ast_channel_sched(chan));
136 }
137 ast_channel_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
138 }
139 --- /dev/null
140 +++ b/doc/CHANGES-staging/app_dial_announcement.txt
141 @@ -0,0 +1,6 @@
142 +Subject: app_dial announcement option
143 +
144 +The A option for Dial now supports
145 +playing audio to the caller as well
146 +as the called party.
147 +