bridge_features: Support One touch Monitor/MixMonitor
[asterisk/asterisk.git] / bridges / bridge_builtin_features.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Built in bridging features
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  *
25  * \ingroup bridges
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41
42 #include "asterisk/module.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/bridging.h"
45 #include "asterisk/bridging_technology.h"
46 #include "asterisk/frame.h"
47 #include "asterisk/file.h"
48 #include "asterisk/app.h"
49 #include "asterisk/astobj2.h"
50 #include "asterisk/pbx.h"
51 #include "asterisk/parking.h"
52 #include "asterisk/features_config.h"
53 #include "asterisk/monitor.h"
54 #include "asterisk/mixmonitor.h"
55 #include "asterisk/audiohook.h"
56
57 /*!
58  * \brief Helper function that presents dialtone and grabs extension
59  *
60  * \retval 0 on success
61  * \retval -1 on failure
62  */
63 static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
64 {
65         int res;
66         int digit_timeout;
67         RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
68
69         ast_channel_lock(chan);
70         xfer_cfg = ast_get_chan_features_xfer_config(chan);
71         if (!xfer_cfg) {
72                 ast_log(LOG_ERROR, "Unable to get transfer configuration\n");
73                 ast_channel_unlock(chan);
74                 return -1;
75         }
76         digit_timeout = xfer_cfg->transferdigittimeout;
77         ast_channel_unlock(chan);
78
79         /* Play the simple "transfer" prompt out and wait */
80         res = ast_stream_and_wait(chan, "pbx-transfer", AST_DIGIT_ANY);
81         ast_stopstream(chan);
82         if (res < 0) {
83                 /* Hangup or error */
84                 return -1;
85         }
86         if (res) {
87                 /* Store the DTMF digit that interrupted playback of the file. */
88                 exten[0] = res;
89         }
90
91         /* Drop to dialtone so they can enter the extension they want to transfer to */
92         res = ast_app_dtget(chan, context, exten, exten_len, exten_len - 1, digit_timeout);
93         if (res < 0) {
94                 /* Hangup or error */
95                 res = -1;
96         } else if (!res) {
97                 /* 0 for invalid extension dialed. */
98                 if (ast_strlen_zero(exten)) {
99                         ast_debug(1, "%s dialed no digits.\n", ast_channel_name(chan));
100                 } else {
101                         ast_debug(1, "%s dialed '%s@%s' does not exist.\n",
102                                 ast_channel_name(chan), exten, context);
103                 }
104                 ast_stream_and_wait(chan, "pbx-invalid", AST_DIGIT_NONE);
105                 res = -1;
106         } else {
107                 /* Dialed extension is valid. */
108                 res = 0;
109         }
110         return res;
111 }
112
113 static void copy_caller_data(struct ast_channel *dest, struct ast_channel *caller)
114 {
115         ast_channel_lock_both(caller, dest);
116         ast_connected_line_copy_from_caller(ast_channel_connected(dest), ast_channel_caller(caller));
117         ast_channel_inherit_variables(caller, dest);
118         ast_channel_datastore_inherit(caller, dest);
119         ast_channel_unlock(dest);
120         ast_channel_unlock(caller);
121 }
122
123 /*! \brief Helper function that creates an outgoing channel and returns it immediately */
124 static struct ast_channel *dial_transfer(struct ast_channel *caller, const char *exten, const char *context)
125 {
126         char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
127         struct ast_channel *chan;
128         int cause;
129
130         /* Fill the variable with the extension and context we want to call */
131         snprintf(destination, sizeof(destination), "%s@%s", exten, context);
132
133         /* Now we request a local channel to prepare to call the destination */
134         chan = ast_request("Local", ast_channel_nativeformats(caller), caller, destination,
135                 &cause);
136         if (!chan) {
137                 return NULL;
138         }
139
140         /* Who is transferring the call. */
141         pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
142
143         /* Before we actually dial out let's inherit appropriate information. */
144         copy_caller_data(chan, caller);
145
146         /* Since the above worked fine now we actually call it and return the channel */
147         if (ast_call(chan, destination, 0)) {
148                 ast_hangup(chan);
149                 return NULL;
150         }
151
152         return chan;
153 }
154
155 /*!
156  * \internal
157  * \brief Determine the transfer context to use.
158  * \since 12.0.0
159  *
160  * \param transferer Channel initiating the transfer.
161  * \param context User supplied context if available.  May be NULL.
162  *
163  * \return The context to use for the transfer.
164  */
165 static const char *get_transfer_context(struct ast_channel *transferer, const char *context)
166 {
167         if (!ast_strlen_zero(context)) {
168                 return context;
169         }
170         context = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
171         if (!ast_strlen_zero(context)) {
172                 return context;
173         }
174         context = ast_channel_macrocontext(transferer);
175         if (!ast_strlen_zero(context)) {
176                 return context;
177         }
178         context = ast_channel_context(transferer);
179         if (!ast_strlen_zero(context)) {
180                 return context;
181         }
182         return "default";
183 }
184
185 static void blind_transfer_cb(struct ast_channel *new_channel, void *user_data,
186                 enum ast_transfer_type transfer_type)
187 {
188         struct ast_channel *transferer_channel = user_data;
189
190         if (transfer_type == AST_BRIDGE_TRANSFER_MULTI_PARTY) {
191                 copy_caller_data(new_channel, transferer_channel);
192         }
193 }
194
195 /*! \brief Internal built in feature for blind transfers */
196 static int feature_blind_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
197 {
198         char exten[AST_MAX_EXTENSION] = "";
199         struct ast_bridge_features_blind_transfer *blind_transfer = hook_pvt;
200         const char *context;
201         char *goto_on_blindxfr;
202
203         ast_bridge_channel_write_hold(bridge_channel, NULL);
204
205         ast_channel_lock(bridge_channel->chan);
206         context = ast_strdupa(get_transfer_context(bridge_channel->chan,
207                 blind_transfer ? blind_transfer->context : NULL));
208         goto_on_blindxfr = ast_strdupa(S_OR(pbx_builtin_getvar_helper(bridge_channel->chan,
209                 "GOTO_ON_BLINDXFR"), ""));
210         ast_channel_unlock(bridge_channel->chan);
211
212         /* Grab the extension to transfer to */
213         if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), context)) {
214                 ast_bridge_channel_write_unhold(bridge_channel);
215                 return 0;
216         }
217
218         if (!ast_strlen_zero(goto_on_blindxfr)) {
219                 ast_debug(1, "After transfer, transferer %s goes to %s\n",
220                                 ast_channel_name(bridge_channel->chan), goto_on_blindxfr);
221                 ast_after_bridge_set_go_on(bridge_channel->chan, NULL, NULL, 0, goto_on_blindxfr);
222         }
223
224         if (ast_bridge_transfer_blind(0, bridge_channel->chan, exten, context, blind_transfer_cb,
225                         bridge_channel->chan) != AST_BRIDGE_TRANSFER_SUCCESS &&
226                         !ast_strlen_zero(goto_on_blindxfr)) {
227                 ast_after_bridge_goto_discard(bridge_channel->chan);
228         }
229
230         return 0;
231 }
232
233 /*! Attended transfer code */
234 enum atxfer_code {
235         /*! Party C hungup or other reason to abandon the transfer. */
236         ATXFER_INCOMPLETE,
237         /*! Transfer party C to party A. */
238         ATXFER_COMPLETE,
239         /*! Turn the transfer into a threeway call. */
240         ATXFER_THREEWAY,
241         /*! Hangup party C and return party B to the bridge. */
242         ATXFER_ABORT,
243 };
244
245 /*! \brief Attended transfer feature to complete transfer */
246 static int attended_transfer_complete(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
247 {
248         enum atxfer_code *transfer_code = hook_pvt;
249
250         *transfer_code = ATXFER_COMPLETE;
251         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
252         return 0;
253 }
254
255 /*! \brief Attended transfer feature to turn it into a threeway call */
256 static int attended_transfer_threeway(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
257 {
258         enum atxfer_code *transfer_code = hook_pvt;
259
260         *transfer_code = ATXFER_THREEWAY;
261         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
262         return 0;
263 }
264
265 /*! \brief Attended transfer feature to abort transfer */
266 static int attended_transfer_abort(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
267 {
268         enum atxfer_code *transfer_code = hook_pvt;
269
270         *transfer_code = ATXFER_ABORT;
271         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
272         return 0;
273 }
274
275 /*! \brief Internal built in feature for attended transfers */
276 static int feature_attended_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
277 {
278         char exten[AST_MAX_EXTENSION] = "";
279         struct ast_channel *peer;
280         struct ast_bridge *attended_bridge;
281         struct ast_bridge_features caller_features;
282         int xfer_failed;
283         struct ast_bridge_features_attended_transfer *attended_transfer = hook_pvt;
284         const char *complete_sound;
285         const char *context;
286         enum atxfer_code transfer_code = ATXFER_INCOMPLETE;
287         const char *atxfer_abort;
288         const char *atxfer_threeway;
289         const char *atxfer_complete;
290         const char *fail_sound;
291         RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
292
293         ast_bridge_channel_write_hold(bridge_channel, NULL);
294
295         bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
296
297         ast_channel_lock(bridge_channel->chan);
298         context = ast_strdupa(get_transfer_context(bridge_channel->chan,
299                 attended_transfer ? attended_transfer->context : NULL));
300         xfer_cfg = ast_get_chan_features_xfer_config(bridge_channel->chan);
301         if (!xfer_cfg) {
302                 ast_log(LOG_ERROR, "Unable to get transfer configuration options\n");
303                 ast_channel_unlock(bridge_channel->chan);
304                 return 0;
305         }
306         if (attended_transfer) {
307                 atxfer_abort = ast_strdupa(S_OR(attended_transfer->abort, xfer_cfg->atxferabort));
308                 atxfer_threeway = ast_strdupa(S_OR(attended_transfer->threeway, xfer_cfg->atxferthreeway));
309                 atxfer_complete = ast_strdupa(S_OR(attended_transfer->complete, xfer_cfg->atxfercomplete));
310         } else {
311                 atxfer_abort = ast_strdupa(xfer_cfg->atxferabort);
312                 atxfer_threeway = ast_strdupa(xfer_cfg->atxferthreeway);
313                 atxfer_complete = ast_strdupa(xfer_cfg->atxfercomplete);
314         }
315         fail_sound = ast_strdupa(xfer_cfg->xferfailsound);
316         ast_channel_unlock(bridge_channel->chan);
317
318         /* Grab the extension to transfer to */
319         if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), context)) {
320                 ast_bridge_merge_inhibit(bridge, -1);
321                 ao2_ref(bridge, -1);
322                 ast_bridge_channel_write_unhold(bridge_channel);
323                 return 0;
324         }
325
326         /* Get a channel that is the destination we wish to call */
327         peer = dial_transfer(bridge_channel->chan, exten, context);
328         if (!peer) {
329                 ast_bridge_merge_inhibit(bridge, -1);
330                 ao2_ref(bridge, -1);
331                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
332                 ast_bridge_channel_write_unhold(bridge_channel);
333                 return 0;
334         }
335
336 /* BUGBUG bridging API features does not support the features.conf atxfer bounce between C & B channels */
337         /* Setup a DTMF menu to control the transfer. */
338         if (ast_bridge_features_init(&caller_features)
339                 || ast_bridge_hangup_hook(&caller_features,
340                         attended_transfer_complete, &transfer_code, NULL, 0)
341                 || ast_bridge_dtmf_hook(&caller_features, atxfer_abort,
342                         attended_transfer_abort, &transfer_code, NULL, 0)
343                 || ast_bridge_dtmf_hook(&caller_features, atxfer_complete,
344                         attended_transfer_complete, &transfer_code, NULL, 0)
345                 || ast_bridge_dtmf_hook(&caller_features, atxfer_threeway,
346                         attended_transfer_threeway, &transfer_code, NULL, 0)) {
347                 ast_bridge_features_cleanup(&caller_features);
348                 ast_hangup(peer);
349                 ast_bridge_merge_inhibit(bridge, -1);
350                 ao2_ref(bridge, -1);
351                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
352                 ast_bridge_channel_write_unhold(bridge_channel);
353                 return 0;
354         }
355
356         /* Create a bridge to use to talk to the person we are calling */
357         attended_bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX,
358                 AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
359         if (!attended_bridge) {
360                 ast_bridge_features_cleanup(&caller_features);
361                 ast_hangup(peer);
362                 ast_bridge_merge_inhibit(bridge, -1);
363                 ao2_ref(bridge, -1);
364                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
365                 ast_bridge_channel_write_unhold(bridge_channel);
366                 return 0;
367         }
368         ast_bridge_merge_inhibit(attended_bridge, +1);
369
370         /* This is how this is going down, we are imparting the channel we called above into this bridge first */
371 /* BUGBUG we should impart the peer as an independent and move it to the original bridge. */
372         if (ast_bridge_impart(attended_bridge, peer, NULL, NULL, 0)) {
373                 ast_bridge_destroy(attended_bridge);
374                 ast_bridge_features_cleanup(&caller_features);
375                 ast_hangup(peer);
376                 ast_bridge_merge_inhibit(bridge, -1);
377                 ao2_ref(bridge, -1);
378                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
379                 ast_bridge_channel_write_unhold(bridge_channel);
380                 return 0;
381         }
382
383         /*
384          * For the caller we want to join the bridge in a blocking
385          * fashion so we don't spin around in this function doing
386          * nothing while waiting.
387          */
388         ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features, NULL, 0);
389
390 /*
391  * BUGBUG there is a small window where the channel does not point to the bridge_channel.
392  *
393  * This window is expected to go away when atxfer is redesigned
394  * to fully support existing functionality.  There will be one
395  * and only one ast_bridge_channel structure per channel.
396  */
397         /* Point the channel back to the original bridge and bridge_channel. */
398         ast_bridge_channel_lock(bridge_channel);
399         ast_channel_lock(bridge_channel->chan);
400         ast_channel_internal_bridge_channel_set(bridge_channel->chan, bridge_channel);
401         ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
402         ast_channel_unlock(bridge_channel->chan);
403         ast_bridge_channel_unlock(bridge_channel);
404
405         /* Wait for peer thread to exit bridge and die. */
406         if (!ast_autoservice_start(bridge_channel->chan)) {
407                 ast_bridge_depart(peer);
408                 ast_autoservice_stop(bridge_channel->chan);
409         } else {
410                 ast_bridge_depart(peer);
411         }
412
413         /* Now that all channels are out of it we can destroy the bridge and the feature structures */
414         ast_bridge_destroy(attended_bridge);
415         ast_bridge_features_cleanup(&caller_features);
416
417         /* Is there a courtesy sound to play to the peer? */
418         ast_channel_lock(bridge_channel->chan);
419         complete_sound = pbx_builtin_getvar_helper(bridge_channel->chan,
420                 "ATTENDED_TRANSFER_COMPLETE_SOUND");
421         if (!ast_strlen_zero(complete_sound)) {
422                 complete_sound = ast_strdupa(complete_sound);
423         } else {
424                 complete_sound = NULL;
425         }
426         ast_channel_unlock(bridge_channel->chan);
427         if (complete_sound) {
428                 pbx_builtin_setvar_helper(peer, "BRIDGE_PLAY_SOUND", complete_sound);
429         }
430
431         xfer_failed = -1;
432         switch (transfer_code) {
433         case ATXFER_INCOMPLETE:
434                 /* Peer hungup */
435                 break;
436         case ATXFER_COMPLETE:
437                 /* The peer takes our place in the bridge. */
438                 ast_bridge_channel_write_unhold(bridge_channel);
439                 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
440                 xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, bridge_channel->chan, NULL, 1);
441                 break;
442         case ATXFER_THREEWAY:
443                 /*
444                  * Transferer wants to convert to a threeway call.
445                  *
446                  * Just impart the peer onto the bridge and have us return to it
447                  * as normal.
448                  */
449                 ast_bridge_channel_write_unhold(bridge_channel);
450                 xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, NULL, NULL, 1);
451                 break;
452         case ATXFER_ABORT:
453                 /* Transferer decided not to transfer the call after all. */
454                 break;
455         }
456         ast_bridge_merge_inhibit(bridge, -1);
457         ao2_ref(bridge, -1);
458         if (xfer_failed) {
459                 ast_hangup(peer);
460                 if (!ast_check_hangup_locked(bridge_channel->chan)) {
461                         ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
462                 }
463                 ast_bridge_channel_write_unhold(bridge_channel);
464         }
465
466         return 0;
467 }
468
469 static void stop_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg)
470 {
471         const char *stop_message;
472
473         ast_channel_lock(bridge_channel->chan);
474         stop_message = pbx_builtin_getvar_helper(bridge_channel->chan, "TOUCH_MONITOR_MESSAGE_STOP");
475         stop_message = ast_strdupa(S_OR(stop_message, ""));
476         ast_channel_unlock(bridge_channel->chan);
477
478         ast_verb(3, "AutoMonitor used to stop recording call.\n");
479
480         ast_channel_lock(peer_chan);
481         if (ast_channel_monitor(peer_chan)) {
482                 if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {
483                         ast_verb(3, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));
484                         if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
485                                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
486                         }
487                         ast_channel_unlock(peer_chan);
488                         return;
489                 }
490         } else {
491                 /* Something else removed the Monitor before we got to it. */
492                 ast_channel_unlock(peer_chan);
493                 return;
494         }
495
496         ast_channel_unlock(peer_chan);
497
498         if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
499                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
500                 ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
501         }
502
503         if (!ast_strlen_zero(stop_message)) {
504                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
505                 ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
506         }
507 }
508
509 enum set_touch_variables_res {
510         SET_TOUCH_SUCCESS = 0,
511         SET_TOUCH_UNSET,
512         SET_TOUCH_ALLOC_FAILURE,
513 };
514
515 static int set_touch_variables(struct ast_channel *chan, int is_mixmonitor, char **touch_format, char **touch_monitor, char **touch_monitor_prefix)
516 {
517         enum set_touch_variables_res res = SET_TOUCH_UNSET;
518         const char *c_touch_format, *c_touch_monitor, *c_touch_monitor_prefix;
519
520         SCOPED_CHANNELLOCK(lock, chan);
521
522         c_touch_format = pbx_builtin_getvar_helper(chan, is_mixmonitor ? "TOUCH_MIXMONITOR_FORMAT" : "TOUCH_MONITOR_FORMAT");
523
524         if (!ast_strlen_zero(c_touch_format)) {
525                 if (!(*touch_format = ast_strdup(c_touch_format))) {
526                         return SET_TOUCH_ALLOC_FAILURE;
527                 }
528                 res = SET_TOUCH_SUCCESS;
529         }
530
531         c_touch_monitor = pbx_builtin_getvar_helper(chan, is_mixmonitor ? "TOUCH_MIXMONITOR" : "TOUCH_MONITOR");
532
533         if (!ast_strlen_zero(c_touch_monitor)) {
534                 if (!(*touch_monitor = ast_strdup(c_touch_monitor))) {
535                         return SET_TOUCH_ALLOC_FAILURE;
536                 }
537                 res = SET_TOUCH_SUCCESS;
538         }
539
540         c_touch_monitor_prefix = pbx_builtin_getvar_helper(chan, is_mixmonitor ? "TOUCH_MIXMONITOR_PREFIX" : "TOUCH_MONITOR_PREFIX");
541
542         if (!ast_strlen_zero(c_touch_monitor_prefix)) {
543                 if (!(*touch_monitor_prefix = ast_strdup(c_touch_monitor_prefix))) {
544                         return SET_TOUCH_ALLOC_FAILURE;
545                 }
546                 res = SET_TOUCH_SUCCESS;
547         }
548
549         return res;
550 }
551
552 static int feature_automonitor(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
553 {
554         char *caller_chan_id = NULL, *peer_chan_id = NULL, *touch_filename = NULL;
555         size_t len;
556         const char *automon_message;
557         int x;
558         enum set_touch_variables_res set_touch_res;
559
560         RAII_VAR(char *, touch_format, NULL, ast_free);
561         RAII_VAR(char *, touch_monitor, NULL, ast_free);
562         RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
563
564         RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
565         RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
566
567         features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
568         peer_chan = ast_bridge_peer(bridge, bridge_channel->chan);
569
570         if (!peer_chan) {
571                 ast_verb(3, "Cannot start AutoMonitor for %s - can not determine peer in bridge.\n", ast_channel_name(bridge_channel->chan));
572                 if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
573                         ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
574                 }
575                 return 0;
576         }
577
578         if (ast_channel_monitor(peer_chan)) {
579                 stop_automonitor(bridge_channel, peer_chan, features_cfg);
580                 return 0;
581         }
582
583         if ((set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format, &touch_monitor, &touch_monitor_prefix))) {
584                 if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
585                         return 0;
586                 }
587                 if (set_touch_variables(peer_chan, 0, &touch_format, &touch_monitor, &touch_monitor_prefix) == SET_TOUCH_ALLOC_FAILURE) {
588                         return 0;
589                 }
590         }
591
592         if (!ast_strlen_zero(touch_monitor)) {
593                 len = strlen(touch_monitor) + 50;
594                 touch_filename = ast_alloca(len);
595                 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
596         } else {
597                 caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
598                         ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
599                 peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
600                         ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
601                 len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
602                 touch_filename = ast_alloca(len);
603                 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, peer_chan_id);
604         }
605
606         for ( x = 0; x < strlen(touch_filename); x++) {
607                 if (touch_filename[x] == '/') {
608                         touch_filename[x] = '-';
609                 }
610         }
611
612         ast_verb(3, "AutoMonitor used to record call. Filename: %s\n", touch_filename);
613
614         if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT)) {
615                 ast_verb(3, "automon feature was tried by '%s' but monitor failed to start.\n", ast_channel_name(bridge_channel->chan));
616                 return 0;
617         }
618
619         ast_channel_lock(bridge_channel->chan);
620         if ((automon_message = pbx_builtin_getvar_helper(bridge_channel->chan, "TOUCH_MONITOR_MESSAGE_START"))) {
621                 automon_message = ast_strdupa(automon_message);
622         }
623         ast_channel_unlock(bridge_channel->chan);
624
625         if ((features_cfg = ast_get_chan_features_general_config(bridge_channel->chan)) && !(ast_strlen_zero(features_cfg->courtesytone))) {
626                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
627                 ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
628         }
629
630         if (!ast_strlen_zero(automon_message)) {
631                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, automon_message, NULL);
632                 ast_bridge_channel_write_playfile(bridge_channel, NULL, automon_message, NULL);
633         }
634
635         pbx_builtin_setvar_helper(peer_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
636
637         return 0;
638 }
639
640 static void stop_automixmonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg)
641 {
642         const char *stop_message;
643
644         ast_channel_lock(bridge_channel->chan);
645         stop_message = pbx_builtin_getvar_helper(bridge_channel->chan, "TOUCH_MIXMONITOR_MESSAGE_STOP");
646         stop_message = ast_strdupa(S_OR(stop_message, ""));
647         ast_channel_unlock(bridge_channel->chan);
648
649         ast_verb(3, "AutoMixMonitor used to stop recording call.\n");
650
651         if (ast_stop_mixmonitor(peer_chan, NULL)) {
652                 ast_verb(3, "Failed to stop Mixmonitor for %s.\n", ast_channel_name(bridge_channel->chan));
653                 if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
654                         ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
655                 }
656                 return;
657         }
658
659         if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
660                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
661                 ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
662         }
663
664         if (!ast_strlen_zero(stop_message)) {
665                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
666                 ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
667         }
668
669 }
670
671 static int feature_automixmonitor(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
672 {
673         char *caller_chan_id = NULL, *peer_chan_id = NULL, *touch_filename = NULL;
674         size_t len;
675         const char *automon_message;
676         static char *mixmonitor_spy_type = "MixMonitor";
677         int count, x;
678         enum set_touch_variables_res set_touch_res;
679
680         RAII_VAR(char *, touch_format, NULL, ast_free);
681         RAII_VAR(char *, touch_monitor, NULL, ast_free);
682         RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
683
684         RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
685         RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
686
687         features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
688
689         peer_chan = ast_bridge_peer(bridge, bridge_channel->chan);
690
691         if (!peer_chan) {
692                 ast_verb(3, "Cannot start AutoMixMonitor for %s - can not determine peer in bridge.\n", ast_channel_name(bridge_channel->chan));
693                 if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
694                         ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
695                 }
696                 return 0;
697         }
698
699         count = ast_channel_audiohook_count_by_source(peer_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
700         if (count > 0) {
701                 stop_automixmonitor(bridge_channel, peer_chan, features_cfg);
702                 return 0;
703         }
704
705         if ((set_touch_res = set_touch_variables(bridge_channel->chan, 1, &touch_format, &touch_monitor, &touch_monitor_prefix))) {
706                 if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
707                         return 0;
708                 }
709                 if (set_touch_variables(peer_chan, 1, &touch_format, &touch_monitor, &touch_monitor_prefix) == SET_TOUCH_ALLOC_FAILURE) {
710                         return 0;
711                 }
712         }
713
714         if (!ast_strlen_zero(touch_monitor)) {
715                 len = strlen(touch_monitor) + 50;
716                 touch_filename = ast_alloca(len);
717                 snprintf(touch_filename, len, "%s-%ld-%s.%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor, S_OR(touch_format, "wav"));
718         } else {
719                 caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
720                         ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
721                 peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
722                         ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
723                 len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
724                 touch_filename = ast_alloca(len);
725                 snprintf(touch_filename, len, "%s-%ld-%s-%s.%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, peer_chan_id, S_OR(touch_format, "wav"));
726         }
727
728         for ( x = 0; x < strlen(touch_filename); x++) {
729                 if (touch_filename[x] == '/') {
730                         touch_filename[x] = '-';
731                 }
732         }
733
734         ast_verb(3, "AutoMixMonitor used to record call. Filename: %s\n", touch_filename);
735
736         if (ast_start_mixmonitor(peer_chan, touch_filename, "b")) {
737                 ast_verb(3, "automixmon feature was tried by '%s' but mixmonitor failed to start.\n", ast_channel_name(bridge_channel->chan));
738
739                 if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
740                         ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
741                 }
742
743                 return 0;
744         }
745
746         ast_channel_lock(bridge_channel->chan);
747         if ((automon_message = pbx_builtin_getvar_helper(bridge_channel->chan, "TOUCH_MIXMONITOR_MESSAGE_START"))) {
748                 automon_message = ast_strdupa(automon_message);
749         }
750         ast_channel_unlock(bridge_channel->chan);
751
752         if ((features_cfg = ast_get_chan_features_general_config(bridge_channel->chan)) && !(ast_strlen_zero(features_cfg->courtesytone))) {
753                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
754                 ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
755         }
756
757         if (!ast_strlen_zero(automon_message)) {
758                 ast_bridge_channel_queue_playfile(bridge_channel, NULL, automon_message, NULL);
759                 ast_bridge_channel_write_playfile(bridge_channel, NULL, automon_message, NULL);
760         }
761
762         pbx_builtin_setvar_helper(peer_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
763
764         return 0;
765 }
766
767 /*! \brief Internal built in feature for hangup */
768 static int feature_hangup(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
769 {
770         /*
771          * This is very simple, we simply change the state on the
772          * bridge_channel to force the channel out of the bridge and the
773          * core takes care of the rest.
774          */
775         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
776         return 0;
777 }
778
779 static int unload_module(void)
780 {
781         return 0;
782 }
783
784 static int load_module(void)
785 {
786         ast_bridge_features_register(AST_BRIDGE_BUILTIN_BLINDTRANSFER, feature_blind_transfer, NULL);
787         ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, feature_attended_transfer, NULL);
788         ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);
789         ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMON, feature_automonitor, NULL);
790         ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMIXMON, feature_automixmonitor, NULL);
791
792         /* Bump up our reference count so we can't be unloaded */
793         ast_module_ref(ast_module_info->self);
794
795         return AST_MODULE_LOAD_SUCCESS;
796 }
797
798 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Built in bridging features");