Refactor the features configuration scheme.
[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
54 /*!
55  * \brief Helper function that presents dialtone and grabs extension
56  *
57  * \retval 0 on success
58  * \retval -1 on failure
59  */
60 static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
61 {
62         int res;
63         int digit_timeout;
64         RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
65
66         ast_channel_lock(chan);
67         xfer_cfg = ast_get_chan_features_xfer_config(chan);
68         if (!xfer_cfg) {
69                 ast_log(LOG_ERROR, "Unable to get transfer configuration\n");
70                 ast_channel_unlock(chan);
71                 return -1;
72         }
73         digit_timeout = xfer_cfg->transferdigittimeout;
74         ast_channel_unlock(chan);
75
76         /* Play the simple "transfer" prompt out and wait */
77         res = ast_stream_and_wait(chan, "pbx-transfer", AST_DIGIT_ANY);
78         ast_stopstream(chan);
79         if (res < 0) {
80                 /* Hangup or error */
81                 return -1;
82         }
83         if (res) {
84                 /* Store the DTMF digit that interrupted playback of the file. */
85                 exten[0] = res;
86         }
87
88         /* Drop to dialtone so they can enter the extension they want to transfer to */
89         res = ast_app_dtget(chan, context, exten, exten_len, exten_len - 1, digit_timeout);
90         if (res < 0) {
91                 /* Hangup or error */
92                 res = -1;
93         } else if (!res) {
94                 /* 0 for invalid extension dialed. */
95                 if (ast_strlen_zero(exten)) {
96                         ast_debug(1, "%s dialed no digits.\n", ast_channel_name(chan));
97                 } else {
98                         ast_debug(1, "%s dialed '%s@%s' does not exist.\n",
99                                 ast_channel_name(chan), exten, context);
100                 }
101                 ast_stream_and_wait(chan, "pbx-invalid", AST_DIGIT_NONE);
102                 res = -1;
103         } else {
104                 /* Dialed extension is valid. */
105                 res = 0;
106         }
107         return res;
108 }
109
110 static void copy_caller_data(struct ast_channel *dest, struct ast_channel *caller)
111 {
112         ast_channel_lock_both(caller, dest);
113         ast_connected_line_copy_from_caller(ast_channel_connected(dest), ast_channel_caller(caller));
114         ast_channel_inherit_variables(caller, dest);
115         ast_channel_datastore_inherit(caller, dest);
116         ast_channel_unlock(dest);
117         ast_channel_unlock(caller);
118 }
119
120 /*! \brief Helper function that creates an outgoing channel and returns it immediately */
121 static struct ast_channel *dial_transfer(struct ast_channel *caller, const char *exten, const char *context)
122 {
123         char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
124         struct ast_channel *chan;
125         int cause;
126
127         /* Fill the variable with the extension and context we want to call */
128         snprintf(destination, sizeof(destination), "%s@%s", exten, context);
129
130         /* Now we request a local channel to prepare to call the destination */
131         chan = ast_request("Local", ast_channel_nativeformats(caller), caller, destination,
132                 &cause);
133         if (!chan) {
134                 return NULL;
135         }
136
137         /* Before we actually dial out let's inherit appropriate information. */
138         copy_caller_data(chan, caller);
139
140         /* Since the above worked fine now we actually call it and return the channel */
141         if (ast_call(chan, destination, 0)) {
142                 ast_hangup(chan);
143                 return NULL;
144         }
145
146         return chan;
147 }
148
149 /*!
150  * \internal
151  * \brief Determine the transfer context to use.
152  * \since 12.0.0
153  *
154  * \param transferer Channel initiating the transfer.
155  * \param context User supplied context if available.  May be NULL.
156  *
157  * \return The context to use for the transfer.
158  */
159 static const char *get_transfer_context(struct ast_channel *transferer, const char *context)
160 {
161         if (!ast_strlen_zero(context)) {
162                 return context;
163         }
164         context = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
165         if (!ast_strlen_zero(context)) {
166                 return context;
167         }
168         context = ast_channel_macrocontext(transferer);
169         if (!ast_strlen_zero(context)) {
170                 return context;
171         }
172         context = ast_channel_context(transferer);
173         if (!ast_strlen_zero(context)) {
174                 return context;
175         }
176         return "default";
177 }
178
179 static void blind_transfer_cb(struct ast_channel *new_channel, void *user_data,
180                 enum ast_transfer_type transfer_type)
181 {
182         struct ast_channel *transferer_channel = user_data;
183
184         if (transfer_type == AST_BRIDGE_TRANSFER_MULTI_PARTY) {
185                 copy_caller_data(new_channel, transferer_channel);
186         }
187 }
188
189 /*! \brief Internal built in feature for blind transfers */
190 static int feature_blind_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
191 {
192         char exten[AST_MAX_EXTENSION] = "";
193         struct ast_bridge_features_blind_transfer *blind_transfer = hook_pvt;
194         const char *context;
195         char *goto_on_blindxfr;
196
197         ast_bridge_channel_write_hold(bridge_channel, NULL);
198
199         ast_channel_lock(bridge_channel->chan);
200         context = ast_strdupa(get_transfer_context(bridge_channel->chan,
201                 blind_transfer ? blind_transfer->context : NULL));
202         goto_on_blindxfr = ast_strdupa(S_OR(pbx_builtin_getvar_helper(bridge_channel->chan,
203                 "GOTO_ON_BLINDXFR"), ""));
204         ast_channel_unlock(bridge_channel->chan);
205
206         /* Grab the extension to transfer to */
207         if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), context)) {
208                 ast_bridge_channel_write_unhold(bridge_channel);
209                 return 0;
210         }
211
212         if (!ast_strlen_zero(goto_on_blindxfr)) {
213                 ast_debug(1, "After transfer, transferer %s goes to %s\n",
214                                 ast_channel_name(bridge_channel->chan), goto_on_blindxfr);
215                 ast_after_bridge_set_go_on(bridge_channel->chan, NULL, NULL, 0, goto_on_blindxfr);
216         }
217
218         if (ast_bridge_transfer_blind(bridge_channel->chan, exten, context, blind_transfer_cb,
219                         bridge_channel->chan) != AST_BRIDGE_TRANSFER_SUCCESS &&
220                         !ast_strlen_zero(goto_on_blindxfr)) {
221                 ast_after_bridge_goto_discard(bridge_channel->chan);
222         }
223
224         return 0;
225 }
226
227 /*! Attended transfer code */
228 enum atxfer_code {
229         /*! Party C hungup or other reason to abandon the transfer. */
230         ATXFER_INCOMPLETE,
231         /*! Transfer party C to party A. */
232         ATXFER_COMPLETE,
233         /*! Turn the transfer into a threeway call. */
234         ATXFER_THREEWAY,
235         /*! Hangup party C and return party B to the bridge. */
236         ATXFER_ABORT,
237 };
238
239 /*! \brief Attended transfer feature to complete transfer */
240 static int attended_transfer_complete(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
241 {
242         enum atxfer_code *transfer_code = hook_pvt;
243
244         *transfer_code = ATXFER_COMPLETE;
245         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
246         return 0;
247 }
248
249 /*! \brief Attended transfer feature to turn it into a threeway call */
250 static int attended_transfer_threeway(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
251 {
252         enum atxfer_code *transfer_code = hook_pvt;
253
254         *transfer_code = ATXFER_THREEWAY;
255         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
256         return 0;
257 }
258
259 /*! \brief Attended transfer feature to abort transfer */
260 static int attended_transfer_abort(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
261 {
262         enum atxfer_code *transfer_code = hook_pvt;
263
264         *transfer_code = ATXFER_ABORT;
265         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
266         return 0;
267 }
268
269 /*! \brief Internal built in feature for attended transfers */
270 static int feature_attended_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
271 {
272         char exten[AST_MAX_EXTENSION] = "";
273         struct ast_channel *peer;
274         struct ast_bridge *attended_bridge;
275         struct ast_bridge_features caller_features;
276         int xfer_failed;
277         struct ast_bridge_features_attended_transfer *attended_transfer = hook_pvt;
278         const char *context;
279         enum atxfer_code transfer_code = ATXFER_INCOMPLETE;
280         const char *atxfer_abort;
281         const char *atxfer_threeway;
282         const char *atxfer_complete;
283         const char *fail_sound;
284         RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
285
286         ast_bridge_channel_write_hold(bridge_channel, NULL);
287
288         bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
289
290         ast_channel_lock(bridge_channel->chan);
291         context = ast_strdupa(get_transfer_context(bridge_channel->chan,
292                 attended_transfer ? attended_transfer->context : NULL));
293         xfer_cfg = ast_get_chan_features_xfer_config(bridge_channel->chan);
294         if (!xfer_cfg) {
295                 ast_log(LOG_ERROR, "Unable to get transfer configuration options\n");
296                 ast_channel_unlock(bridge_channel->chan);
297                 return 0;
298         }
299         if (attended_transfer) {
300                 atxfer_abort = ast_strdupa(S_OR(attended_transfer->abort, xfer_cfg->atxferabort));
301                 atxfer_threeway = ast_strdupa(S_OR(attended_transfer->threeway, xfer_cfg->atxferthreeway));
302                 atxfer_complete = ast_strdupa(S_OR(attended_transfer->complete, xfer_cfg->atxfercomplete));
303         } else {
304                 atxfer_abort = ast_strdupa(xfer_cfg->atxferabort);
305                 atxfer_threeway = ast_strdupa(xfer_cfg->atxferthreeway);
306                 atxfer_complete = ast_strdupa(xfer_cfg->atxfercomplete);
307         }
308         fail_sound = ast_strdupa(xfer_cfg->xferfailsound);
309         ast_channel_unlock(bridge_channel->chan);
310
311         /* Grab the extension to transfer to */
312         if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), context)) {
313                 ast_bridge_merge_inhibit(bridge, -1);
314                 ao2_ref(bridge, -1);
315                 ast_bridge_channel_write_unhold(bridge_channel);
316                 return 0;
317         }
318
319         /* Get a channel that is the destination we wish to call */
320         peer = dial_transfer(bridge_channel->chan, exten, context);
321         if (!peer) {
322                 ast_bridge_merge_inhibit(bridge, -1);
323                 ao2_ref(bridge, -1);
324                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
325                 ast_bridge_channel_write_unhold(bridge_channel);
326                 return 0;
327         }
328
329 /* BUGBUG bridging API features does not support the features.conf atxfer bounce between C & B channels */
330         /* Setup a DTMF menu to control the transfer. */
331         if (ast_bridge_features_init(&caller_features)
332                 || ast_bridge_hangup_hook(&caller_features,
333                         attended_transfer_complete, &transfer_code, NULL, 0)
334                 || ast_bridge_dtmf_hook(&caller_features, atxfer_abort,
335                         attended_transfer_abort, &transfer_code, NULL, 0)
336                 || ast_bridge_dtmf_hook(&caller_features, atxfer_complete,
337                         attended_transfer_complete, &transfer_code, NULL, 0)
338                 || ast_bridge_dtmf_hook(&caller_features, atxfer_threeway,
339                         attended_transfer_threeway, &transfer_code, NULL, 0)) {
340                 ast_bridge_features_cleanup(&caller_features);
341                 ast_hangup(peer);
342                 ast_bridge_merge_inhibit(bridge, -1);
343                 ao2_ref(bridge, -1);
344                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
345                 ast_bridge_channel_write_unhold(bridge_channel);
346                 return 0;
347         }
348
349         /* Create a bridge to use to talk to the person we are calling */
350         attended_bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX,
351                 AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
352         if (!attended_bridge) {
353                 ast_bridge_features_cleanup(&caller_features);
354                 ast_hangup(peer);
355                 ast_bridge_merge_inhibit(bridge, -1);
356                 ao2_ref(bridge, -1);
357                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
358                 ast_bridge_channel_write_unhold(bridge_channel);
359                 return 0;
360         }
361         ast_bridge_merge_inhibit(attended_bridge, +1);
362
363         /* This is how this is going down, we are imparting the channel we called above into this bridge first */
364 /* BUGBUG we should impart the peer as an independent and move it to the original bridge. */
365         if (ast_bridge_impart(attended_bridge, peer, NULL, NULL, 0)) {
366                 ast_bridge_destroy(attended_bridge);
367                 ast_bridge_features_cleanup(&caller_features);
368                 ast_hangup(peer);
369                 ast_bridge_merge_inhibit(bridge, -1);
370                 ao2_ref(bridge, -1);
371                 ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
372                 ast_bridge_channel_write_unhold(bridge_channel);
373                 return 0;
374         }
375
376         /*
377          * For the caller we want to join the bridge in a blocking
378          * fashion so we don't spin around in this function doing
379          * nothing while waiting.
380          */
381         ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features, NULL, 0);
382
383 /*
384  * BUGBUG there is a small window where the channel does not point to the bridge_channel.
385  *
386  * This window is expected to go away when atxfer is redesigned
387  * to fully support existing functionality.  There will be one
388  * and only one ast_bridge_channel structure per channel.
389  */
390         /* Point the channel back to the original bridge and bridge_channel. */
391         ast_bridge_channel_lock(bridge_channel);
392         ast_channel_lock(bridge_channel->chan);
393         ast_channel_internal_bridge_channel_set(bridge_channel->chan, bridge_channel);
394         ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
395         ast_channel_unlock(bridge_channel->chan);
396         ast_bridge_channel_unlock(bridge_channel);
397
398         /* Wait for peer thread to exit bridge and die. */
399         if (!ast_autoservice_start(bridge_channel->chan)) {
400                 ast_bridge_depart(peer);
401                 ast_autoservice_stop(bridge_channel->chan);
402         } else {
403                 ast_bridge_depart(peer);
404         }
405
406         /* Now that all channels are out of it we can destroy the bridge and the feature structures */
407         ast_bridge_destroy(attended_bridge);
408         ast_bridge_features_cleanup(&caller_features);
409
410         xfer_failed = -1;
411         switch (transfer_code) {
412         case ATXFER_INCOMPLETE:
413                 /* Peer hungup */
414                 break;
415         case ATXFER_COMPLETE:
416                 /* The peer takes our place in the bridge. */
417                 ast_bridge_channel_write_unhold(bridge_channel);
418                 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
419                 xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, bridge_channel->chan, NULL, 1);
420                 break;
421         case ATXFER_THREEWAY:
422                 /*
423                  * Transferer wants to convert to a threeway call.
424                  *
425                  * Just impart the peer onto the bridge and have us return to it
426                  * as normal.
427                  */
428                 ast_bridge_channel_write_unhold(bridge_channel);
429                 xfer_failed = ast_bridge_impart(bridge_channel->bridge, peer, NULL, NULL, 1);
430                 break;
431         case ATXFER_ABORT:
432                 /* Transferer decided not to transfer the call after all. */
433                 break;
434         }
435         ast_bridge_merge_inhibit(bridge, -1);
436         ao2_ref(bridge, -1);
437         if (xfer_failed) {
438                 ast_hangup(peer);
439                 if (!ast_check_hangup_locked(bridge_channel->chan)) {
440                         ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
441                 }
442                 ast_bridge_channel_write_unhold(bridge_channel);
443         }
444
445         return 0;
446 }
447
448 /*! \brief Internal built in feature for hangup */
449 static int feature_hangup(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
450 {
451         /*
452          * This is very simple, we simply change the state on the
453          * bridge_channel to force the channel out of the bridge and the
454          * core takes care of the rest.
455          */
456         ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
457         return 0;
458 }
459
460 static int unload_module(void)
461 {
462         return 0;
463 }
464
465 static int load_module(void)
466 {
467         ast_bridge_features_register(AST_BRIDGE_BUILTIN_BLINDTRANSFER, feature_blind_transfer, NULL);
468         ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, feature_attended_transfer, NULL);
469         ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);
470
471         /* Bump up our reference count so we can't be unloaded */
472         ast_module_ref(ast_module_info->self);
473
474         return AST_MODULE_LOAD_SUCCESS;
475 }
476
477 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Built in bridging features");