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"
35 #include <sys/signal.h>
36 #include <netinet/in.h>
38 #include "asterisk/lock.h"
39 #include "asterisk/file.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/causes.h"
43 #include "asterisk/module.h"
44 #include "asterisk/translate.h"
45 #include "asterisk/app.h"
46 #include "asterisk/say.h"
47 #include "asterisk/features.h"
48 #include "asterisk/musiconhold.h"
49 #include "asterisk/config.h"
50 #include "asterisk/cli.h"
51 #include "asterisk/manager.h"
52 #include "asterisk/utils.h"
53 #include "asterisk/adsi.h"
54 #include "asterisk/devicestate.h"
55 #include "asterisk/monitor.h"
56 #include "asterisk/audiohook.h"
57 #include "asterisk/global_datastores.h"
58 #include "asterisk/astobj2.h"
59 #include "asterisk/cel.h"
60 #include "asterisk/test.h"
63 <application name="Bridge" language="en_US">
68 <parameter name="channel" required="true">
69 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
71 <parameter name="options">
74 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
77 <para>Allow the called party to hang up by sending the
78 <replaceable>*</replaceable> DTMF digit.</para>
81 <para>Allow the calling party to hang up by pressing the
82 <replaceable>*</replaceable> DTMF digit.</para>
85 <para>Allow the called party to enable parking of the call by sending
86 the DTMF sequence defined for call parking in features.conf.</para>
89 <para>Allow the calling party to enable parking of the call by sending
90 the DTMF sequence defined for call parking in features.conf.</para>
92 <option name="L(x[:y][:z])">
93 <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
94 when <replaceable>y</replaceable> ms are left. Repeat the warning every
95 <replaceable>z</replaceable> ms. The following special variables can be
96 used with this option:</para>
98 <variable name="LIMIT_PLAYAUDIO_CALLER">
99 <para>Play sounds to the caller. yes|no (default yes)</para>
101 <variable name="LIMIT_PLAYAUDIO_CALLEE">
102 <para>Play sounds to the callee. yes|no</para>
104 <variable name="LIMIT_TIMEOUT_FILE">
105 <para>File to play when time is up.</para>
107 <variable name="LIMIT_CONNECT_FILE">
108 <para>File to play when call begins.</para>
110 <variable name="LIMIT_WARNING_FILE">
111 <para>File to play as warning if <replaceable>y</replaceable> is
112 defined. The default is to say the time remaining.</para>
117 <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
120 <para>Allow the called party to transfer the calling party by sending the
121 DTMF sequence defined in features.conf.</para>
124 <para>Allow the calling party to transfer the called party by sending the
125 DTMF sequence defined in features.conf.</para>
128 <para>Allow the called party to enable recording of the call by sending
129 the DTMF sequence defined for one-touch recording in features.conf.</para>
132 <para>Allow the calling party to enable recording of the call by sending
133 the DTMF sequence defined for one-touch recording in features.conf.</para>
136 <para>Cause the called party to be hung up after the bridge, instead of being
137 restarted in the dialplan.</para>
143 <para>Allows the ability to bridge two channels via the dialplan.</para>
144 <para>This application sets the following channel variable upon completion:</para>
146 <variable name="BRIDGERESULT">
147 <para>The result of the bridge attempt as a text string.</para>
148 <value name="SUCCESS" />
149 <value name="FAILURE" />
150 <value name="LOOP" />
151 <value name="NONEXISTENT" />
152 <value name="INCOMPATIBLE" />
157 <application name="ParkedCall" language="en_US">
159 Answer a parked call.
162 <parameter name="exten" required="true" />
165 <para>Used to connect to a parked call. This application is always
166 registered internally and does not need to be explicitly added
167 into the dialplan, although you should include the <literal>parkedcalls</literal>
168 context. If no extension is provided, then the first available
169 parked call will be acquired.</para>
172 <ref type="application">Park</ref>
173 <ref type="application">ParkAndAnnounce</ref>
176 <application name="Park" language="en_US">
181 <parameter name="timeout">
182 <para>A custom parking timeout for this parked call.</para>
184 <parameter name="return_context">
185 <para>The context to return the call to after it times out.</para>
187 <parameter name="return_exten">
188 <para>The extension to return the call to after it times out.</para>
190 <parameter name="return_priority">
191 <para>The priority to return the call to after it times out.</para>
193 <parameter name="options">
194 <para>A list of options for this parked call.</para>
197 <para>Send ringing instead of MOH to the parked call.</para>
200 <para>Randomize the selection of a parking space.</para>
203 <para>Silence announcement of the parking space number.</para>
209 <para>Used to park yourself (typically in combination with a supervised
210 transfer to know the parking space). This application is always
211 registered internally and does not need to be explicitly added
212 into the dialplan, although you should include the <literal>parkedcalls</literal>
213 context (or the context specified in <filename>features.conf</filename>).</para>
214 <para>If you set the <variable>PARKINGLOT</variable> variable, the call will be parked
215 in the specifed parking context. Note setting this variable overrides the <variable>
216 PARKINGLOT</variable> set by the <literal>CHANNEL</literal> function.</para>
217 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
218 parking context, Park() will park the call on that extension, unless
219 it already exists. In that case, execution will continue at next priority.</para>
220 <para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
221 in that parkinglot.</para>
222 <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
223 will be used as template for the newly created dynamic lot.</para>
224 <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
225 parking lot will use this context.</para>
226 <para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
227 will use those parking postitions.</para>
230 <ref type="application">ParkAndAnnounce</ref>
231 <ref type="application">ParkedCall</ref>
234 <manager name="ParkedCalls" language="en_US">
239 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
242 <para>List parked calls.</para>
245 <manager name="Park" language="en_US">
250 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
251 <parameter name="Channel" required="true">
252 <para>Channel name to park.</para>
254 <parameter name="Channel2" required="true">
255 <para>Channel to announce park info to (and return to if timeout).</para>
257 <parameter name="Timeout">
258 <para>Number of milliseconds to wait before callback.</para>
262 <para>Park a channel.</para>
265 <manager name="Bridge" language="en_US">
267 Bridge two channels already in the PBX.
270 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
271 <parameter name="Channel1" required="true">
272 <para>Channel to Bridge to Channel2.</para>
274 <parameter name="Channel2" required="true">
275 <para>Channel to Bridge to Channel1.</para>
277 <parameter name="Tone">
278 <para>Play courtesy tone to Channel 2.</para>
286 <para>Bridge together two channels already in the PBX.</para>
291 #define DEFAULT_PARK_TIME 45000
292 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
293 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000
294 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
295 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
296 #define DEFAULT_ATXFER_DROP_CALL 0
297 #define DEFAULT_ATXFER_LOOP_DELAY 10000
298 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
300 #define AST_MAX_WATCHERS 256
301 #define MAX_DIAL_FEATURE_OPTIONS 30
303 struct feature_group_exten {
304 AST_LIST_ENTRY(feature_group_exten) entry;
305 AST_DECLARE_STRING_FIELDS(
306 AST_STRING_FIELD(exten);
308 struct ast_call_feature *feature;
311 struct feature_group {
312 AST_LIST_ENTRY(feature_group) entry;
313 AST_DECLARE_STRING_FIELDS(
314 AST_STRING_FIELD(gname);
316 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
319 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
321 static char *parkedcall = "ParkedCall";
323 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
325 /*! \brief Description of one parked call, added to a list while active, then removed.
326 The list belongs to a parkinglot
329 struct ast_channel *chan; /*!< Parking channel */
330 struct timeval start; /*!< Time the parking started */
331 int parkingnum; /*!< Parking lot */
332 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
333 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
334 char exten[AST_MAX_EXTENSION];
336 int parkingtime; /*!< Maximum length in parking lot before return */
337 unsigned int notquiteyet:1;
338 unsigned int options_specified:1;
340 unsigned char moh_trys;
341 struct ast_parkinglot *parkinglot;
342 AST_LIST_ENTRY(parkeduser) list;
345 /*! \brief Structure for parking lots which are put in a container. */
346 struct ast_parkinglot {
347 char name[AST_MAX_CONTEXT];
348 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
349 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
350 int parking_start; /*!< First available extension for parking */
351 int parking_stop; /*!< Last available extension for parking */
354 int parkingtime; /*!< Default parking time */
355 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
356 int parkaddhints; /*!< Add parking hints automatically */
357 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
358 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
359 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
360 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
361 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
364 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
365 static struct ao2_container *parkinglots;
367 struct ast_parkinglot *default_parkinglot;
368 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
370 static char courtesytone[256]; /*!< Courtesy tone */
371 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
372 static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
373 static char xfersound[256]; /*!< Call transfer sound */
374 static char xferfailsound[256]; /*!< Call transfer failure sound */
375 static char pickupsound[256]; /*!< Pickup sound */
376 static char pickupfailsound[256]; /*!< Pickup failure sound */
380 static int transferdigittimeout;
381 static int featuredigittimeout;
382 static int comebacktoorigin = 1;
384 static int atxfernoanswertimeout;
385 static unsigned int atxferdropcall;
386 static unsigned int atxferloopdelay;
387 static unsigned int atxfercallbackretries;
389 static char *registrar = "features"; /*!< Registrar for operations */
391 /* module and CLI command definitions */
392 static char *parkcall = PARK_APP_NAME;
394 static struct ast_app *monitor_app = NULL;
395 static int monitor_ok = 1;
397 static struct ast_app *mixmonitor_app = NULL;
398 static int mixmonitor_ok = 1;
400 static struct ast_app *stopmixmonitor_app = NULL;
401 static int stopmixmonitor_ok = 1;
403 static pthread_t parking_thread;
404 struct ast_dial_features {
405 struct ast_flags features_caller;
406 struct ast_flags features_callee;
410 static void *dial_features_duplicate(void *data)
412 struct ast_dial_features *df = data, *df_copy;
414 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
418 memcpy(df_copy, df, sizeof(*df));
423 static void dial_features_destroy(void *data)
425 struct ast_dial_features *df = data;
431 static const struct ast_datastore_info dial_features_info = {
432 .type = "dial-features",
433 .destroy = dial_features_destroy,
434 .duplicate = dial_features_duplicate,
437 /* Forward declarations */
438 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
439 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
440 static void parkinglot_destroy(void *obj);
441 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
442 struct ast_parkinglot *find_parkinglot(const char *name);
443 static struct ast_parkinglot *create_parkinglot(const char *name);
444 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
446 const char *ast_parking_ext(void)
451 const char *ast_pickup_ext(void)
456 struct ast_bridge_thread_obj
458 struct ast_bridge_config bconfig;
459 struct ast_channel *chan;
460 struct ast_channel *peer;
461 unsigned int return_to_pbx:1;
464 static int parkinglot_hash_cb(const void *obj, const int flags)
466 const struct ast_parkinglot *parkinglot = obj;
468 return ast_str_case_hash(parkinglot->name);
471 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
473 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
475 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
479 * \brief store context, extension and priority
480 * \param chan, context, ext, pri
482 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
484 ast_copy_string(chan->context, context, sizeof(chan->context));
485 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
486 chan->priority = pri;
490 * \brief Check goto on transfer
493 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
494 * When found make sure the types are compatible. Check if channel is valid
495 * if so start the new channel else hangup the call.
497 static void check_goto_on_transfer(struct ast_channel *chan)
499 struct ast_channel *xferchan;
500 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
501 char *x, *goto_on_transfer;
504 if (ast_strlen_zero(val))
507 goto_on_transfer = ast_strdupa(val);
509 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", chan->linkedid, 0, "%s", chan->name)))
512 for (x = goto_on_transfer; x && *x; x++) {
516 /* Make formats okay */
517 xferchan->readformat = chan->readformat;
518 xferchan->writeformat = chan->writeformat;
519 ast_channel_masquerade(xferchan, chan);
520 ast_parseable_goto(xferchan, goto_on_transfer);
521 xferchan->_state = AST_STATE_UP;
522 ast_clear_flag(xferchan, AST_FLAGS_ALL);
523 xferchan->_softhangup = 0;
524 if ((f = ast_read(xferchan))) {
527 ast_pbx_start(xferchan);
529 ast_hangup(xferchan);
533 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);
536 * \brief bridge the call
537 * \param data thread bridge.
539 * Set Last Data for respective channels, reset cdr for channels
540 * bridge call, check if we're going back to dialplan
541 * if not hangup both legs of the call
543 static void *bridge_call_thread(void *data)
545 struct ast_bridge_thread_obj *tobj = data;
548 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
549 tobj->chan->data = tobj->peer->name;
550 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
551 tobj->peer->data = tobj->chan->name;
553 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
555 if (tobj->return_to_pbx) {
556 if (!ast_check_hangup(tobj->peer)) {
557 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
558 res = ast_pbx_start(tobj->peer);
559 if (res != AST_PBX_SUCCESS)
560 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
562 ast_hangup(tobj->peer);
563 if (!ast_check_hangup(tobj->chan)) {
564 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
565 res = ast_pbx_start(tobj->chan);
566 if (res != AST_PBX_SUCCESS)
567 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
569 ast_hangup(tobj->chan);
571 ast_hangup(tobj->chan);
572 ast_hangup(tobj->peer);
581 * \brief create thread for the parked call
584 * Create thread and attributes, call bridge_call_thread
586 static void bridge_call_thread_launch(void *data)
590 struct sched_param sched;
592 pthread_attr_init(&attr);
593 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
594 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
595 pthread_attr_destroy(&attr);
596 memset(&sched, 0, sizeof(sched));
597 pthread_setschedparam(thread, SCHED_RR, &sched);
601 * \brief Announce call parking by ADSI
603 * \param parkingexten .
604 * Create message to show for ADSI, display message.
605 * \retval 0 on success.
606 * \retval -1 on failure.
608 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
611 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
613 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
615 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
617 res = ast_adsi_load_session(chan, NULL, 0, 1);
620 return ast_adsi_print(chan, message, justify, 1);
623 /*! \brief Find parking lot name from channel */
624 static const char *findparkinglotname(struct ast_channel *chan)
626 const char *temp, *parkinglot = NULL;
628 /* Check if the channel has a parking lot */
629 if (!ast_strlen_zero(chan->parkinglot))
630 parkinglot = chan->parkinglot;
632 /* Channel variables override everything */
634 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
640 /*! \brief Notify metermaids that we've changed an extension */
641 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
643 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
644 exten, context, ast_devstate2str(state));
646 ast_devstate_changed(state, "park:%s@%s", exten, context);
649 /*! \brief metermaids callback from devicestate.c */
650 static enum ast_device_state metermaidstate(const char *data)
655 context = ast_strdupa(data);
657 exten = strsep(&context, "@");
659 return AST_DEVICE_INVALID;
661 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
663 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
664 return AST_DEVICE_NOT_INUSE;
666 return AST_DEVICE_INUSE;
669 /*! Options to pass to park_call_full */
670 enum ast_park_call_options {
671 /*! Provide ringing to the parked caller instead of music on hold */
672 AST_PARK_OPT_RINGING = (1 << 0),
673 /*! Randomly choose a parking spot for the caller instead of choosing
674 * the first one that is available. */
675 AST_PARK_OPT_RANDOMIZE = (1 << 1),
676 /*! Do not announce the parking number */
677 AST_PARK_OPT_SILENCE = (1 << 2),
680 struct ast_park_call_args {
681 /*! How long to wait in the parking lot before the call gets sent back
682 * to the specified return extension (or a best guess at where it came
683 * from if not explicitly specified). */
685 /*! An output parameter to store the parking space where the parked caller
688 const char *orig_chan_name;
689 const char *return_con;
690 const char *return_ext;
693 /*! Parked user that has already obtained a parking space */
694 struct parkeduser *pu;
697 static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
699 struct parkeduser *pu;
700 int i, parking_space = -1, parking_range;
701 const char *parkinglotname = NULL;
702 const char *parkingexten;
703 struct ast_parkinglot *parkinglot = NULL;
706 parkinglotname = findparkinglotname(peer);
707 else /* peer was NULL, check chan (ParkAndAnnounce / res_agi) */
708 parkinglotname = findparkinglotname(chan);
710 if (parkinglotname) {
711 ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglotname);
712 parkinglot = find_parkinglot(parkinglotname);
716 /* Dynamically create parkinglot */
717 if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
718 const char *dyn_context, *dyn_range;
719 const char *parkinglotname_copy = NULL;
720 struct ast_parkinglot *parkinglot_copy = NULL;
721 int dyn_start, dyn_end;
723 ast_channel_lock(chan);
724 parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
725 dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
726 dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
727 ast_channel_unlock(chan);
729 if (!ast_strlen_zero(parkinglotname_copy)) {
730 parkinglot_copy = find_parkinglot(parkinglotname_copy);
732 if (!parkinglot_copy) {
733 parkinglot_copy = parkinglot_addref(default_parkinglot);
734 ast_debug(1, "Using default parking lot for copy\n");
736 if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
737 ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
739 if (!ast_strlen_zero(dyn_context)) {
740 ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
742 if (!ast_strlen_zero(dyn_range)) {
743 if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
744 ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
746 parkinglot->parking_start = dyn_start;
747 parkinglot->parking_stop = dyn_end;
750 ao2_link(parkinglots, parkinglot);
753 if (parkinglot_copy) {
754 /* unref our tempory copy */
755 parkinglot_unref(parkinglot_copy);
756 parkinglot_copy = NULL;
761 parkinglot = parkinglot_addref(default_parkinglot);
765 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
767 /* Allocate memory for parking data */
768 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
769 parkinglot_unref(parkinglot);
773 /* Lock parking list */
774 AST_LIST_LOCK(&parkinglot->parkings);
775 /* Check for channel variable PARKINGEXTEN */
776 ast_channel_lock(chan);
777 parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
778 ast_channel_unlock(chan);
779 if (!ast_strlen_zero(parkingexten)) {
780 /*!\note The API forces us to specify a numeric parking slot, even
781 * though the architecture would tend to support non-numeric extensions
782 * (as are possible with SIP, for example). Hence, we enforce that
783 * limitation here. If extout was not numeric, we could permit
784 * arbitrary non-numeric extensions.
786 if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space < 0) {
787 AST_LIST_UNLOCK(&parkinglot->parkings);
788 parkinglot_unref(parkinglot);
790 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
793 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
795 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
796 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
797 AST_LIST_UNLOCK(&parkinglot->parkings);
798 parkinglot_unref(parkinglot);
804 struct parkeduser *cur = NULL;
806 /* Select parking space within range */
807 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
809 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
810 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
812 start = parkinglot->parking_start;
815 for (i = start; 1; i++) {
816 if (i == parkinglot->parking_stop + 1) {
817 i = parkinglot->parking_start - 1;
821 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
822 if (cur->parkingnum == i) {
832 if (i == start - 1 && cur) {
833 ast_log(LOG_WARNING, "No more parking spaces\n");
835 AST_LIST_UNLOCK(&parkinglot->parkings);
836 parkinglot_unref(parkinglot);
839 /* Set pointer for next parking */
840 if (parkinglot->parkfindnext)
841 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
842 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
846 pu->parkingnum = parking_space;
847 pu->parkinglot = parkinglot_addref(parkinglot);
848 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
849 parkinglot_unref(parkinglot);
855 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
857 struct ast_context *con;
859 struct parkeduser *pu = args->pu;
860 const char *event_from;
863 args->pu = pu = park_space_reserve(chan, peer, args);
865 return 1; /* Continue execution if possible */
867 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
869 chan->appl = "Parked Call";
874 /* Put the parked channel on hold if we have two different channels */
876 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
877 ast_indicate(pu->chan, AST_CONTROL_RINGING);
879 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
880 S_OR(pu->parkinglot->mohclass, NULL),
881 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
885 pu->start = ast_tvnow();
886 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
887 parkingnum_copy = pu->parkingnum;
889 *(args->extout) = pu->parkingnum;
892 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
893 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
894 and we need the callback name to be that of transferer. Since local,1/2 have the same
895 name we can be tricky and just grab the bridged channel from the other side of the local
897 if (!strcasecmp(peer->tech->type, "Local")) {
898 struct ast_channel *tmpchan, *base_peer;
899 char other_side[AST_CHANNEL_NAME];
901 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
902 if ((c = strrchr(other_side, ';'))) {
905 if ((tmpchan = ast_channel_get_by_name(other_side))) {
906 ast_channel_lock(tmpchan);
907 if ((base_peer = ast_bridged_channel(tmpchan))) {
908 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
910 ast_channel_unlock(tmpchan);
911 tmpchan = ast_channel_unref(tmpchan);
914 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
918 /* Remember what had been dialed, so that if the parking
919 expires, we try to come back to the same place */
921 pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
923 /* If extension has options specified, they override all other possibilities
924 such as the returntoorigin flag and transferred context. Information on
925 extension options is lost here, so we set a flag */
927 ast_copy_string(pu->context,
928 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
929 sizeof(pu->context));
930 ast_copy_string(pu->exten,
931 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
933 pu->priority = args->return_pri ? args->return_pri :
934 (chan->macropriority ? chan->macropriority : chan->priority);
936 /* If parking a channel directly, don't quiet yet get parking running on it.
937 * All parking lot entries are put into the parking lot with notquiteyet on. */
941 /* Wake up the (presumably select()ing) thread */
942 pthread_kill(parking_thread, SIGURG);
943 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));
945 ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
948 event_from = peer->name;
950 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
953 ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
959 "CallerIDNum: %s\r\n"
960 "CallerIDName: %s\r\n"
962 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
963 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
964 S_OR(pu->chan->cid.cid_num, "<unknown>"),
965 S_OR(pu->chan->cid.cid_name, "<unknown>"),
969 if (peer && adsipark && ast_adsi_available(peer)) {
970 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
971 ast_adsi_unload_session(peer);
974 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
975 if (!con) /* Still no context? Bad */
976 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
978 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
979 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
982 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
984 /* Only say number if it's a number and the channel hasn't been masqueraded away */
985 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
986 /* 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. */
987 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
988 /* Tell the peer channel the number of the parking space */
989 ast_say_digits(peer, pu->parkingnum, "", peer->language);
990 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
992 if (peer == chan) { /* pu->notquiteyet = 1 */
993 /* Wake up parking thread if we're really done */
994 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
995 S_OR(pu->parkinglot->mohclass, NULL),
996 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
998 pthread_kill(parking_thread, SIGURG);
1003 /*! \brief Park a call */
1004 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
1006 struct ast_park_call_args args = {
1011 return park_call_full(chan, peer, &args);
1014 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)
1016 struct ast_channel *chan;
1017 struct ast_frame *f;
1019 struct ast_park_call_args park_args = {0,};
1023 args->timeout = timeout;
1024 args->extout = extout;
1027 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
1029 ast_stream_and_wait(peer, "beeperr", "");
1030 return AST_FEATURE_RETURN_PARKFAILED;
1033 /* Make a new, fake channel that we'll use to masquerade in the real one */
1034 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))) {
1035 ast_log(LOG_WARNING, "Unable to create parked channel\n");
1039 /* Make formats okay */
1040 chan->readformat = rchan->readformat;
1041 chan->writeformat = rchan->writeformat;
1042 ast_channel_masquerade(chan, rchan);
1044 /* Setup the extensions and such */
1045 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
1047 /* Setup the macro extension and such */
1048 ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
1049 ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
1050 chan->macropriority = rchan->macropriority;
1052 /* Make the masq execute */
1053 if ((f = ast_read(chan)))
1056 if (peer == rchan) {
1060 if (peer && (!play_announcement && args == &park_args)) {
1061 args->orig_chan_name = ast_strdupa(peer->name);
1064 park_status = park_call_full(chan, peer, args);
1065 if (park_status == 1) {
1066 /* would be nice to play "invalid parking extension" */
1074 /* Park call via masqueraded channel */
1075 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1077 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
1080 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
1082 return masq_park_call(rchan, peer, 0, NULL, 1, args);
1085 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1087 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
1090 #ifdef TEST_FRAMEWORK
1091 static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
1096 static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
1098 struct ast_channel *test_channel1;
1099 if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1100 NULL, NULL, 0, 0, "TestChannel1"))) {
1104 /* normally this is done in the channel driver */
1105 test_channel1->nativeformats = AST_FORMAT_GSM;
1106 test_channel1->writeformat = AST_FORMAT_GSM;
1107 test_channel1->rawwriteformat = AST_FORMAT_GSM;
1108 test_channel1->readformat = AST_FORMAT_GSM;
1109 test_channel1->rawreadformat = AST_FORMAT_GSM;
1110 test_channel1->tech = fake_tech;
1112 return test_channel1;
1115 static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
1117 struct ast_context *con;
1118 struct parkeduser *pu_toremove;
1119 args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
1120 AST_LIST_LOCK(&args->pu->parkinglot->parkings);
1121 AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
1122 con = ast_context_find(args->pu->parkinglot->parking_con);
1124 if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
1125 ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
1128 notify_metermaids(args->pu->parkingexten, pu_toremove->parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
1131 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1134 if (pu_toremove == args->pu) {
1135 AST_LIST_REMOVE_CURRENT(list);
1139 AST_LIST_TRAVERSE_SAFE_END;
1140 AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
1142 /* the only way this would be unsafe is if a timeout occurred, which is set at 45 sec */
1146 ast_hangup(toremove);
1150 AST_TEST_DEFINE(features_test)
1152 int saved_parkeddynamic;
1153 struct ast_channel *test_channel1 = NULL;
1154 struct ast_channel *parked_chan = NULL;
1155 struct ast_parkinglot *dynlot = NULL;
1156 struct ast_park_call_args args = {
1157 .timeout = DEFAULT_PARK_TIME,
1162 static const struct ast_channel_tech fake_tech = {
1163 .fixup = fake_fixup, /* silence warning from masquerade */
1166 static const char unique_parkinglot[] = "myuniquetestparkinglot3141592654";
1167 static const char parkinglot_range[] = "750-760";
1171 info->name = "features_test";
1172 info->category = "/main/features/";
1173 info->summary = "Features unit test";
1175 "Tests whether parking respects PARKINGLOT settings";
1176 return AST_TEST_NOT_RUN;
1181 /* changing a config option is a bad practice, but must be done in this case */
1182 saved_parkeddynamic = parkeddynamic;
1185 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1186 goto exit_features_test;
1189 ast_test_status_update(test, "Test parking functionality with defaults\n");
1190 if (park_call_full(test_channel1, NULL, &args)) {
1191 goto exit_features_test;
1193 if (unpark_test_channel(test_channel1, &args)) {
1194 goto exit_features_test;
1197 ast_test_status_update(test, "Check that certain parking options are respected\n");
1198 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1199 goto exit_features_test;
1201 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1202 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1203 if (park_call_full(test_channel1, NULL, &args)) {
1204 goto exit_features_test;
1206 /* grab newly created parking lot for destruction in the end */
1207 dynlot = args.pu->parkinglot;
1208 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1209 ast_test_status_update(test, "Parking settings were not respected\n");
1210 goto exit_features_test;
1212 ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
1214 if (unpark_test_channel(test_channel1, &args)) {
1215 goto exit_features_test;
1218 ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
1219 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1220 goto exit_features_test;
1222 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1223 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1224 if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args) == AST_FEATURE_RETURN_PARKFAILED) {
1225 goto exit_features_test;
1227 /* hangup zombie channel */
1228 ast_hangup(test_channel1);
1229 test_channel1 = NULL;
1230 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1231 ast_test_status_update(test, "Parking settings were not respected\n");
1232 goto exit_features_test;
1234 ast_test_status_update(test, "Parking settings for masquerading park verified\n");
1236 /* find the real channel */
1237 parked_chan = ast_channel_get_by_name("TestChannel1");
1238 if (unpark_test_channel(parked_chan, &args)) {
1239 goto exit_features_test;
1246 if (test_channel1) {
1247 ast_hangup(test_channel1);
1250 /* careful, if PARKINGDYNCONTEXT is tested, need to delete context */
1251 ao2_unlink(parkinglots, dynlot);
1252 parkeddynamic = saved_parkeddynamic;
1253 return res ? AST_TEST_FAIL : AST_TEST_PASS;
1259 * \brief set caller and callee according to the direction
1260 * \param caller, callee, peer, chan, sense
1262 * Detect who triggered feature and set callee/caller variables accordingly
1264 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
1265 struct ast_channel *peer, struct ast_channel *chan, int sense)
1267 if (sense == FEATURE_SENSE_PEER) {
1277 * \brief support routing for one touch call parking
1278 * \param chan channel parking call
1279 * \param peer channel to be parked
1280 * \param config unsed
1281 * \param code unused
1282 * \param sense feature options
1285 * Setup channel, set return exten,priority to 's,1'
1286 * answer chan, sleep chan, park call
1288 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1290 struct ast_channel *parker;
1291 struct ast_channel *parkee;
1294 set_peers(&parker, &parkee, peer, chan, sense);
1295 /* we used to set chan's exten and priority to "s" and 1
1296 here, but this generates (in some cases) an invalid
1297 extension, and if "s" exists, could errantly
1298 cause execution of extensions you don't expect. It
1299 makes more sense to let nature take its course
1300 when chan finishes, and let the pbx do its thing
1301 and hang up when the park is over.
1303 if (chan->_state != AST_STATE_UP)
1304 res = ast_answer(chan);
1306 res = ast_safe_sleep(chan, 1000);
1308 if (!res) { /* one direction used to call park_call.... */
1309 res = masq_park_call_announce(parkee, parker, 0, NULL);
1310 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
1316 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1317 other channel during the message, so please don't use this for very long messages
1319 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1321 /* First play for caller, put other channel on auto service */
1322 if (ast_autoservice_start(callee_chan))
1324 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
1325 ast_log(LOG_WARNING, "Failed to play automon message!\n");
1326 ast_autoservice_stop(callee_chan);
1329 if (ast_autoservice_stop(callee_chan))
1331 /* Then play for callee, put other channel on auto service */
1332 if (ast_autoservice_start(caller_chan))
1334 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
1335 ast_log(LOG_WARNING, "Failed to play automon message !\n");
1336 ast_autoservice_stop(caller_chan);
1339 if (ast_autoservice_stop(caller_chan))
1345 * \brief Monitor a channel by DTMF
1346 * \param chan channel requesting monitor
1347 * \param peer channel to be monitored
1350 * \param sense feature options
1353 * Check monitor app enabled, setup channels, both caller/callee chans not null
1354 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
1355 * \retval AST_FEATURE_RETURN_SUCCESS on success.
1356 * \retval -1 on error.
1358 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1360 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1363 struct ast_channel *caller_chan, *callee_chan;
1364 const char *automon_message_start = NULL;
1365 const char *automon_message_stop = NULL;
1368 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1372 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1374 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1378 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1379 if (caller_chan) { /* Find extra messages */
1380 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1381 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1384 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1385 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1390 if (callee_chan->monitor) {
1391 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1392 if (!ast_strlen_zero(automon_message_stop)) {
1393 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1395 callee_chan->monitor->stop(callee_chan, 1);
1396 return AST_FEATURE_RETURN_SUCCESS;
1399 if (caller_chan && callee_chan) {
1400 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1401 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1402 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1405 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1408 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1410 if (!touch_monitor_prefix)
1411 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1413 if (touch_monitor) {
1414 len = strlen(touch_monitor) + 50;
1416 touch_filename = alloca(len);
1417 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1418 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1420 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1421 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1422 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1424 touch_filename = alloca(len);
1425 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1426 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1429 for(x = 0; x < strlen(args); x++) {
1434 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1436 pbx_exec(callee_chan, monitor_app, args);
1437 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1438 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1440 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1441 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1444 return AST_FEATURE_RETURN_SUCCESS;
1447 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1451 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1453 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1456 struct ast_channel *caller_chan, *callee_chan;
1457 const char *mixmonitor_spy_type = "MixMonitor";
1460 if (!mixmonitor_ok) {
1461 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1465 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1467 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1471 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1473 if (!ast_strlen_zero(courtesytone)) {
1474 if (ast_autoservice_start(callee_chan))
1476 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1477 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1478 ast_autoservice_stop(callee_chan);
1481 if (ast_autoservice_stop(callee_chan))
1485 ast_channel_lock(callee_chan);
1486 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1487 ast_channel_unlock(callee_chan);
1489 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1492 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1494 /* Make sure they are running */
1495 ast_channel_lock(callee_chan);
1496 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1497 ast_channel_unlock(callee_chan);
1499 if (!stopmixmonitor_ok) {
1500 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1503 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1504 stopmixmonitor_ok = 0;
1505 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1508 pbx_exec(callee_chan, stopmixmonitor_app, "");
1509 return AST_FEATURE_RETURN_SUCCESS;
1513 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1516 if (caller_chan && callee_chan) {
1517 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1518 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1521 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1524 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1526 if (touch_monitor) {
1527 len = strlen(touch_monitor) + 50;
1529 touch_filename = alloca(len);
1530 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1531 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1533 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1534 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1535 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1537 touch_filename = alloca(len);
1538 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1539 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1542 for( x = 0; x < strlen(args); x++) {
1547 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1549 pbx_exec(callee_chan, mixmonitor_app, args);
1550 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1551 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1552 return AST_FEATURE_RETURN_SUCCESS;
1556 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1561 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1563 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1564 return AST_FEATURE_RETURN_HANGUP;
1567 static int finishup(struct ast_channel *chan)
1569 ast_indicate(chan, AST_CONTROL_UNHOLD);
1571 return ast_autoservice_stop(chan);
1575 * \brief Find the context for the transfer
1579 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1580 * \return a context string
1582 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1584 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1585 if (ast_strlen_zero(s)) {
1586 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1588 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1589 s = transferer->macrocontext;
1591 if (ast_strlen_zero(s)) {
1592 s = transferer->context;
1598 * \brief Blind transfer user to another extension
1599 * \param chan channel to be transfered
1600 * \param peer channel initiated blind transfer
1604 * \param sense feature options
1606 * Place chan on hold, check if transferred to parkinglot extension,
1607 * otherwise check extension exists and transfer caller.
1608 * \retval AST_FEATURE_RETURN_SUCCESS.
1609 * \retval -1 on failure.
1611 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1613 struct ast_channel *transferer;
1614 struct ast_channel *transferee;
1615 const char *transferer_real_context;
1617 int res, parkstatus = 0;
1619 set_peers(&transferer, &transferee, peer, chan, sense);
1620 transferer_real_context = real_ctx(transferer, transferee);
1621 /* Start autoservice on chan while we talk to the originator */
1622 ast_autoservice_start(transferee);
1623 ast_indicate(transferee, AST_CONTROL_HOLD);
1625 memset(xferto, 0, sizeof(xferto));
1628 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1630 finishup(transferee);
1631 return -1; /* error ? */
1633 if (res > 0) /* If they've typed a digit already, handle it */
1634 xferto[0] = (char) res;
1636 ast_stopstream(transferer);
1637 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1638 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1639 finishup(transferee);
1642 if (!strcmp(xferto, ast_parking_ext())) {
1643 res = finishup(transferee);
1646 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1647 /* We return non-zero, but tell the PBX not to hang the channel when
1648 the thread dies -- We have to be careful now though. We are responsible for
1649 hanging up the channel, else it will never be hung up! */
1653 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1655 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1656 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1657 ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
1658 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1659 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1660 res=finishup(transferee);
1661 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1662 transferer->cdr=ast_cdr_alloc();
1663 if (transferer->cdr) {
1664 ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
1665 ast_cdr_start(transferer->cdr);
1668 if (transferer->cdr) {
1669 struct ast_cdr *swap = transferer->cdr;
1670 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1671 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1672 transferer->cdr->channel, transferer->cdr->dstchannel);
1673 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1674 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1675 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1676 /* swap cdrs-- it will save us some time & work */
1677 transferer->cdr = transferee->cdr;
1678 transferee->cdr = swap;
1680 if (!transferee->pbx) {
1681 /* Doh! Use our handy async_goto functions */
1682 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1683 ,transferee->name, xferto, transferer_real_context);
1684 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1685 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1687 /* Set the channel's new extension, since it exists, using transferer context */
1688 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1689 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1690 if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
1691 ast_channel_update_connected_line(transferee, &transferer->connected);
1693 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1695 check_goto_on_transfer(transferer);
1698 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1700 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1701 finishup(transferee);
1704 ast_stopstream(transferer);
1705 res = finishup(transferee);
1707 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1710 return AST_FEATURE_RETURN_SUCCESS;
1714 * \brief make channels compatible
1717 * \retval 0 on success.
1718 * \retval -1 on failure.
1720 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1722 if (ast_channel_make_compatible(c, newchan) < 0) {
1723 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1724 c->name, newchan->name);
1725 ast_hangup(newchan);
1732 * \brief Attended transfer
1733 * \param chan transfered user
1734 * \param peer person transfering call
1737 * \param sense feature options
1740 * Get extension to transfer to, if you cannot generate channel (or find extension)
1741 * return to host channel. After called channel answered wait for hangup of transferer,
1742 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1744 * \return -1 on failure
1746 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1748 struct ast_channel *transferer;
1749 struct ast_channel *transferee;
1750 const char *transferer_real_context;
1751 char xferto[256] = "";
1754 struct ast_channel *newchan;
1755 struct ast_channel *xferchan;
1756 struct ast_bridge_thread_obj *tobj;
1757 struct ast_bridge_config bconfig;
1758 struct ast_frame *f;
1760 struct ast_party_connected_line connected_line;
1761 struct ast_datastore *features_datastore;
1762 struct ast_dial_features *dialfeatures = NULL;
1764 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1765 set_peers(&transferer, &transferee, peer, chan, sense);
1766 transferer_real_context = real_ctx(transferer, transferee);
1767 /* Start autoservice on chan while we talk to the originator */
1768 ast_autoservice_start(transferee);
1769 ast_indicate(transferee, AST_CONTROL_HOLD);
1772 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1774 finishup(transferee);
1777 if (res > 0) /* If they've typed a digit already, handle it */
1778 xferto[0] = (char) res;
1780 /* this is specific of atxfer */
1781 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1782 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1783 finishup(transferee);
1787 ast_log(LOG_WARNING, "Did not read data.\n");
1788 finishup(transferee);
1789 if (ast_stream_and_wait(transferer, "beeperr", ""))
1791 return AST_FEATURE_RETURN_SUCCESS;
1794 /* valid extension, res == 1 */
1795 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1796 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1797 finishup(transferee);
1798 if (ast_stream_and_wait(transferer, "beeperr", ""))
1800 return AST_FEATURE_RETURN_SUCCESS;
1803 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1804 * the different variables for handling this properly with a builtin_atxfer */
1805 if (!strcmp(xferto, ast_parking_ext())) {
1806 finishup(transferee);
1807 return builtin_parkcall(chan, peer, config, code, sense, data);
1811 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1813 /* If we are performing an attended transfer and we have two channels involved then
1814 copy sound file information to play upon attended transfer completion */
1816 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1817 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1819 if (!ast_strlen_zero(chan1_attended_sound)) {
1820 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1822 if (!ast_strlen_zero(chan2_attended_sound)) {
1823 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1827 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1828 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1830 ast_party_connected_line_init(&connected_line);
1831 if (!ast_check_hangup(transferer)) {
1832 /* Transferer is up - old behaviour */
1833 ast_indicate(transferer, -1);
1835 finishup(transferee);
1836 /* any reason besides user requested cancel and busy triggers the failed sound */
1837 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1838 ast_stream_and_wait(transferer, xferfailsound, ""))
1840 if (ast_stream_and_wait(transferer, xfersound, ""))
1841 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1842 return AST_FEATURE_RETURN_SUCCESS;
1845 if (check_compat(transferer, newchan)) {
1846 /* we do mean transferee here, NOT transferer */
1847 finishup(transferee);
1850 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1851 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1852 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1853 /* We need to get the transferer's connected line information copied
1854 * at this point because he is likely to hang up during the bridge with
1855 * newchan. This info will be used down below before bridging the
1856 * transferee and newchan
1858 * As a result, we need to be sure to free this data before returning
1859 * or overwriting it.
1861 ast_channel_lock(transferer);
1862 ast_party_connected_line_copy(&connected_line, &transferer->connected);
1863 ast_channel_unlock(transferer);
1864 res = ast_bridge_call(transferer, newchan, &bconfig);
1865 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1866 ast_hangup(newchan);
1867 if (ast_stream_and_wait(transferer, xfersound, ""))
1868 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1869 finishup(transferee);
1870 transferer->_softhangup = 0;
1871 ast_party_connected_line_free(&connected_line);
1872 return AST_FEATURE_RETURN_SUCCESS;
1875 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
1877 if (check_compat(transferee, newchan)) {
1878 finishup(transferee);
1879 ast_party_connected_line_free(&connected_line);
1882 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1884 if ((ast_autoservice_stop(transferee) < 0)
1885 || (ast_waitfordigit(transferee, 100) < 0)
1886 || (ast_waitfordigit(newchan, 100) < 0)
1887 || ast_check_hangup(transferee)
1888 || ast_check_hangup(newchan)) {
1889 ast_hangup(newchan);
1890 ast_party_connected_line_free(&connected_line);
1893 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
1895 ast_hangup(newchan);
1896 ast_party_connected_line_free(&connected_line);
1899 /* Make formats okay */
1900 xferchan->visible_indication = transferer->visible_indication;
1901 xferchan->readformat = transferee->readformat;
1902 xferchan->writeformat = transferee->writeformat;
1903 ast_channel_masquerade(xferchan, transferee);
1904 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1905 xferchan->_state = AST_STATE_UP;
1906 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1907 xferchan->_softhangup = 0;
1908 if ((f = ast_read(xferchan)))
1910 newchan->_state = AST_STATE_UP;
1911 ast_clear_flag(newchan, AST_FLAGS_ALL);
1912 newchan->_softhangup = 0;
1913 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1914 ast_hangup(xferchan);
1915 ast_hangup(newchan);
1916 ast_party_connected_line_free(&connected_line);
1920 ast_channel_lock(newchan);
1921 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1922 dialfeatures = features_datastore->data;
1924 ast_channel_unlock(newchan);
1927 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1928 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1929 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1930 dialfeatures = NULL;
1933 ast_channel_lock(xferchan);
1934 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1935 dialfeatures = features_datastore->data;
1937 ast_channel_unlock(xferchan);
1940 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1943 tobj->chan = newchan;
1944 tobj->peer = xferchan;
1945 tobj->bconfig = *config;
1947 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1948 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1951 /* Due to a limitation regarding when callerID is set on a Local channel,
1952 * we use the transferer's connected line information here.
1955 /* xferchan is transferee, and newchan is the transfer target
1956 * So...in a transfer, who is the caller and who is the callee?
1958 * When the call is originally made, it is clear who is caller and callee.
1959 * When a transfer occurs, it is my humble opinion that the transferee becomes
1960 * the caller, and the transfer target is the callee.
1962 * The problem is that these macros were set with the intention of the original
1963 * caller and callee taking those roles. A transfer can totally mess things up,
1964 * to be technical. What sucks even more is that you can't effectively change
1965 * the macros in the dialplan during the call from the transferer to the transfer
1966 * target because the transferee is stuck with whatever role he originally had.
1968 * I think the answer here is just to make sure that it is well documented that
1969 * during a transfer, the transferee is the "caller" and the transfer target
1972 * This means that if party A calls party B, and party A transfers party B to
1973 * party C, then B has switched roles for the call. Now party B will have the
1974 * caller macro called on his channel instead of the callee macro.
1976 * Luckily, the method by which the bridge is launched here ensures that the
1977 * transferee is the "chan" on the bridge and the transfer target is the "peer,"
1978 * so my idea for the roles post-transfer does not require extensive code changes.
1980 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1981 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1982 ast_channel_update_connected_line(xferchan, &connected_line);
1984 ast_channel_lock(xferchan);
1985 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1986 ast_channel_unlock(xferchan);
1987 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1988 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1989 ast_channel_update_connected_line(newchan, &connected_line);
1991 ast_party_connected_line_free(&connected_line);
1993 if (ast_stream_and_wait(newchan, xfersound, ""))
1994 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1995 bridge_call_thread_launch(tobj);
1996 return -1; /* XXX meaning the channel is bridged ? */
1997 } else if (!ast_check_hangup(transferee)) {
1998 /* act as blind transfer */
1999 if (ast_autoservice_stop(transferee) < 0) {
2000 ast_hangup(newchan);
2005 unsigned int tries = 0;
2006 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
2008 transferer_tech = strsep(&transferer_name, "/");
2009 transferer_name = strsep(&transferer_name, "-");
2011 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
2012 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
2013 if (ast_stream_and_wait(transferee, "beeperr", ""))
2015 return AST_FEATURE_RETURN_SUCCESS;
2018 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
2019 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
2020 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
2021 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
2022 /* Trying to transfer again */
2023 ast_autoservice_start(transferee);
2024 ast_indicate(transferee, AST_CONTROL_HOLD);
2026 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
2027 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
2028 if (ast_autoservice_stop(transferee) < 0) {
2030 ast_hangup(newchan);
2034 /* Transfer failed, sleeping */
2035 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
2036 ast_safe_sleep(transferee, atxferloopdelay);
2037 ast_debug(1, "Trying to callback...\n");
2038 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
2039 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
2047 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
2049 /* newchan is up, we should prepare transferee and bridge them */
2050 if (check_compat(transferee, newchan)) {
2051 finishup(transferee);
2054 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2056 if ((ast_waitfordigit(transferee, 100) < 0)
2057 || (ast_waitfordigit(newchan, 100) < 0)
2058 || ast_check_hangup(transferee)
2059 || ast_check_hangup(newchan)) {
2060 ast_hangup(newchan);
2064 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
2066 ast_hangup(newchan);
2069 /* Make formats okay */
2070 xferchan->visible_indication = transferer->visible_indication;
2071 xferchan->readformat = transferee->readformat;
2072 xferchan->writeformat = transferee->writeformat;
2073 ast_channel_masquerade(xferchan, transferee);
2074 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
2075 xferchan->_state = AST_STATE_UP;
2076 ast_clear_flag(xferchan, AST_FLAGS_ALL);
2077 xferchan->_softhangup = 0;
2078 if ((f = ast_read(xferchan)))
2080 newchan->_state = AST_STATE_UP;
2081 ast_clear_flag(newchan, AST_FLAGS_ALL);
2082 newchan->_softhangup = 0;
2083 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
2084 ast_hangup(xferchan);
2085 ast_hangup(newchan);
2088 tobj->chan = newchan;
2089 tobj->peer = xferchan;
2090 tobj->bconfig = *config;
2092 if (tobj->bconfig.end_bridge_callback_data_fixup) {
2093 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
2096 ast_channel_lock(newchan);
2097 ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
2098 ast_channel_unlock(newchan);
2099 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2100 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
2101 ast_channel_update_connected_line(xferchan, &connected_line);
2103 ast_channel_lock(xferchan);
2104 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
2105 ast_channel_unlock(xferchan);
2106 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2107 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
2108 ast_channel_update_connected_line(newchan, &connected_line);
2111 ast_party_connected_line_free(&connected_line);
2113 if (ast_stream_and_wait(newchan, xfersound, ""))
2114 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2115 bridge_call_thread_launch(tobj);
2116 return -1; /* XXX meaning the channel is bridged ? */
2118 /* Transferee hung up */
2119 finishup(transferee);
2120 /* At this point both the transferer transferee have hungup,
2121 * so if newchan is up, hang it up as it has no one to talk to */
2123 ast_hangup(newchan);
2129 /* add atxfer and automon as undefined so you can only use em if you configure them */
2130 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
2132 AST_RWLOCK_DEFINE_STATIC(features_lock);
2134 static struct ast_call_feature builtin_features[] = {
2135 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2136 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2137 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2138 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2139 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2140 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2144 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
2146 /*! \brief register new feature into feature_list*/
2147 void ast_register_feature(struct ast_call_feature *feature)
2150 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
2154 AST_RWLIST_WRLOCK(&feature_list);
2155 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
2156 AST_RWLIST_UNLOCK(&feature_list);
2158 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
2162 * \brief Add new feature group
2163 * \param fgname feature group name.
2165 * Add new feature group to the feature group list insert at head of list.
2166 * \note This function MUST be called while feature_groups is locked.
2168 static struct feature_group *register_group(const char *fgname)
2170 struct feature_group *fg;
2173 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
2177 if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128))) {
2181 ast_string_field_set(fg, gname, fgname);
2183 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
2185 ast_verb(2, "Registered group '%s'\n", fg->gname);
2191 * \brief Add feature to group
2192 * \param fg feature group
2194 * \param feature feature to add.
2196 * Check fg and feature specified, add feature to list
2197 * \note This function MUST be called while feature_groups is locked.
2199 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
2201 struct feature_group_exten *fge;
2204 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
2209 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
2213 if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128))) {
2217 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
2219 fge->feature = feature;
2221 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
2223 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
2224 feature->sname, fg->gname, fge->exten);
2227 void ast_unregister_feature(struct ast_call_feature *feature)
2233 AST_RWLIST_WRLOCK(&feature_list);
2234 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
2235 AST_RWLIST_UNLOCK(&feature_list);
2240 /*! \brief Remove all features in the list */
2241 static void ast_unregister_features(void)
2243 struct ast_call_feature *feature;
2245 AST_RWLIST_WRLOCK(&feature_list);
2246 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
2249 AST_RWLIST_UNLOCK(&feature_list);
2252 /*! \brief find a call feature by name */
2253 static struct ast_call_feature *find_dynamic_feature(const char *name)
2255 struct ast_call_feature *tmp;
2257 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
2258 if (!strcasecmp(tmp->sname, name)) {
2266 /*! \brief Remove all feature groups in the list */
2267 static void ast_unregister_groups(void)
2269 struct feature_group *fg;
2270 struct feature_group_exten *fge;
2272 AST_RWLIST_WRLOCK(&feature_groups);
2273 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
2274 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
2275 ast_string_field_free_memory(fge);
2279 ast_string_field_free_memory(fg);
2282 AST_RWLIST_UNLOCK(&feature_groups);
2286 * \brief Find a group by name
2287 * \param name feature name
2288 * \retval feature group on success.
2289 * \retval NULL on failure.
2291 static struct feature_group *find_group(const char *name)
2293 struct feature_group *fg = NULL;
2295 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
2296 if (!strcasecmp(fg->gname, name))
2303 void ast_rdlock_call_features(void)
2305 ast_rwlock_rdlock(&features_lock);
2308 void ast_unlock_call_features(void)
2310 ast_rwlock_unlock(&features_lock);
2313 struct ast_call_feature *ast_find_call_feature(const char *name)
2316 for (x = 0; x < FEATURES_COUNT; x++) {
2317 if (!strcasecmp(name, builtin_features[x].sname))
2318 return &builtin_features[x];
2324 * \brief exec an app by feature
2325 * \param chan,peer,config,code,sense,data
2327 * Find a feature, determine which channel activated
2328 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
2330 * \retval -2 when an application cannot be found.
2332 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)
2334 struct ast_app *app;
2335 struct ast_call_feature *feature = data;
2336 struct ast_channel *work, *idle;
2339 if (!feature) { /* shouldn't ever happen! */
2340 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
2344 if (sense == FEATURE_SENSE_CHAN) {
2345 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2346 return AST_FEATURE_RETURN_KEEPTRYING;
2347 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2355 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2356 return AST_FEATURE_RETURN_KEEPTRYING;
2357 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2366 if (!(app = pbx_findapp(feature->app))) {
2367 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
2371 ast_autoservice_start(idle);
2374 pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", idle->name);
2375 pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", work->name);
2376 pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
2377 pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
2380 if (!ast_strlen_zero(feature->moh_class))
2381 ast_moh_start(idle, feature->moh_class, NULL);
2383 res = pbx_exec(work, app, feature->app_args);
2385 if (!ast_strlen_zero(feature->moh_class))
2388 ast_autoservice_stop(idle);
2391 return AST_FEATURE_RETURN_SUCCESSBREAK;
2393 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
2396 static void unmap_features(void)
2400 ast_rwlock_wrlock(&features_lock);
2401 for (x = 0; x < FEATURES_COUNT; x++)
2402 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
2403 ast_rwlock_unlock(&features_lock);
2406 static int remap_feature(const char *name, const char *value)
2410 ast_rwlock_wrlock(&features_lock);
2411 for (x = 0; x < FEATURES_COUNT; x++) {
2412 if (strcasecmp(builtin_features[x].sname, name))
2415 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
2419 ast_rwlock_unlock(&features_lock);
2425 * \brief Helper function for feature_interpret and ast_feature_detect
2426 * \param chan,peer,config,code,sense,dynamic_features_buf,features,operation,feature
2428 * Lock features list, browse for code, unlock list
2429 * If a feature is found and the operation variable is set, that feature's
2430 * operation is executed. The first feature found is copied to the feature parameter.
2431 * \retval res on success.
2432 * \retval -1 on failure.
2434 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
2435 struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
2436 struct ast_flags *features, int operation, struct ast_call_feature *feature)
2439 struct feature_group *fg = NULL;
2440 struct feature_group_exten *fge;
2441 struct ast_call_feature *tmpfeature;
2443 int res = AST_FEATURE_RETURN_PASSDIGITS;
2444 int feature_detected = 0;
2446 if (!(peer && chan && config) && operation) {
2447 return -1; /* can not run feature operation */
2450 ast_rwlock_rdlock(&features_lock);
2451 for (x = 0; x < FEATURES_COUNT; x++) {
2452 if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
2453 !ast_strlen_zero(builtin_features[x].exten)) {
2454 /* Feature is up for consideration */
2455 if (!strcmp(builtin_features[x].exten, code)) {
2456 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2458 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2460 memcpy(feature, &builtin_features[x], sizeof(feature));
2461 feature_detected = 1;
2463 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2464 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2465 res = AST_FEATURE_RETURN_STOREDIGITS;
2469 ast_rwlock_unlock(&features_lock);
2471 if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
2475 tmp = dynamic_features_buf;
2477 while ((tok = strsep(&tmp, "#"))) {
2478 AST_RWLIST_RDLOCK(&feature_groups);
2480 fg = find_group(tok);
2483 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2484 if (!strcmp(fge->exten, code)) {
2486 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2488 memcpy(feature, fge->feature, sizeof(feature));
2489 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2490 AST_RWLIST_UNLOCK(&feature_groups);
2493 res = AST_FEATURE_RETURN_PASSDIGITS;
2494 } else if (!strncmp(fge->exten, code, strlen(code))) {
2495 res = AST_FEATURE_RETURN_STOREDIGITS;
2503 AST_RWLIST_UNLOCK(&feature_groups);
2505 AST_RWLIST_RDLOCK(&feature_list);
2507 if (!(tmpfeature = find_dynamic_feature(tok))) {
2508 AST_RWLIST_UNLOCK(&feature_list);
2512 /* Feature is up for consideration */
2513 if (!strcmp(tmpfeature->exten, code)) {
2514 ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
2516 res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
2518 memcpy(feature, tmpfeature, sizeof(feature));
2519 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2520 AST_RWLIST_UNLOCK(&feature_list);
2523 res = AST_FEATURE_RETURN_PASSDIGITS;
2524 } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
2525 res = AST_FEATURE_RETURN_STOREDIGITS;
2527 AST_RWLIST_UNLOCK(&feature_list);
2534 * \brief Check the dynamic features
2535 * \param chan,peer,config,code,sense
2537 * \retval res on success.
2538 * \retval -1 on failure.
2541 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
2543 char dynamic_features_buf[128];
2544 const char *peer_dynamic_features, *chan_dynamic_features;
2545 struct ast_flags features;
2546 struct ast_call_feature feature;
2547 if (sense == FEATURE_SENSE_CHAN) {
2548 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
2551 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
2554 ast_channel_lock(peer);
2555 peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
2556 ast_channel_unlock(peer);
2558 ast_channel_lock(chan);
2559 chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
2560 ast_channel_unlock(chan);
2562 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,""));
2564 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);
2566 return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, 1, &feature);
2570 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
2572 return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
2575 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2579 ast_clear_flag(config, AST_FLAGS_ALL);
2581 ast_rwlock_rdlock(&features_lock);
2582 for (x = 0; x < FEATURES_COUNT; x++) {
2583 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2586 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2587 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2589 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2590 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2592 ast_rwlock_unlock(&features_lock);
2594 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2595 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2597 if (dynamic_features) {
2598 char *tmp = ast_strdupa(dynamic_features);
2600 struct ast_call_feature *feature;
2602 /* while we have a feature */
2603 while ((tok = strsep(&tmp, "#"))) {
2604 struct feature_group *fg;
2606 AST_RWLIST_RDLOCK(&feature_groups);
2607 AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
2608 struct feature_group_exten *fge;
2610 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2611 if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLER)) {
2612 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2614 if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLEE)) {
2615 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2619 AST_RWLIST_UNLOCK(&feature_groups);
2621 AST_RWLIST_RDLOCK(&feature_list);
2622 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2623 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
2624 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2626 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) {
2627 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2630 AST_RWLIST_UNLOCK(&feature_list);
2637 * \brief Get feature and dial
2638 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate,language
2640 * Request channel, set channel variables, initiate call,check if they want to disconnect
2641 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2642 * check for answer break loop, set cdr return channel.
2644 * \todo XXX Check - this is very similar to the code in channel.c
2645 * \return always a channel
2647 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)
2652 struct ast_channel *chan;
2653 struct ast_channel *monitor_chans[2];
2654 struct ast_channel *active_channel;
2655 int res = 0, ready = 0;
2656 struct timeval started;
2658 char *disconnect_code = NULL, *dialed_code = NULL;
2660 if (!(chan = ast_request(type, format, caller, data, &cause))) {
2661 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2663 case AST_CAUSE_BUSY:
2664 state = AST_CONTROL_BUSY;
2666 case AST_CAUSE_CONGESTION:
2667 state = AST_CONTROL_CONGESTION;
2673 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2674 ast_string_field_set(chan, language, language);
2675 ast_channel_inherit_variables(caller, chan);
2676 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2678 ast_channel_lock(chan);
2679 ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
2680 ast_channel_unlock(chan);
2682 if (ast_call(chan, data, timeout)) {
2683 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2687 ast_indicate(caller, AST_CONTROL_RINGING);
2688 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2689 ast_rwlock_rdlock(&features_lock);
2690 for (x = 0; x < FEATURES_COUNT; x++) {
2691 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2694 disconnect_code = builtin_features[x].exten;
2695 len = strlen(disconnect_code) + 1;
2696 dialed_code = alloca(len);
2697 memset(dialed_code, 0, len);
2700 ast_rwlock_unlock(&features_lock);
2702 started = ast_tvnow();
2705 ast_poll_channel_add(caller, chan);
2707 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2708 struct ast_frame *f = NULL;
2710 monitor_chans[0] = caller;
2711 monitor_chans[1] = chan;
2712 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2714 /* see if the timeout has been violated */
2715 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2716 state = AST_CONTROL_UNHOLD;
2717 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2718 break; /*doh! timeout*/
2721 if (!active_channel)
2724 if (chan && (chan == active_channel)){
2725 if (!ast_strlen_zero(chan->call_forward)) {
2726 if (!(chan = ast_call_forward(caller, chan, &to, format, NULL, outstate))) {
2732 if (f == NULL) { /*doh! where'd he go?*/
2733 state = AST_CONTROL_HANGUP;
2738 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2739 if (f->subclass.integer == AST_CONTROL_RINGING) {
2740 state = f->subclass.integer;
2741 ast_verb(3, "%s is ringing\n", chan->name);
2742 ast_indicate(caller, AST_CONTROL_RINGING);
2743 } else if ((f->subclass.integer == AST_CONTROL_BUSY) || (f->subclass.integer == AST_CONTROL_CONGESTION)) {
2744 state = f->subclass.integer;
2745 ast_verb(3, "%s is busy\n", chan->name);
2746 ast_indicate(caller, AST_CONTROL_BUSY);
2750 } else if (f->subclass.integer == AST_CONTROL_ANSWER) {
2751 /* This is what we are hoping for */
2752 state = f->subclass.integer;
2757 } else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
2758 if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) {
2759 ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
2761 } else if (f->subclass.integer == AST_CONTROL_REDIRECTING) {
2762 if (ast_channel_redirecting_macro(chan, caller, f, 1, 1)) {
2763 ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
2765 } else if (f->subclass.integer != -1 && f->subclass.integer != AST_CONTROL_PROGRESS) {
2766 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass.integer);
2768 /* else who cares */
2769 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2770 ast_write(caller, f);
2773 } else if (caller && (active_channel == caller)) {
2774 f = ast_read(caller);
2775 if (f == NULL) { /*doh! where'd he go?*/
2776 if (!igncallerstate) {
2777 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2778 /* make this a blind transfer */
2782 state = AST_CONTROL_HANGUP;
2788 if (f->frametype == AST_FRAME_DTMF) {
2789 dialed_code[x++] = f->subclass.integer;
2790 dialed_code[x] = '\0';
2791 if (strlen(dialed_code) == len) {
2793 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2795 dialed_code[x] = '\0';
2797 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2798 /* Caller Canceled the call */
2799 state = AST_CONTROL_UNHOLD;
2804 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2813 ast_poll_channel_del(caller, chan);
2816 ast_indicate(caller, -1);
2817 if (chan && ready) {
2818 if (chan->_state == AST_STATE_UP)
2819 state = AST_CONTROL_ANSWER;
2835 void ast_channel_log(char *title, struct ast_channel *chan);
2837 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
2839 ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long)chan);
2840 ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
2841 chan->name, chan->appl, chan->data, chan->context, chan->exten, chan->priority);
2842 ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
2843 chan->accountcode, chan->dialcontext, chan->amaflags, chan->macrocontext, chan->macroexten, chan->macropriority);
2844 ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; _bridge: %p; uniqueID: %s; linkedID:%s\n",
2845 chan->masq, chan->masqr,
2846 chan->_bridge, chan->uniqueid, chan->linkedid);
2848 ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
2849 chan->masqr->name, chan->masqr->cdr);
2851 ast_log(LOG_NOTICE, "CHAN: Bridged to %s\n", chan->_bridge->name);
2853 ast_log(LOG_NOTICE, "===== done ====\n");
2857 * \brief return the first unlocked cdr in a possible chain
2859 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2861 struct ast_cdr *cdr_orig = cdr;
2863 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2867 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2870 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2872 const char *feature;
2874 if (ast_strlen_zero(features)) {
2878 for (feature = features; *feature; feature++) {
2882 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2886 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2890 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2894 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2897 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2902 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2904 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2905 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2907 ast_channel_lock(caller);
2908 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2909 ast_channel_unlock(caller);
2910 if (!ds_caller_features) {
2911 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2912 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2915 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2916 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2917 ast_datastore_free(ds_caller_features);
2920 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2921 caller_features->is_caller = 1;
2922 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2923 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2924 ds_caller_features->data = caller_features;
2925 ast_channel_lock(caller);
2926 ast_channel_datastore_add(caller, ds_caller_features);
2927 ast_channel_unlock(caller);
2929 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2930 * flags over from the atxfer to the caller */
2934 ast_channel_lock(callee);
2935 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2936 ast_channel_unlock(callee);
2937 if (!ds_callee_features) {
2938 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2939 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2942 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2943 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2944 ast_datastore_free(ds_callee_features);
2947 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2948 callee_features->is_caller = 0;
2949 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2950 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2951 ds_callee_features->data = callee_features;
2952 ast_channel_lock(callee);
2953 ast_channel_datastore_add(callee, ds_callee_features);
2954 ast_channel_unlock(callee);
2961 * \brief bridge the call and set CDR
2962 * \param chan,peer,config
2964 * Set start time, check for two channels,check if monitor on
2965 * check for feature activation, create new CDR
2966 * \retval res on success.
2967 * \retval -1 on failure to bridge.
2969 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2971 /* Copy voice back and forth between the two channels. Give the peer
2972 the ability to transfer calls with '#<extension' syntax. */
2973 struct ast_frame *f;
2974 struct ast_channel *who;
2975 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2976 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2977 char orig_channame[AST_MAX_EXTENSION];
2978 char orig_peername[AST_MAX_EXTENSION];
2984 struct ast_option_header *aoh;
2985 struct ast_cdr *bridge_cdr = NULL;
2986 struct ast_cdr *orig_peer_cdr = NULL;
2987 struct ast_cdr *chan_cdr = chan->cdr; /* the proper chan cdr, if there are forked cdrs */
2988 struct ast_cdr *peer_cdr = peer->cdr; /* the proper chan cdr, if there are forked cdrs */
2989 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2990 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2993 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2994 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2996 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2999 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
3000 add_features_datastores(chan, peer, config);
3002 /* This is an interesting case. One example is if a ringing channel gets redirected to
3003 * an extension that picks up a parked call. This will make sure that the call taken
3004 * out of parking gets told that the channel it just got bridged to is still ringing. */
3005 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
3006 ast_indicate(peer, AST_CONTROL_RINGING);
3010 const char *monitor_exec;
3011 struct ast_channel *src = NULL;
3013 if (!(monitor_app = pbx_findapp("Monitor")))
3016 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
3018 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
3020 if (monitor_app && src) {
3021 char *tmp = ast_strdupa(monitor_exec);
3022 pbx_exec(src, monitor_app, tmp);
3026 set_config_flags(chan, peer, config);
3028 /* Answer if need be */
3029 if (chan->_state != AST_STATE_UP) {
3030 if (ast_raw_answer(chan, 1)) {
3036 /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
3037 ast_channel_log("Pre-bridge CHAN Channel info", chan);
3038 ast_channel_log("Pre-bridge PEER Channel info", peer);
3040 /* two channels are being marked as linked here */
3041 ast_channel_set_linkgroup(chan,peer);
3043 /* copy the userfield from the B-leg to A-leg if applicable */
3044 if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
3046 if (!ast_strlen_zero(chan->cdr->userfield)) {
3047 snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
3048 ast_cdr_appenduserfield(chan, tmp);
3050 ast_cdr_setuserfield(chan, peer->cdr->userfield);
3051 /* free the peer's cdr without ast_cdr_free complaining */
3052 ast_free(peer->cdr);
3055 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
3056 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
3057 orig_peer_cdr = peer_cdr;
3059 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
3062 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
3063 ast_cdr_update(chan);
3064 bridge_cdr = ast_cdr_dup_unique_swap(chan_cdr);
3065 /* rip any forked CDR's off of the chan_cdr and attach
3066 * them to the bridge_cdr instead */
3067 bridge_cdr->next = chan_cdr->next;
3068 chan_cdr->next = NULL;
3069 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
3070 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
3071 if (peer_cdr && !ast_strlen_zero(peer_cdr->userfield)) {
3072 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
3074 ast_cdr_setaccount(peer, chan->accountcode);
3077 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
3078 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
3079 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
3080 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
3081 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
3082 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
3083 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
3084 ast_cdr_setcid(bridge_cdr, chan);
3085 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
3086 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
3087 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
3088 /* Destination information */
3089 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
3090 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
3092 bridge_cdr->start = peer_cdr->start;
3093 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
3095 ast_cdr_start(bridge_cdr);
3098 ast_debug(4,"bridge answer set, chan answer set\n");
3099 /* peer_cdr->answer will be set when a macro runs on the peer;
3100 in that case, the bridge answer will be delayed while the
3101 macro plays on the peer channel. The peer answered the call
3102 before the macro started playing. To the phone system,
3103 this is billable time for the call, even tho the caller
3104 hears nothing but ringing while the macro does its thing. */
3106 /* Another case where the peer cdr's time will be set, is when
3107 A self-parks by pickup up phone and dialing 700, then B
3108 picks up A by dialing its parking slot; there may be more
3109 practical paths that get the same result, tho... in which
3110 case you get the previous answer time from the Park... which
3111 is before the bridge's start time, so I added in the
3112 tvcmp check to the if below */
3114 if (peer_cdr && !ast_tvzero(peer_cdr->answer) && ast_tvcmp(peer_cdr->answer, bridge_cdr->start) >= 0) {
3115 ast_cdr_setanswer(bridge_cdr, peer_cdr->answer);
3116 ast_cdr_setdisposition(bridge_cdr, peer_cdr->disposition);
3118 ast_cdr_setanswer(chan_cdr, peer_cdr->answer);
3119 ast_cdr_setdisposition(chan_cdr, peer_cdr->disposition);
3122 ast_cdr_answer(bridge_cdr);
3124 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
3127 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
3129 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
3132 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
3135 /* the DIALED flag may be set if a dialed channel is transfered
3136 * and then bridged to another channel. In order for the
3137 * bridge CDR to be written, the DIALED flag must not be
3139 ast_clear_flag(bridge_cdr, AST_CDR_FLAG_DIALED);
3141 ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, NULL);
3143 struct ast_channel *other; /* used later */
3145 res = ast_channel_bridge(chan, peer, config, &f, &who);
3147 /* When frame is not set, we are probably involved in a situation
3148 where we've timed out.
3149 When frame is set, we'll come this code twice; once for DTMF_BEGIN
3150 and also for DTMF_END. If we flow into the following 'if' for both, then
3151 our wait times are cut in half, as both will subtract from the
3152 feature_timer. Not good!
3154 if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
3155 /* Update feature timer for next pass */
3156 diff = ast_tvdiff_ms(ast_tvnow(), config->feature_start_time);
3157 if (res == AST_BRIDGE_RETRY) {
3158 /* The feature fully timed out but has not been updated. Skip
3159 * the potential round error from the diff calculation and
3160 * explicitly set to expired. */
3161 config->feature_timer = -1;
3163 config->feature_timer -= diff;
3167 if (config->feature_timer <= 0) {
3168 /* Not *really* out of time, just out of time for
3169 digits to come in for features. */
3170 ast_debug(1, "Timed out for feature!\n");
3171 if (!ast_strlen_zero(peer_featurecode)) {
3172 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
3173 memset(peer_featurecode, 0, sizeof(peer_featurecode));
3175 if (!ast_strlen_zero(chan_featurecode)) {
3176 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
3177 memset(chan_featurecode, 0, sizeof(chan_featurecode));
3181 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
3183 /* No more digits expected - reset the timer */
3184 config->feature_timer = 0;
3186 hadfeatures = hasfeatures;
3187 /* Continue as we were */
3190 /* The bridge returned without a frame and there is a feature in progress.
3191 * However, we don't think the feature has quite yet timed out, so just
3192 * go back into the bridge. */
3196 if (config->feature_timer <=0) {
3197 /* We ran out of time */
3198 config->feature_timer = 0;
3208 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer)) {
3209 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
3214 if (!f || (f->frametype == AST_FRAME_CONTROL &&
3215 (f->subclass.integer == AST_CONTROL_HANGUP || f->subclass.integer == AST_CONTROL_BUSY ||
3216 f->subclass.integer == AST_CONTROL_CONGESTION))) {
3220 /* many things should be sent to the 'other' channel */
3221 other = (who == chan) ? peer : chan;
3222 if (f->frametype == AST_FRAME_CONTROL) {
3223 switch (f->subclass.integer) {
3224 case AST_CONTROL_RINGING:
3225 case AST_CONTROL_FLASH:
3227 ast_indicate(other, f->subclass.integer);
3229 case AST_CONTROL_CONNECTED_LINE:
3230 if (!ast_channel_connected_line_macro(who, other, f, who != chan, 1)) {
3233 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
3235 case AST_CONTROL_REDIRECTING:
3236 if (!ast_channel_redirecting_macro(who, other, f, who != chan, 1)) {
3239 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
3241 case AST_CONTROL_AOC:
3242 case AST_CONTROL_HOLD:
3243 case AST_CONTROL_UNHOLD:
3244 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
3246 case AST_CONTROL_OPTION:
3248 /* Forward option Requests */
3249 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
3250 ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
3251 f->datalen - sizeof(struct ast_option_header), 0);
3255 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
3257 } else if (f->frametype == AST_FRAME_DTMF) {
3261 hadfeatures = hasfeatures;
3262 /* This cannot overrun because the longest feature is one shorter than our buffer */
3264 sense = FEATURE_SENSE_CHAN;
3265 featurecode = chan_featurecode;
3267 sense = FEATURE_SENSE_PEER;
3268 featurecode = peer_featurecode;
3270 /*! append the event to featurecode. we rely on the string being zero-filled, and
3271 * not overflowing it.
3272 * \todo XXX how do we guarantee the latter ?
3274 featurecode[strlen(featurecode)] = f->subclass.integer;
3275 /* Get rid of the frame before we start doing "stuff" with the channels */
3278 config->feature_timer = 0;
3279 res = feature_interpret(chan, peer, config, featurecode, sense);
3281 case AST_FEATURE_RETURN_PASSDIGITS:
3282 ast_dtmf_stream(other, who, featurecode, 0, 0);
3284 case AST_FEATURE_RETURN_SUCCESS:
3285 memset(featurecode, 0, sizeof(chan_featurecode));
3288 if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
3293 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
3294 if (hadfeatures && !hasfeatures) {
3295 /* Feature completed or timed out */
3296 config->feature_timer = 0;
3297 } else if (hasfeatures) {
3298 if (config->timelimit) {
3299 /* No warning next time - we are waiting for future */
3300 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
3302 config->feature_start_time = ast_tvnow();
3303 config->feature_timer = featuredigittimeout;
3304 ast_debug(1, "Set feature timer to %ld\n", config->feature_timer);
3311 ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, NULL);
3314 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
3315 ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
3317 ast_cdr_discard(bridge_cdr);
3318 /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
3320 return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
3323 if (config->end_bridge_callback) {
3324 config->end_bridge_callback(config->end_bridge_callback_data);
3327 /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
3328 * if it were, then chan belongs to a different thread now, and might have been hung up long
3331 if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
3332 ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
3333 struct ast_cdr *swapper = NULL;
3334 char savelastapp[AST_MAX_EXTENSION];
3335 char savelastdata[AST_MAX_EXTENSION];
3336 char save_exten[AST_MAX_EXTENSION];
3338 int found = 0; /* set if we find at least one match */
3339 int spawn_error = 0;
3341 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
3342 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
3343 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
3344 ast_cdr_end(bridge_cdr);
3346 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
3347 dialplan code operate on it */
3348 ast_channel_lock(chan);
3350 swapper = chan->cdr;
3351 ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
3352 ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
3353 chan->cdr = bridge_cdr;
3355 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
3356 save_prio = chan->priority;
3357 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
3359 ast_channel_unlock(chan);
3360 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
3363 if (spawn_error && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num) || ast_check_hangup(chan))) {
3364 /* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
3367 if (found && spawn_error) {
3368 /* Something bad happened, or a hangup has been requested. */
3369 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
3370 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
3373 ast_channel_lock(chan);
3374 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
3375 chan->priority = save_prio;
3377 if (chan->cdr == bridge_cdr) {
3378 chan->cdr = swapper;
3384 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
3386 ast_channel_unlock(chan);
3387 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
3389 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
3390 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
3392 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
3395 /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */