2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief Routines implementing call features as call pickup, parking and transfer
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30 #include "asterisk/_private.h"
34 #include <sys/signal.h>
35 #include <netinet/in.h>
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/app.h"
45 #include "asterisk/say.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/config.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/adsi.h"
53 #include "asterisk/devicestate.h"
54 #include "asterisk/monitor.h"
55 #include "asterisk/audiohook.h"
56 #include "asterisk/global_datastores.h"
57 #include "asterisk/astobj2.h"
58 #include "asterisk/cel.h"
61 <application name="Bridge" language="en_US">
66 <parameter name="channel" required="true">
67 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
69 <parameter name="options">
72 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
75 <para>Allow the called party to hang up by sending the
76 <replaceable>*</replaceable> DTMF digit.</para>
79 <para>Allow the calling party to hang up by pressing the
80 <replaceable>*</replaceable> DTMF digit.</para>
83 <para>Allow the called party to enable parking of the call by sending
84 the DTMF sequence defined for call parking in features.conf.</para>
87 <para>Allow the calling party to enable parking of the call by sending
88 the DTMF sequence defined for call parking in features.conf.</para>
90 <option name="L(x[:y][:z])">
91 <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
92 when <replaceable>y</replaceable> ms are left. Repeat the warning every
93 <replaceable>z</replaceable> ms. The following special variables can be
94 used with this option:</para>
96 <variable name="LIMIT_PLAYAUDIO_CALLER">
97 <para>Play sounds to the caller. yes|no (default yes)</para>
99 <variable name="LIMIT_PLAYAUDIO_CALLEE">
100 <para>Play sounds to the callee. yes|no</para>
102 <variable name="LIMIT_TIMEOUT_FILE">
103 <para>File to play when time is up.</para>
105 <variable name="LIMIT_CONNECT_FILE">
106 <para>File to play when call begins.</para>
108 <variable name="LIMIT_WARNING_FILE">
109 <para>File to play as warning if <replaceable>y</replaceable> is
110 defined. The default is to say the time remaining.</para>
115 <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
118 <para>Allow the called party to transfer the calling party by sending the
119 DTMF sequence defined in features.conf.</para>
122 <para>Allow the calling party to transfer the called party by sending the
123 DTMF sequence defined in features.conf.</para>
126 <para>Allow the called party to enable recording of the call by sending
127 the DTMF sequence defined for one-touch recording in features.conf.</para>
130 <para>Allow the calling party to enable recording of the call by sending
131 the DTMF sequence defined for one-touch recording in features.conf.</para>
134 <para>Cause the called party to be hung up after the bridge, instead of being
135 restarted in the dialplan.</para>
141 <para>Allows the ability to bridge two channels via the dialplan.</para>
142 <para>This application sets the following channel variable upon completion:</para>
144 <variable name="BRIDGERESULT">
145 <para>The result of the bridge attempt as a text string.</para>
146 <value name="SUCCESS" />
147 <value name="FAILURE" />
148 <value name="LOOP" />
149 <value name="NONEXISTENT" />
150 <value name="INCOMPATIBLE" />
155 <application name="ParkedCall" language="en_US">
157 Answer a parked call.
160 <parameter name="exten" required="true" />
163 <para>Used to connect to a parked call. This application is always
164 registered internally and does not need to be explicitly added
165 into the dialplan, although you should include the <literal>parkedcalls</literal>
166 context. If no extension is provided, then the first available
167 parked call will be acquired.</para>
170 <ref type="application">Park</ref>
171 <ref type="application">ParkAndAnnounce</ref>
174 <application name="Park" language="en_US">
179 <parameter name="timeout">
180 <para>A custom parking timeout for this parked call.</para>
182 <parameter name="return_context">
183 <para>The context to return the call to after it times out.</para>
185 <parameter name="return_exten">
186 <para>The extension to return the call to after it times out.</para>
188 <parameter name="return_priority">
189 <para>The priority to return the call to after it times out.</para>
191 <parameter name="options">
192 <para>A list of options for this parked call.</para>
195 <para>Send ringing instead of MOH to the parked call.</para>
198 <para>Randomize the selection of a parking space.</para>
201 <para>Silence announcement of the parking space number.</para>
207 <para>Used to park yourself (typically in combination with a supervised
208 transfer to know the parking space). This application is always
209 registered internally and does not need to be explicitly added
210 into the dialplan, although you should include the <literal>parkedcalls</literal>
211 context (or the context specified in <filename>features.conf</filename>).</para>
212 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
213 parking context, Park() will park the call on that extension, unless
214 it already exists. In that case, execution will continue at next priority.</para>
215 <para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
216 in that parkinglot.</para>
217 <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
218 will be used as template for the newly created dynamic lot.</para>
219 <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
220 parking lot will use this context.</para>
221 <para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
222 will use those parking postitions.</para>
225 <ref type="application">ParkAndAnnounce</ref>
226 <ref type="application">ParkedCall</ref>
229 <manager name="ParkedCalls" language="en_US">
234 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
237 <para>List parked calls.</para>
240 <manager name="Park" language="en_US">
245 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
246 <parameter name="Channel" required="true">
247 <para>Channel name to park.</para>
249 <parameter name="Channel2" required="true">
250 <para>Channel to announce park info to (and return to if timeout).</para>
252 <parameter name="Timeout">
253 <para>Number of milliseconds to wait before callback.</para>
257 <para>Park a channel.</para>
260 <manager name="Bridge" language="en_US">
262 Bridge two channels already in the PBX.
265 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
266 <parameter name="Channel1" required="true">
267 <para>Channel to Bridge to Channel2.</para>
269 <parameter name="Channel2" required="true">
270 <para>Channel to Bridge to Channel1.</para>
272 <parameter name="Tone">
273 <para>Play courtesy tone to Channel 2.</para>
281 <para>Bridge together two channels already in the PBX.</para>
286 #define DEFAULT_PARK_TIME 45000
287 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
288 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000
289 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
290 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
291 #define DEFAULT_ATXFER_DROP_CALL 0
292 #define DEFAULT_ATXFER_LOOP_DELAY 10000
293 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
295 #define AST_MAX_WATCHERS 256
296 #define MAX_DIAL_FEATURE_OPTIONS 30
298 struct feature_group_exten {
299 AST_LIST_ENTRY(feature_group_exten) entry;
300 AST_DECLARE_STRING_FIELDS(
301 AST_STRING_FIELD(exten);
303 struct ast_call_feature *feature;
306 struct feature_group {
307 AST_LIST_ENTRY(feature_group) entry;
308 AST_DECLARE_STRING_FIELDS(
309 AST_STRING_FIELD(gname);
311 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
314 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
316 static char *parkedcall = "ParkedCall";
318 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
320 /*! \brief Description of one parked call, added to a list while active, then removed.
321 The list belongs to a parkinglot
324 struct ast_channel *chan; /*!< Parking channel */
325 struct timeval start; /*!< Time the parking started */
326 int parkingnum; /*!< Parking lot */
327 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
328 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
329 char exten[AST_MAX_EXTENSION];
331 int parkingtime; /*!< Maximum length in parking lot before return */
332 unsigned int notquiteyet:1;
333 unsigned int options_specified:1;
335 unsigned char moh_trys;
336 struct ast_parkinglot *parkinglot;
337 AST_LIST_ENTRY(parkeduser) list;
340 /*! \brief Structure for parking lots which are put in a container. */
341 struct ast_parkinglot {
342 char name[AST_MAX_CONTEXT];
343 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
344 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
345 int parking_start; /*!< First available extension for parking */
346 int parking_stop; /*!< Last available extension for parking */
349 int parkingtime; /*!< Default parking time */
350 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
351 int parkaddhints; /*!< Add parking hints automatically */
352 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
353 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
354 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
355 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
356 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
359 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
360 static struct ao2_container *parkinglots;
362 struct ast_parkinglot *default_parkinglot;
363 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
365 static char courtesytone[256]; /*!< Courtesy tone */
366 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
367 static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
368 static char xfersound[256]; /*!< Call transfer sound */
369 static char xferfailsound[256]; /*!< Call transfer failure sound */
370 static char pickupsound[256]; /*!< Pickup sound */
371 static char pickupfailsound[256]; /*!< Pickup failure sound */
375 static int transferdigittimeout;
376 static int featuredigittimeout;
377 static int comebacktoorigin = 1;
379 static int atxfernoanswertimeout;
380 static unsigned int atxferdropcall;
381 static unsigned int atxferloopdelay;
382 static unsigned int atxfercallbackretries;
384 static char *registrar = "features"; /*!< Registrar for operations */
386 /* module and CLI command definitions */
387 static char *parkcall = PARK_APP_NAME;
389 static struct ast_app *monitor_app = NULL;
390 static int monitor_ok = 1;
392 static struct ast_app *mixmonitor_app = NULL;
393 static int mixmonitor_ok = 1;
395 static struct ast_app *stopmixmonitor_app = NULL;
396 static int stopmixmonitor_ok = 1;
398 static pthread_t parking_thread;
399 struct ast_dial_features {
400 struct ast_flags features_caller;
401 struct ast_flags features_callee;
405 static void *dial_features_duplicate(void *data)
407 struct ast_dial_features *df = data, *df_copy;
409 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
413 memcpy(df_copy, df, sizeof(*df));
418 static void dial_features_destroy(void *data)
420 struct ast_dial_features *df = data;
426 static const struct ast_datastore_info dial_features_info = {
427 .type = "dial-features",
428 .destroy = dial_features_destroy,
429 .duplicate = dial_features_duplicate,
432 /* Forward declarations */
433 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
434 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
435 static void parkinglot_destroy(void *obj);
436 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
437 struct ast_parkinglot *find_parkinglot(const char *name);
438 static struct ast_parkinglot *create_parkinglot(const char *name);
439 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
441 const char *ast_parking_ext(void)
446 const char *ast_pickup_ext(void)
451 struct ast_bridge_thread_obj
453 struct ast_bridge_config bconfig;
454 struct ast_channel *chan;
455 struct ast_channel *peer;
456 unsigned int return_to_pbx:1;
459 static int parkinglot_hash_cb(const void *obj, const int flags)
461 const struct ast_parkinglot *parkinglot = obj;
463 return ast_str_case_hash(parkinglot->name);
466 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
468 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
470 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
474 * \brief store context, extension and priority
475 * \param chan, context, ext, pri
477 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
479 ast_copy_string(chan->context, context, sizeof(chan->context));
480 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
481 chan->priority = pri;
485 * \brief Check goto on transfer
488 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
489 * When found make sure the types are compatible. Check if channel is valid
490 * if so start the new channel else hangup the call.
492 static void check_goto_on_transfer(struct ast_channel *chan)
494 struct ast_channel *xferchan;
495 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
496 char *x, *goto_on_transfer;
499 if (ast_strlen_zero(val))
502 goto_on_transfer = ast_strdupa(val);
504 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", chan->linkedid, 0, "%s", chan->name)))
507 for (x = goto_on_transfer; x && *x; x++) {
511 /* Make formats okay */
512 xferchan->readformat = chan->readformat;
513 xferchan->writeformat = chan->writeformat;
514 ast_channel_masquerade(xferchan, chan);
515 ast_parseable_goto(xferchan, goto_on_transfer);
516 xferchan->_state = AST_STATE_UP;
517 ast_clear_flag(xferchan, AST_FLAGS_ALL);
518 xferchan->_softhangup = 0;
519 if ((f = ast_read(xferchan))) {
522 ast_pbx_start(xferchan);
524 ast_hangup(xferchan);
528 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language);
531 * \brief bridge the call
532 * \param data thread bridge.
534 * Set Last Data for respective channels, reset cdr for channels
535 * bridge call, check if we're going back to dialplan
536 * if not hangup both legs of the call
538 static void *bridge_call_thread(void *data)
540 struct ast_bridge_thread_obj *tobj = data;
543 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
544 tobj->chan->data = tobj->peer->name;
545 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
546 tobj->peer->data = tobj->chan->name;
548 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
550 if (tobj->return_to_pbx) {
551 if (!ast_check_hangup(tobj->peer)) {
552 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
553 res = ast_pbx_start(tobj->peer);
554 if (res != AST_PBX_SUCCESS)
555 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
557 ast_hangup(tobj->peer);
558 if (!ast_check_hangup(tobj->chan)) {
559 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
560 res = ast_pbx_start(tobj->chan);
561 if (res != AST_PBX_SUCCESS)
562 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
564 ast_hangup(tobj->chan);
566 ast_hangup(tobj->chan);
567 ast_hangup(tobj->peer);
576 * \brief create thread for the parked call
579 * Create thread and attributes, call bridge_call_thread
581 static void bridge_call_thread_launch(void *data)
585 struct sched_param sched;
587 pthread_attr_init(&attr);
588 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
589 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
590 pthread_attr_destroy(&attr);
591 memset(&sched, 0, sizeof(sched));
592 pthread_setschedparam(thread, SCHED_RR, &sched);
596 * \brief Announce call parking by ADSI
598 * \param parkingexten .
599 * Create message to show for ADSI, display message.
600 * \retval 0 on success.
601 * \retval -1 on failure.
603 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
606 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
608 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
610 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
612 res = ast_adsi_load_session(chan, NULL, 0, 1);
615 return ast_adsi_print(chan, message, justify, 1);
618 /*! \brief Find parking lot name from channel */
619 static const char *findparkinglotname(struct ast_channel *chan)
621 const char *temp, *parkinglot = NULL;
623 /* Check if the channel has a parking lot */
624 if (!ast_strlen_zero(chan->parkinglot))
625 parkinglot = chan->parkinglot;
627 /* Channel variables override everything */
629 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
635 /*! \brief Notify metermaids that we've changed an extension */
636 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
638 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
639 exten, context, ast_devstate2str(state));
641 ast_devstate_changed(state, "park:%s@%s", exten, context);
644 /*! \brief metermaids callback from devicestate.c */
645 static enum ast_device_state metermaidstate(const char *data)
650 context = ast_strdupa(data);
652 exten = strsep(&context, "@");
654 return AST_DEVICE_INVALID;
656 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
658 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
659 return AST_DEVICE_NOT_INUSE;
661 return AST_DEVICE_INUSE;
664 /*! Options to pass to park_call_full */
665 enum ast_park_call_options {
666 /*! Provide ringing to the parked caller instead of music on hold */
667 AST_PARK_OPT_RINGING = (1 << 0),
668 /*! Randomly choose a parking spot for the caller instead of choosing
669 * the first one that is available. */
670 AST_PARK_OPT_RANDOMIZE = (1 << 1),
671 /*! Do not announce the parking number */
672 AST_PARK_OPT_SILENCE = (1 << 2),
675 struct ast_park_call_args {
676 /*! How long to wait in the parking lot before the call gets sent back
677 * to the specified return extension (or a best guess at where it came
678 * from if not explicitly specified). */
680 /*! An output parameter to store the parking space where the parked caller
683 const char *orig_chan_name;
684 const char *return_con;
685 const char *return_ext;
688 /*! Parked user that has already obtained a parking space */
689 struct parkeduser *pu;
692 static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
694 struct parkeduser *pu;
695 int i, parking_space = -1, parking_range;
696 const char *parkinglotname = NULL;
697 const char *parkingexten;
698 struct ast_parkinglot *parkinglot = NULL;
701 parkinglotname = findparkinglotname(peer);
703 if (parkinglotname) {
704 ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglotname);
705 parkinglot = find_parkinglot(parkinglotname);
709 /* Dynamically create parkinglot */
710 if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
711 const char *dyn_context, *dyn_range;
712 const char *parkinglotname_copy = NULL;
713 struct ast_parkinglot *parkinglot_copy = NULL;
714 int dyn_start, dyn_end;
716 ast_channel_lock(chan);
717 parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
718 dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
719 dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
720 ast_channel_unlock(chan);
722 if (!ast_strlen_zero(parkinglotname_copy)) {
723 parkinglot_copy = find_parkinglot(parkinglotname_copy);
725 if (!parkinglot_copy) {
726 parkinglot_copy = parkinglot_addref(default_parkinglot);
727 ast_debug(1, "Using default parking lot for copy\n");
729 if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
730 ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
732 if (!ast_strlen_zero(dyn_context)) {
733 ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
735 if (!ast_strlen_zero(dyn_range)) {
736 if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
737 ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
739 parkinglot->parking_start = dyn_start;
740 parkinglot->parking_stop = dyn_end;
743 ao2_link(parkinglots, parkinglot);
746 if (parkinglot_copy) {
747 /* unref our tempory copy */
748 parkinglot_unref(parkinglot_copy);
749 parkinglot_copy = NULL;
754 parkinglot = parkinglot_addref(default_parkinglot);
758 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
760 /* Allocate memory for parking data */
761 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
762 parkinglot_unref(parkinglot);
766 /* Lock parking list */
767 AST_LIST_LOCK(&parkinglot->parkings);
768 /* Check for channel variable PARKINGEXTEN */
769 ast_channel_lock(chan);
770 parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
771 ast_channel_unlock(chan);
772 if (!ast_strlen_zero(parkingexten)) {
773 /*!\note The API forces us to specify a numeric parking slot, even
774 * though the architecture would tend to support non-numeric extensions
775 * (as are possible with SIP, for example). Hence, we enforce that
776 * limitation here. If extout was not numeric, we could permit
777 * arbitrary non-numeric extensions.
779 if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space < 0) {
780 AST_LIST_UNLOCK(&parkinglot->parkings);
781 parkinglot_unref(parkinglot);
783 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
786 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
788 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
789 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
790 AST_LIST_UNLOCK(&parkinglot->parkings);
791 parkinglot_unref(parkinglot);
797 struct parkeduser *cur = NULL;
799 /* Select parking space within range */
800 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
802 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
803 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
805 start = parkinglot->parking_start;
808 for (i = start; 1; i++) {
809 if (i == parkinglot->parking_stop + 1) {
810 i = parkinglot->parking_start - 1;
814 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
815 if (cur->parkingnum == i) {
825 if (i == start - 1 && cur) {
826 ast_log(LOG_WARNING, "No more parking spaces\n");
828 AST_LIST_UNLOCK(&parkinglot->parkings);
829 parkinglot_unref(parkinglot);
832 /* Set pointer for next parking */
833 if (parkinglot->parkfindnext)
834 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
835 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
839 pu->parkingnum = parking_space;
840 pu->parkinglot = parkinglot_addref(parkinglot);
841 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
842 parkinglot_unref(parkinglot);
848 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
850 struct ast_context *con;
852 struct parkeduser *pu = args->pu;
853 const char *event_from;
856 pu = park_space_reserve(chan, peer, args);
858 return 1; /* Continue execution if possible */
860 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
862 chan->appl = "Parked Call";
867 /* Put the parked channel on hold if we have two different channels */
869 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
870 ast_indicate(pu->chan, AST_CONTROL_RINGING);
872 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
873 S_OR(pu->parkinglot->mohclass, NULL),
874 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
878 pu->start = ast_tvnow();
879 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
880 parkingnum_copy = pu->parkingnum;
882 *(args->extout) = pu->parkingnum;
885 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
886 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
887 and we need the callback name to be that of transferer. Since local,1/2 have the same
888 name we can be tricky and just grab the bridged channel from the other side of the local
890 if (!strcasecmp(peer->tech->type, "Local")) {
891 struct ast_channel *tmpchan, *base_peer;
892 char other_side[AST_CHANNEL_NAME];
894 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
895 if ((c = strrchr(other_side, ';'))) {
898 if ((tmpchan = ast_channel_get_by_name(other_side))) {
899 ast_channel_lock(tmpchan);
900 if ((base_peer = ast_bridged_channel(tmpchan))) {
901 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
903 ast_channel_unlock(tmpchan);
904 tmpchan = ast_channel_unref(tmpchan);
907 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
911 /* Remember what had been dialed, so that if the parking
912 expires, we try to come back to the same place */
914 pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
916 /* If extension has options specified, they override all other possibilities
917 such as the returntoorigin flag and transferred context. Information on
918 extension options is lost here, so we set a flag */
920 ast_copy_string(pu->context,
921 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
922 sizeof(pu->context));
923 ast_copy_string(pu->exten,
924 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
926 pu->priority = args->return_pri ? args->return_pri :
927 (chan->macropriority ? chan->macropriority : chan->priority);
929 /* If parking a channel directly, don't quiet yet get parking running on it.
930 * All parking lot entries are put into the parking lot with notquiteyet on. */
934 /* Wake up the (presumably select()ing) thread */
935 pthread_kill(parking_thread, SIGURG);
936 ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
938 ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
941 event_from = peer->name;
943 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
946 ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
952 "CallerIDNum: %s\r\n"
953 "CallerIDName: %s\r\n"
955 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
956 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
957 S_OR(pu->chan->cid.cid_num, "<unknown>"),
958 S_OR(pu->chan->cid.cid_name, "<unknown>"),
962 if (peer && adsipark && ast_adsi_available(peer)) {
963 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
964 ast_adsi_unload_session(peer);
967 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
968 if (!con) /* Still no context? Bad */
969 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
971 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
972 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
975 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
977 /* Only say number if it's a number and the channel hasn't been masqueraded away */
978 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
979 /* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */
980 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
981 /* Tell the peer channel the number of the parking space */
982 ast_say_digits(peer, pu->parkingnum, "", peer->language);
983 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
985 if (peer == chan) { /* pu->notquiteyet = 1 */
986 /* Wake up parking thread if we're really done */
987 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
988 S_OR(pu->parkinglot->mohclass, NULL),
989 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
991 pthread_kill(parking_thread, SIGURG);
996 /*! \brief Park a call */
997 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
999 struct ast_park_call_args args = {
1004 return park_call_full(chan, peer, &args);
1007 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, struct ast_park_call_args *args)
1009 struct ast_channel *chan;
1010 struct ast_frame *f;
1012 struct ast_park_call_args park_args = {0,};
1016 args->timeout = timeout;
1017 args->extout = extout;
1020 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
1022 ast_stream_and_wait(peer, "beeperr", "");
1023 return AST_FEATURE_RETURN_PARKFAILED;
1026 /* Make a new, fake channel that we'll use to masquerade in the real one */
1027 if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->linkedid, rchan->amaflags, "Parked/%s",rchan->name))) {
1028 ast_log(LOG_WARNING, "Unable to create parked channel\n");
1032 /* Make formats okay */
1033 chan->readformat = rchan->readformat;
1034 chan->writeformat = rchan->writeformat;
1035 ast_channel_masquerade(chan, rchan);
1037 /* Setup the extensions and such */
1038 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
1040 /* Setup the macro extension and such */
1041 ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
1042 ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
1043 chan->macropriority = rchan->macropriority;
1045 /* Make the masq execute */
1046 if ((f = ast_read(chan)))
1049 if (peer == rchan) {
1053 if (peer && (!play_announcement && args == &park_args)) {
1054 args->orig_chan_name = ast_strdupa(peer->name);
1057 park_status = park_call_full(chan, peer, args);
1058 if (park_status == 1) {
1059 /* would be nice to play "invalid parking extension" */
1067 /* Park call via masquraded channel */
1068 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1070 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
1073 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
1075 return masq_park_call(rchan, peer, 0, NULL, 1, args);
1078 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1080 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
1084 * \brief set caller and callee according to the direction
1085 * \param caller, callee, peer, chan, sense
1087 * Detect who triggered feature and set callee/caller variables accordingly
1089 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
1090 struct ast_channel *peer, struct ast_channel *chan, int sense)
1092 if (sense == FEATURE_SENSE_PEER) {
1102 * \brief support routing for one touch call parking
1103 * \param chan channel parking call
1104 * \param peer channel to be parked
1105 * \param config unsed
1106 * \param code unused
1107 * \param sense feature options
1110 * Setup channel, set return exten,priority to 's,1'
1111 * answer chan, sleep chan, park call
1113 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1115 struct ast_channel *parker;
1116 struct ast_channel *parkee;
1119 set_peers(&parker, &parkee, peer, chan, sense);
1120 /* we used to set chan's exten and priority to "s" and 1
1121 here, but this generates (in some cases) an invalid
1122 extension, and if "s" exists, could errantly
1123 cause execution of extensions you don't expect. It
1124 makes more sense to let nature take its course
1125 when chan finishes, and let the pbx do its thing
1126 and hang up when the park is over.
1128 if (chan->_state != AST_STATE_UP)
1129 res = ast_answer(chan);
1131 res = ast_safe_sleep(chan, 1000);
1133 if (!res) { /* one direction used to call park_call.... */
1134 res = masq_park_call_announce(parkee, parker, 0, NULL);
1135 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
1141 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1142 other channel during the message, so please don't use this for very long messages
1144 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1146 /* First play for caller, put other channel on auto service */
1147 if (ast_autoservice_start(callee_chan))
1149 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
1150 ast_log(LOG_WARNING, "Failed to play automon message!\n");
1151 ast_autoservice_stop(callee_chan);
1154 if (ast_autoservice_stop(callee_chan))
1156 /* Then play for callee, put other channel on auto service */
1157 if (ast_autoservice_start(caller_chan))
1159 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
1160 ast_log(LOG_WARNING, "Failed to play automon message !\n");
1161 ast_autoservice_stop(caller_chan);
1164 if (ast_autoservice_stop(caller_chan))
1170 * \brief Monitor a channel by DTMF
1171 * \param chan channel requesting monitor
1172 * \param peer channel to be monitored
1175 * \param sense feature options
1178 * Check monitor app enabled, setup channels, both caller/callee chans not null
1179 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
1180 * \retval AST_FEATURE_RETURN_SUCCESS on success.
1181 * \retval -1 on error.
1183 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1185 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1188 struct ast_channel *caller_chan, *callee_chan;
1189 const char *automon_message_start = NULL;
1190 const char *automon_message_stop = NULL;
1193 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1197 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1199 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1203 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1204 if (caller_chan) { /* Find extra messages */
1205 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1206 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1209 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1210 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1215 if (callee_chan->monitor) {
1216 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1217 if (!ast_strlen_zero(automon_message_stop)) {
1218 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1220 callee_chan->monitor->stop(callee_chan, 1);
1221 return AST_FEATURE_RETURN_SUCCESS;
1224 if (caller_chan && callee_chan) {
1225 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1226 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1227 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1230 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1233 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1235 if (!touch_monitor_prefix)
1236 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1238 if (touch_monitor) {
1239 len = strlen(touch_monitor) + 50;
1241 touch_filename = alloca(len);
1242 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1243 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1245 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1246 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1247 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1249 touch_filename = alloca(len);
1250 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1251 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1254 for(x = 0; x < strlen(args); x++) {
1259 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1261 pbx_exec(callee_chan, monitor_app, args);
1262 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1263 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1265 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1266 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1269 return AST_FEATURE_RETURN_SUCCESS;
1272 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1276 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1278 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1281 struct ast_channel *caller_chan, *callee_chan;
1282 const char *mixmonitor_spy_type = "MixMonitor";
1285 if (!mixmonitor_ok) {
1286 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1290 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1292 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1296 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1298 if (!ast_strlen_zero(courtesytone)) {
1299 if (ast_autoservice_start(callee_chan))
1301 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1302 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1303 ast_autoservice_stop(callee_chan);
1306 if (ast_autoservice_stop(callee_chan))
1310 ast_channel_lock(callee_chan);
1311 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1312 ast_channel_unlock(callee_chan);
1314 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1317 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1319 /* Make sure they are running */
1320 ast_channel_lock(callee_chan);
1321 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1322 ast_channel_unlock(callee_chan);
1324 if (!stopmixmonitor_ok) {
1325 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1328 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1329 stopmixmonitor_ok = 0;
1330 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1333 pbx_exec(callee_chan, stopmixmonitor_app, "");
1334 return AST_FEATURE_RETURN_SUCCESS;
1338 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1341 if (caller_chan && callee_chan) {
1342 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1343 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1346 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1349 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1351 if (touch_monitor) {
1352 len = strlen(touch_monitor) + 50;
1354 touch_filename = alloca(len);
1355 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1356 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1358 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1359 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1360 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1362 touch_filename = alloca(len);
1363 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1364 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1367 for( x = 0; x < strlen(args); x++) {
1372 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1374 pbx_exec(callee_chan, mixmonitor_app, args);
1375 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1376 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1377 return AST_FEATURE_RETURN_SUCCESS;
1381 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1386 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1388 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1389 return AST_FEATURE_RETURN_HANGUP;
1392 static int finishup(struct ast_channel *chan)
1394 ast_indicate(chan, AST_CONTROL_UNHOLD);
1396 return ast_autoservice_stop(chan);
1400 * \brief Find the context for the transfer
1404 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1405 * \return a context string
1407 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1409 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1410 if (ast_strlen_zero(s)) {
1411 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1413 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1414 s = transferer->macrocontext;
1416 if (ast_strlen_zero(s)) {
1417 s = transferer->context;
1423 * \brief Blind transfer user to another extension
1424 * \param chan channel to be transfered
1425 * \param peer channel initiated blind transfer
1429 * \param sense feature options
1431 * Place chan on hold, check if transferred to parkinglot extension,
1432 * otherwise check extension exists and transfer caller.
1433 * \retval AST_FEATURE_RETURN_SUCCESS.
1434 * \retval -1 on failure.
1436 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1438 struct ast_channel *transferer;
1439 struct ast_channel *transferee;
1440 const char *transferer_real_context;
1442 int res, parkstatus = 0;
1444 set_peers(&transferer, &transferee, peer, chan, sense);
1445 transferer_real_context = real_ctx(transferer, transferee);
1446 /* Start autoservice on chan while we talk to the originator */
1447 ast_autoservice_start(transferee);
1448 ast_indicate(transferee, AST_CONTROL_HOLD);
1450 memset(xferto, 0, sizeof(xferto));
1453 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1455 finishup(transferee);
1456 return -1; /* error ? */
1458 if (res > 0) /* If they've typed a digit already, handle it */
1459 xferto[0] = (char) res;
1461 ast_stopstream(transferer);
1462 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1463 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1464 finishup(transferee);
1467 if (!strcmp(xferto, ast_parking_ext())) {
1468 res = finishup(transferee);
1471 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1472 /* We return non-zero, but tell the PBX not to hang the channel when
1473 the thread dies -- We have to be careful now though. We are responsible for
1474 hanging up the channel, else it will never be hung up! */
1478 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1480 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1481 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1482 ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
1483 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1484 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1485 res=finishup(transferee);
1486 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1487 transferer->cdr=ast_cdr_alloc();
1488 if (transferer->cdr) {
1489 ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
1490 ast_cdr_start(transferer->cdr);
1493 if (transferer->cdr) {
1494 struct ast_cdr *swap = transferer->cdr;
1495 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1496 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1497 transferer->cdr->channel, transferer->cdr->dstchannel);
1498 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1499 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1500 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1501 /* swap cdrs-- it will save us some time & work */
1502 transferer->cdr = transferee->cdr;
1503 transferee->cdr = swap;
1505 if (!transferee->pbx) {
1506 /* Doh! Use our handy async_goto functions */
1507 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1508 ,transferee->name, xferto, transferer_real_context);
1509 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1510 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1512 /* Set the channel's new extension, since it exists, using transferer context */
1513 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1514 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1515 if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
1516 ast_channel_update_connected_line(transferee, &transferer->connected);
1518 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1520 check_goto_on_transfer(transferer);
1523 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1525 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1526 finishup(transferee);
1529 ast_stopstream(transferer);
1530 res = finishup(transferee);
1532 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1535 return AST_FEATURE_RETURN_SUCCESS;
1539 * \brief make channels compatible
1542 * \retval 0 on success.
1543 * \retval -1 on failure.
1545 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1547 if (ast_channel_make_compatible(c, newchan) < 0) {
1548 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1549 c->name, newchan->name);
1550 ast_hangup(newchan);
1557 * \brief Attended transfer
1558 * \param chan transfered user
1559 * \param peer person transfering call
1562 * \param sense feature options
1565 * Get extension to transfer to, if you cannot generate channel (or find extension)
1566 * return to host channel. After called channel answered wait for hangup of transferer,
1567 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1569 * \return -1 on failure
1571 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1573 struct ast_channel *transferer;
1574 struct ast_channel *transferee;
1575 const char *transferer_real_context;
1576 char xferto[256] = "";
1579 struct ast_channel *newchan;
1580 struct ast_channel *xferchan;
1581 struct ast_bridge_thread_obj *tobj;
1582 struct ast_bridge_config bconfig;
1583 struct ast_frame *f;
1585 struct ast_party_connected_line connected_line;
1586 struct ast_datastore *features_datastore;
1587 struct ast_dial_features *dialfeatures = NULL;
1589 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1590 set_peers(&transferer, &transferee, peer, chan, sense);
1591 transferer_real_context = real_ctx(transferer, transferee);
1592 /* Start autoservice on chan while we talk to the originator */
1593 ast_autoservice_start(transferee);
1594 ast_indicate(transferee, AST_CONTROL_HOLD);
1597 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1599 finishup(transferee);
1602 if (res > 0) /* If they've typed a digit already, handle it */
1603 xferto[0] = (char) res;
1605 /* this is specific of atxfer */
1606 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1607 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1608 finishup(transferee);
1612 ast_log(LOG_WARNING, "Did not read data.\n");
1613 finishup(transferee);
1614 if (ast_stream_and_wait(transferer, "beeperr", ""))
1616 return AST_FEATURE_RETURN_SUCCESS;
1619 /* valid extension, res == 1 */
1620 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1621 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1622 finishup(transferee);
1623 if (ast_stream_and_wait(transferer, "beeperr", ""))
1625 return AST_FEATURE_RETURN_SUCCESS;
1628 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1629 * the different variables for handling this properly with a builtin_atxfer */
1630 if (!strcmp(xferto, ast_parking_ext())) {
1631 finishup(transferee);
1632 return builtin_parkcall(chan, peer, config, code, sense, data);
1636 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1638 /* If we are performing an attended transfer and we have two channels involved then
1639 copy sound file information to play upon attended transfer completion */
1641 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1642 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1644 if (!ast_strlen_zero(chan1_attended_sound)) {
1645 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1647 if (!ast_strlen_zero(chan2_attended_sound)) {
1648 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1652 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1653 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1655 ast_party_connected_line_init(&connected_line);
1656 if (!ast_check_hangup(transferer)) {
1657 /* Transferer is up - old behaviour */
1658 ast_indicate(transferer, -1);
1660 finishup(transferee);
1661 /* any reason besides user requested cancel and busy triggers the failed sound */
1662 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1663 ast_stream_and_wait(transferer, xferfailsound, ""))
1665 if (ast_stream_and_wait(transferer, xfersound, ""))
1666 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1667 return AST_FEATURE_RETURN_SUCCESS;
1670 if (check_compat(transferer, newchan)) {
1671 /* we do mean transferee here, NOT transferer */
1672 finishup(transferee);
1675 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1676 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1677 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1678 /* We need to get the transferer's connected line information copied
1679 * at this point because he is likely to hang up during the bridge with
1680 * newchan. This info will be used down below before bridging the
1681 * transferee and newchan
1683 * As a result, we need to be sure to free this data before returning
1684 * or overwriting it.
1686 ast_channel_lock(transferer);
1687 ast_party_connected_line_copy(&connected_line, &transferer->connected);
1688 ast_channel_unlock(transferer);
1689 res = ast_bridge_call(transferer, newchan, &bconfig);
1690 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1691 ast_hangup(newchan);
1692 if (ast_stream_and_wait(transferer, xfersound, ""))
1693 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1694 finishup(transferee);
1695 transferer->_softhangup = 0;
1696 ast_party_connected_line_free(&connected_line);
1697 return AST_FEATURE_RETURN_SUCCESS;
1700 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
1702 if (check_compat(transferee, newchan)) {
1703 finishup(transferee);
1704 ast_party_connected_line_free(&connected_line);
1707 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1709 if ((ast_autoservice_stop(transferee) < 0)
1710 || (ast_waitfordigit(transferee, 100) < 0)
1711 || (ast_waitfordigit(newchan, 100) < 0)
1712 || ast_check_hangup(transferee)
1713 || ast_check_hangup(newchan)) {
1714 ast_hangup(newchan);
1715 ast_party_connected_line_free(&connected_line);
1718 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
1720 ast_hangup(newchan);
1721 ast_party_connected_line_free(&connected_line);
1724 /* Make formats okay */
1725 xferchan->visible_indication = transferer->visible_indication;
1726 xferchan->readformat = transferee->readformat;
1727 xferchan->writeformat = transferee->writeformat;
1728 ast_channel_masquerade(xferchan, transferee);
1729 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1730 xferchan->_state = AST_STATE_UP;
1731 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1732 xferchan->_softhangup = 0;
1733 if ((f = ast_read(xferchan)))
1735 newchan->_state = AST_STATE_UP;
1736 ast_clear_flag(newchan, AST_FLAGS_ALL);
1737 newchan->_softhangup = 0;
1738 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1739 ast_hangup(xferchan);
1740 ast_hangup(newchan);
1741 ast_party_connected_line_free(&connected_line);
1745 ast_channel_lock(newchan);
1746 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1747 dialfeatures = features_datastore->data;
1749 ast_channel_unlock(newchan);
1752 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1753 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1754 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1755 dialfeatures = NULL;
1758 ast_channel_lock(xferchan);
1759 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1760 dialfeatures = features_datastore->data;
1762 ast_channel_unlock(xferchan);
1765 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1768 tobj->chan = newchan;
1769 tobj->peer = xferchan;
1770 tobj->bconfig = *config;
1772 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1773 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1776 /* Due to a limitation regarding when callerID is set on a Local channel,
1777 * we use the transferer's connected line information here.
1780 /* xferchan is transferee, and newchan is the transfer target
1781 * So...in a transfer, who is the caller and who is the callee?
1783 * When the call is originally made, it is clear who is caller and callee.
1784 * When a transfer occurs, it is my humble opinion that the transferee becomes
1785 * the caller, and the transfer target is the callee.
1787 * The problem is that these macros were set with the intention of the original
1788 * caller and callee taking those roles. A transfer can totally mess things up,
1789 * to be technical. What sucks even more is that you can't effectively change
1790 * the macros in the dialplan during the call from the transferer to the transfer
1791 * target because the transferee is stuck with whatever role he originally had.
1793 * I think the answer here is just to make sure that it is well documented that
1794 * during a transfer, the transferee is the "caller" and the transfer target
1797 * This means that if party A calls party B, and party A transfers party B to
1798 * party C, then B has switched roles for the call. Now party B will have the
1799 * caller macro called on his channel instead of the callee macro.
1801 * Luckily, the method by which the bridge is launched here ensures that the
1802 * transferee is the "chan" on the bridge and the transfer target is the "peer,"
1803 * so my idea for the roles post-transfer does not require extensive code changes.
1805 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1806 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1807 ast_channel_update_connected_line(xferchan, &connected_line);
1809 ast_channel_lock(xferchan);
1810 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1811 ast_channel_unlock(xferchan);
1812 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1813 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1814 ast_channel_update_connected_line(newchan, &connected_line);
1816 ast_party_connected_line_free(&connected_line);
1818 if (ast_stream_and_wait(newchan, xfersound, ""))
1819 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1820 bridge_call_thread_launch(tobj);
1821 return -1; /* XXX meaning the channel is bridged ? */
1822 } else if (!ast_check_hangup(transferee)) {
1823 /* act as blind transfer */
1824 if (ast_autoservice_stop(transferee) < 0) {
1825 ast_hangup(newchan);
1830 unsigned int tries = 0;
1831 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1833 transferer_tech = strsep(&transferer_name, "/");
1834 transferer_name = strsep(&transferer_name, "-");
1836 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1837 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1838 if (ast_stream_and_wait(transferee, "beeperr", ""))
1840 return AST_FEATURE_RETURN_SUCCESS;
1843 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1844 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1845 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1846 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1847 /* Trying to transfer again */
1848 ast_autoservice_start(transferee);
1849 ast_indicate(transferee, AST_CONTROL_HOLD);
1851 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1852 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1853 if (ast_autoservice_stop(transferee) < 0) {
1855 ast_hangup(newchan);
1859 /* Transfer failed, sleeping */
1860 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1861 ast_safe_sleep(transferee, atxferloopdelay);
1862 ast_debug(1, "Trying to callback...\n");
1863 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1864 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1872 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
1874 /* newchan is up, we should prepare transferee and bridge them */
1875 if (check_compat(transferee, newchan)) {
1876 finishup(transferee);
1879 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1881 if ((ast_waitfordigit(transferee, 100) < 0)
1882 || (ast_waitfordigit(newchan, 100) < 0)
1883 || ast_check_hangup(transferee)
1884 || ast_check_hangup(newchan)) {
1885 ast_hangup(newchan);
1889 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
1891 ast_hangup(newchan);
1894 /* Make formats okay */
1895 xferchan->visible_indication = transferer->visible_indication;
1896 xferchan->readformat = transferee->readformat;
1897 xferchan->writeformat = transferee->writeformat;
1898 ast_channel_masquerade(xferchan, transferee);
1899 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1900 xferchan->_state = AST_STATE_UP;
1901 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1902 xferchan->_softhangup = 0;
1903 if ((f = ast_read(xferchan)))
1905 newchan->_state = AST_STATE_UP;
1906 ast_clear_flag(newchan, AST_FLAGS_ALL);
1907 newchan->_softhangup = 0;
1908 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1909 ast_hangup(xferchan);
1910 ast_hangup(newchan);
1913 tobj->chan = newchan;
1914 tobj->peer = xferchan;
1915 tobj->bconfig = *config;
1917 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1918 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1921 ast_channel_lock(newchan);
1922 ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
1923 ast_channel_unlock(newchan);
1924 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1925 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1926 ast_channel_update_connected_line(xferchan, &connected_line);
1928 ast_channel_lock(xferchan);
1929 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1930 ast_channel_unlock(xferchan);
1931 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1932 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1933 ast_channel_update_connected_line(newchan, &connected_line);
1936 ast_party_connected_line_free(&connected_line);
1938 if (ast_stream_and_wait(newchan, xfersound, ""))
1939 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1940 bridge_call_thread_launch(tobj);
1941 return -1; /* XXX meaning the channel is bridged ? */
1943 /* Transferee hung up */
1944 finishup(transferee);
1949 /* add atxfer and automon as undefined so you can only use em if you configure them */
1950 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1952 AST_RWLOCK_DEFINE_STATIC(features_lock);
1954 static struct ast_call_feature builtin_features[] = {
1955 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1956 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1957 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1958 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1959 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1960 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1964 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
1966 /*! \brief register new feature into feature_list*/
1967 void ast_register_feature(struct ast_call_feature *feature)
1970 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1974 AST_RWLIST_WRLOCK(&feature_list);
1975 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1976 AST_RWLIST_UNLOCK(&feature_list);
1978 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1982 * \brief Add new feature group
1983 * \param fgname feature group name.
1985 * Add new feature group to the feature group list insert at head of list.
1986 * \note This function MUST be called while feature_groups is locked.
1988 static struct feature_group* register_group(const char *fgname)
1990 struct feature_group *fg;
1993 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1997 if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128)))
2000 ast_string_field_set(fg, gname, fgname);
2002 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
2004 ast_verb(2, "Registered group '%s'\n", fg->gname);
2010 * \brief Add feature to group
2011 * \param fg feature group
2013 * \param feature feature to add.
2015 * Check fg and feature specified, add feature to list
2016 * \note This function MUST be called while feature_groups is locked.
2018 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
2020 struct feature_group_exten *fge;
2023 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
2028 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
2032 if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128)))
2035 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
2037 fge->feature = feature;
2039 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
2041 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
2042 feature->sname, fg->gname, exten);
2045 void ast_unregister_feature(struct ast_call_feature *feature)
2051 AST_RWLIST_WRLOCK(&feature_list);
2052 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
2053 AST_RWLIST_UNLOCK(&feature_list);
2058 /*! \brief Remove all features in the list */
2059 static void ast_unregister_features(void)
2061 struct ast_call_feature *feature;
2063 AST_RWLIST_WRLOCK(&feature_list);
2064 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
2067 AST_RWLIST_UNLOCK(&feature_list);
2070 /*! \brief find a call feature by name */
2071 static struct ast_call_feature *find_dynamic_feature(const char *name)
2073 struct ast_call_feature *tmp;
2075 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
2076 if (!strcasecmp(tmp->sname, name)) {
2084 /*! \brief Remove all feature groups in the list */
2085 static void ast_unregister_groups(void)
2087 struct feature_group *fg;
2088 struct feature_group_exten *fge;
2090 AST_RWLIST_WRLOCK(&feature_groups);
2091 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
2092 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
2093 ast_string_field_free_memory(fge);
2097 ast_string_field_free_memory(fg);
2100 AST_RWLIST_UNLOCK(&feature_groups);
2104 * \brief Find a group by name
2105 * \param name feature name
2106 * \retval feature group on success.
2107 * \retval NULL on failure.
2109 static struct feature_group *find_group(const char *name) {
2110 struct feature_group *fg = NULL;
2112 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
2113 if (!strcasecmp(fg->gname, name))
2120 void ast_rdlock_call_features(void)
2122 ast_rwlock_rdlock(&features_lock);
2125 void ast_unlock_call_features(void)
2127 ast_rwlock_unlock(&features_lock);
2130 struct ast_call_feature *ast_find_call_feature(const char *name)
2133 for (x = 0; x < FEATURES_COUNT; x++) {
2134 if (!strcasecmp(name, builtin_features[x].sname))
2135 return &builtin_features[x];
2141 * \brief exec an app by feature
2142 * \param chan,peer,config,code,sense,data
2144 * Find a feature, determine which channel activated
2145 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
2147 * \retval -2 when an application cannot be found.
2149 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2151 struct ast_app *app;
2152 struct ast_call_feature *feature = data;
2153 struct ast_channel *work, *idle;
2156 if (!feature) { /* shouldn't ever happen! */
2157 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
2161 if (sense == FEATURE_SENSE_CHAN) {
2162 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2163 return AST_FEATURE_RETURN_KEEPTRYING;
2164 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2172 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2173 return AST_FEATURE_RETURN_KEEPTRYING;
2174 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2183 if (!(app = pbx_findapp(feature->app))) {
2184 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
2188 ast_autoservice_start(idle);
2191 pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", idle->name);
2192 pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", work->name);
2193 pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
2194 pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
2197 if (!ast_strlen_zero(feature->moh_class))
2198 ast_moh_start(idle, feature->moh_class, NULL);
2200 res = pbx_exec(work, app, feature->app_args);
2202 if (!ast_strlen_zero(feature->moh_class))
2205 ast_autoservice_stop(idle);
2208 return AST_FEATURE_RETURN_SUCCESSBREAK;
2210 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
2213 static void unmap_features(void)
2217 ast_rwlock_wrlock(&features_lock);
2218 for (x = 0; x < FEATURES_COUNT; x++)
2219 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
2220 ast_rwlock_unlock(&features_lock);
2223 static int remap_feature(const char *name, const char *value)
2227 ast_rwlock_wrlock(&features_lock);
2228 for (x = 0; x < FEATURES_COUNT; x++) {
2229 if (strcasecmp(builtin_features[x].sname, name))
2232 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
2236 ast_rwlock_unlock(&features_lock);
2242 * \brief Helper function for feature_interpret and ast_feature_detect
2243 * \param chan,peer,config,code,sense,dynamic_features char buf,feature flags,operation,feature
2245 * Lock features list, browse for code, unlock list
2246 * If a feature is found and the operation variable is set, that feature's
2247 * operation is executed. The first feature found is copied to the feature parameter.
2248 * \retval res on success.
2249 * \retval -1 on failure.
2251 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
2252 struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
2253 struct ast_flags *features, int operation, struct ast_call_feature *feature)
2256 struct feature_group *fg = NULL;
2257 struct feature_group_exten *fge;
2258 struct ast_call_feature *tmpfeature;
2260 int res = AST_FEATURE_RETURN_PASSDIGITS;
2261 int feature_detected = 0;
2263 if (!(peer && chan && config) && operation) {
2264 return -1; /* can not run feature operation */
2267 ast_rwlock_rdlock(&features_lock);
2268 for (x = 0; x < FEATURES_COUNT; x++) {
2269 if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
2270 !ast_strlen_zero(builtin_features[x].exten)) {
2271 /* Feature is up for consideration */
2272 if (!strcmp(builtin_features[x].exten, code)) {
2273 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2275 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2277 memcpy(feature, &builtin_features[x], sizeof(feature));
2278 feature_detected = 1;
2280 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2281 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2282 res = AST_FEATURE_RETURN_STOREDIGITS;
2286 ast_rwlock_unlock(&features_lock);
2288 if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
2292 tmp = dynamic_features_buf;
2294 while ((tok = strsep(&tmp, "#"))) {
2295 AST_RWLIST_RDLOCK(&feature_groups);
2297 fg = find_group(tok);
2300 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2301 if (strcasecmp(fge->exten, code))
2304 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2306 memcpy(feature, fge->feature, sizeof(feature));
2307 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2308 AST_RWLIST_UNLOCK(&feature_groups);
2311 res = AST_FEATURE_RETURN_PASSDIGITS;
2317 AST_RWLIST_UNLOCK(&feature_groups);
2319 AST_RWLIST_RDLOCK(&feature_list);
2321 if (!(tmpfeature = find_dynamic_feature(tok))) {
2322 AST_RWLIST_UNLOCK(&feature_list);
2326 /* Feature is up for consideration */
2327 if (!strcmp(tmpfeature->exten, code)) {
2328 ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
2330 res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
2332 memcpy(feature, tmpfeature, sizeof(feature));
2333 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2334 AST_RWLIST_UNLOCK(&feature_list);
2337 res = AST_FEATURE_RETURN_PASSDIGITS;
2338 } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
2339 res = AST_FEATURE_RETURN_STOREDIGITS;
2341 AST_RWLIST_UNLOCK(&feature_list);
2348 * \brief Check the dynamic features
2349 * \param chan,peer,config,code,sense
2351 * \retval res on success.
2352 * \retval -1 on failure.
2355 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
2357 char dynamic_features_buf[128];
2358 const char *peer_dynamic_features, *chan_dynamic_features;
2359 struct ast_flags features;
2360 struct ast_call_feature feature;
2361 if (sense == FEATURE_SENSE_CHAN) {
2362 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
2365 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
2368 ast_channel_lock(peer);
2369 peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
2370 ast_channel_unlock(peer);
2372 ast_channel_lock(chan);
2373 chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
2374 ast_channel_unlock(chan);
2376 snprintf(dynamic_features_buf, sizeof(dynamic_features_buf), "%s%s%s", S_OR(chan_dynamic_features, ""), chan_dynamic_features && peer_dynamic_features ? "#" : "", S_OR(peer_dynamic_features,""));
2378 ast_debug(3, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features_buf);
2380 return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, 1, &feature);
2384 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
2386 return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
2389 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2393 ast_clear_flag(config, AST_FLAGS_ALL);
2395 ast_rwlock_rdlock(&features_lock);
2396 for (x = 0; x < FEATURES_COUNT; x++) {
2397 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2400 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2401 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2403 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2404 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2406 ast_rwlock_unlock(&features_lock);
2408 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2409 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2411 if (dynamic_features) {
2412 char *tmp = ast_strdupa(dynamic_features);
2414 struct ast_call_feature *feature;
2416 /* while we have a feature */
2417 while ((tok = strsep(&tmp, "#"))) {
2418 AST_RWLIST_RDLOCK(&feature_list);
2419 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2420 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2421 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2422 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2423 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2425 AST_RWLIST_UNLOCK(&feature_list);
2432 * \brief Get feature and dial
2433 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
2435 * Request channel, set channel variables, initiate call,check if they want to disconnect
2436 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2437 * check for answer break loop, set cdr return channel.
2439 * \todo XXX Check - this is very similar to the code in channel.c
2440 * \return always a channel
2442 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language)
2447 struct ast_channel *chan;
2448 struct ast_channel *monitor_chans[2];
2449 struct ast_channel *active_channel;
2450 int res = 0, ready = 0;
2451 struct timeval started;
2453 char *disconnect_code = NULL, *dialed_code = NULL;
2455 if (!(chan = ast_request(type, format, caller, data, &cause))) {
2456 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2458 case AST_CAUSE_BUSY:
2459 state = AST_CONTROL_BUSY;
2461 case AST_CAUSE_CONGESTION:
2462 state = AST_CONTROL_CONGESTION;
2468 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2469 ast_string_field_set(chan, language, language);
2470 ast_channel_inherit_variables(caller, chan);
2471 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2473 ast_channel_lock(chan);
2474 ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
2475 ast_channel_unlock(chan);
2477 if (ast_call(chan, data, timeout)) {
2478 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2482 ast_indicate(caller, AST_CONTROL_RINGING);
2483 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2484 ast_rwlock_rdlock(&features_lock);
2485 for (x = 0; x < FEATURES_COUNT; x++) {
2486 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2489 disconnect_code = builtin_features[x].exten;
2490 len = strlen(disconnect_code) + 1;
2491 dialed_code = alloca(len);
2492 memset(dialed_code, 0, len);
2495 ast_rwlock_unlock(&features_lock);
2497 started = ast_tvnow();
2500 ast_poll_channel_add(caller, chan);
2502 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2503 struct ast_frame *f = NULL;
2505 monitor_chans[0] = caller;
2506 monitor_chans[1] = chan;
2507 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2509 /* see if the timeout has been violated */
2510 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2511 state = AST_CONTROL_UNHOLD;
2512 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2513 break; /*doh! timeout*/
2516 if (!active_channel)
2519 if (chan && (chan == active_channel)){
2520 if (!ast_strlen_zero(chan->call_forward)) {
2521 if (!(chan = ast_call_forward(caller, chan, &to, format, NULL, outstate))) {
2527 if (f == NULL) { /*doh! where'd he go?*/
2528 state = AST_CONTROL_HANGUP;
2533 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2534 if (f->subclass.integer == AST_CONTROL_RINGING) {
2535 state = f->subclass.integer;
2536 ast_verb(3, "%s is ringing\n", chan->name);
2537 ast_indicate(caller, AST_CONTROL_RINGING);
2538 } else if ((f->subclass.integer == AST_CONTROL_BUSY) || (f->subclass.integer == AST_CONTROL_CONGESTION)) {
2539 state = f->subclass.integer;
2540 ast_verb(3, "%s is busy\n", chan->name);
2541 ast_indicate(caller, AST_CONTROL_BUSY);
2545 } else if (f->subclass.integer == AST_CONTROL_ANSWER) {
2546 /* This is what we are hoping for */
2547 state = f->subclass.integer;
2552 } else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
2553 if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) {
2554 ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
2556 } else if (f->subclass.integer != -1 && f->subclass.integer != AST_CONTROL_PROGRESS) {
2557 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass.integer);
2559 /* else who cares */
2560 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2561 ast_write(caller, f);
2564 } else if (caller && (active_channel == caller)) {
2565 f = ast_read(caller);
2566 if (f == NULL) { /*doh! where'd he go?*/
2567 if (!igncallerstate) {
2568 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2569 /* make this a blind transfer */
2573 state = AST_CONTROL_HANGUP;
2579 if (f->frametype == AST_FRAME_DTMF) {
2580 dialed_code[x++] = f->subclass.integer;
2581 dialed_code[x] = '\0';
2582 if (strlen(dialed_code) == len) {
2584 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2586 dialed_code[x] = '\0';
2588 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2589 /* Caller Canceled the call */
2590 state = AST_CONTROL_UNHOLD;
2595 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2604 ast_poll_channel_del(caller, chan);
2607 ast_indicate(caller, -1);
2608 if (chan && ready) {
2609 if (chan->_state == AST_STATE_UP)
2610 state = AST_CONTROL_ANSWER;
2626 void ast_channel_log(char *title, struct ast_channel *chan);
2628 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
2630 ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long)chan);
2631 ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
2632 chan->name, chan->appl, chan->data, chan->context, chan->exten, chan->priority);
2633 ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
2634 chan->accountcode, chan->dialcontext, chan->amaflags, chan->macrocontext, chan->macroexten, chan->macropriority);
2635 ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; _bridge: %p; uniqueID: %s; linkedID:%s\n",
2636 chan->masq, chan->masqr,
2637 chan->_bridge, chan->uniqueid, chan->linkedid);
2639 ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
2640 chan->masqr->name, chan->masqr->cdr);
2642 ast_log(LOG_NOTICE, "CHAN: Bridged to %s\n", chan->_bridge->name);
2644 ast_log(LOG_NOTICE, "===== done ====\n");
2648 * \brief return the first unlocked cdr in a possible chain
2650 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2652 struct ast_cdr *cdr_orig = cdr;
2654 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2658 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2661 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2663 const char *feature;
2665 if (ast_strlen_zero(features)) {
2669 for (feature = features; *feature; feature++) {
2673 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2677 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2681 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2685 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2688 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2693 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2695 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2696 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2698 ast_channel_lock(caller);
2699 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2700 ast_channel_unlock(caller);
2701 if (!ds_caller_features) {
2702 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2703 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2706 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2707 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2708 ast_datastore_free(ds_caller_features);
2711 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2712 caller_features->is_caller = 1;
2713 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2714 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2715 ds_caller_features->data = caller_features;
2716 ast_channel_lock(caller);
2717 ast_channel_datastore_add(caller, ds_caller_features);
2718 ast_channel_unlock(caller);
2720 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2721 * flags over from the atxfer to the caller */
2725 ast_channel_lock(callee);
2726 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2727 ast_channel_unlock(callee);
2728 if (!ds_callee_features) {
2729 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2730 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2733 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2734 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2735 ast_datastore_free(ds_callee_features);
2738 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2739 callee_features->is_caller = 0;
2740 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2741 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2742 ds_callee_features->data = callee_features;
2743 ast_channel_lock(callee);
2744 ast_channel_datastore_add(callee, ds_callee_features);
2745 ast_channel_unlock(callee);
2752 * \brief bridge the call and set CDR
2753 * \param chan,peer,config
2755 * Set start time, check for two channels,check if monitor on
2756 * check for feature activation, create new CDR
2757 * \retval res on success.
2758 * \retval -1 on failure to bridge.
2760 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2762 /* Copy voice back and forth between the two channels. Give the peer
2763 the ability to transfer calls with '#<extension' syntax. */
2764 struct ast_frame *f;
2765 struct ast_channel *who;
2766 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2767 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2768 char orig_channame[AST_MAX_EXTENSION];
2769 char orig_peername[AST_MAX_EXTENSION];
2775 struct ast_option_header *aoh;
2776 struct ast_cdr *bridge_cdr = NULL;
2777 struct ast_cdr *orig_peer_cdr = NULL;
2778 struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2779 struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2780 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2781 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2784 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2785 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2787 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2790 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
2791 add_features_datastores(chan, peer, config);
2793 /* This is an interesting case. One example is if a ringing channel gets redirected to
2794 * an extension that picks up a parked call. This will make sure that the call taken
2795 * out of parking gets told that the channel it just got bridged to is still ringing. */
2796 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
2797 ast_indicate(peer, AST_CONTROL_RINGING);
2801 const char *monitor_exec;
2802 struct ast_channel *src = NULL;
2804 if (!(monitor_app = pbx_findapp("Monitor")))
2807 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
2809 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2811 if (monitor_app && src) {
2812 char *tmp = ast_strdupa(monitor_exec);
2813 pbx_exec(src, monitor_app, tmp);
2817 set_config_flags(chan, peer, config);
2819 /* Answer if need be */
2820 if (chan->_state != AST_STATE_UP) {
2821 if (ast_raw_answer(chan, 1)) {
2827 /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
2828 ast_channel_log("Pre-bridge CHAN Channel info", chan);
2829 ast_channel_log("Pre-bridge PEER Channel info", peer);
2831 /* two channels are being marked as linked here */
2832 ast_channel_set_linkgroup(chan,peer);
2834 /* copy the userfield from the B-leg to A-leg if applicable */
2835 if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
2837 if (!ast_strlen_zero(chan->cdr->userfield)) {
2838 snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
2839 ast_cdr_appenduserfield(chan, tmp);
2841 ast_cdr_setuserfield(chan, peer->cdr->userfield);
2842 /* free the peer's cdr without ast_cdr_free complaining */
2843 ast_free(peer->cdr);
2846 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
2847 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
2848 orig_peer_cdr = peer_cdr;
2850 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2853 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
2854 ast_cdr_update(chan);
2855 bridge_cdr = ast_cdr_dup_unique_swap(chan_cdr);
2856 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
2857 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
2858 if (peer_cdr && !ast_strlen_zero(peer_cdr->userfield)) {
2859 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2863 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
2864 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
2865 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
2866 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
2867 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
2868 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
2869 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
2870 ast_cdr_setcid(bridge_cdr, chan);
2871 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
2872 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
2873 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
2874 /* Destination information */
2875 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
2876 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
2878 bridge_cdr->start = peer_cdr->start;
2879 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2881 ast_cdr_start(bridge_cdr);
2884 ast_debug(4,"bridge answer set, chan answer set\n");
2885 /* peer_cdr->answer will be set when a macro runs on the peer;
2886 in that case, the bridge answer will be delayed while the
2887 macro plays on the peer channel. The peer answered the call
2888 before the macro started playing. To the phone system,
2889 this is billable time for the call, even tho the caller
2890 hears nothing but ringing while the macro does its thing. */
2892 /* Another case where the peer cdr's time will be set, is when
2893 A self-parks by pickup up phone and dialing 700, then B
2894 picks up A by dialing its parking slot; there may be more
2895 practical paths that get the same result, tho... in which
2896 case you get the previous answer time from the Park... which
2897 is before the bridge's start time, so I added in the
2898 tvcmp check to the if below */
2900 if (peer_cdr && !ast_tvzero(peer_cdr->answer) && ast_tvcmp(peer_cdr->answer, bridge_cdr->start) >= 0) {
2901 bridge_cdr->answer = peer_cdr->answer;
2902 bridge_cdr->disposition = peer_cdr->disposition;
2904 chan_cdr->answer = peer_cdr->answer;
2905 chan_cdr->disposition = peer_cdr->disposition;
2908 ast_cdr_answer(bridge_cdr);
2910 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
2913 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
2915 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
2918 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
2922 ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, NULL);
2924 struct ast_channel *other; /* used later */
2926 res = ast_channel_bridge(chan, peer, config, &f, &who);
2928 /* When frame is not set, we are probably involved in a situation
2929 where we've timed out.
2930 When frame is set, we'll come this code twice; once for DTMF_BEGIN
2931 and also for DTMF_END. If we flow into the following 'if' for both, then
2932 our wait times are cut in half, as both will subtract from the
2933 feature_timer. Not good!
2935 if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
2936 /* Update feature timer for next pass */
2937 diff = ast_tvdiff_ms(ast_tvnow(), config->feature_start_time);
2938 if (res == AST_BRIDGE_RETRY) {
2939 /* The feature fully timed out but has not been updated. Skip
2940 * the potential round error from the diff calculation and
2941 * explicitly set to expired. */
2942 config->feature_timer = -1;
2944 config->feature_timer -= diff;
2948 if (config->feature_timer <= 0) {
2949 /* Not *really* out of time, just out of time for
2950 digits to come in for features. */
2951 ast_debug(1, "Timed out for feature!\n");
2952 if (!ast_strlen_zero(peer_featurecode)) {
2953 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
2954 memset(peer_featurecode, 0, sizeof(peer_featurecode));
2956 if (!ast_strlen_zero(chan_featurecode)) {
2957 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
2958 memset(chan_featurecode, 0, sizeof(chan_featurecode));
2962 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2964 /* No more digits expected - reset the timer */
2965 config->feature_timer = 0;
2967 hadfeatures = hasfeatures;
2968 /* Continue as we were */
2971 /* The bridge returned without a frame and there is a feature in progress.
2972 * However, we don't think the feature has quite yet timed out, so just
2973 * go back into the bridge. */
2977 if (config->feature_timer <=0) {
2978 /* We ran out of time */
2979 config->feature_timer = 0;
2989 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_