2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Routines implementing call features as call pickup, parking and transfer
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30 #include "asterisk/_private.h"
34 #include <sys/signal.h>
35 #include <netinet/in.h>
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/app.h"
45 #include "asterisk/say.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/config.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/adsi.h"
53 #include "asterisk/devicestate.h"
54 #include "asterisk/monitor.h"
55 #include "asterisk/audiohook.h"
56 #include "asterisk/global_datastores.h"
57 #include "asterisk/astobj2.h"
58 #include "asterisk/cel.h"
59 #include "asterisk/test.h"
62 <application name="Bridge" language="en_US">
67 <parameter name="channel" required="true">
68 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
70 <parameter name="options">
73 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
76 <para>Allow the called party to hang up by sending the
77 <replaceable>*</replaceable> DTMF digit.</para>
80 <para>Allow the calling party to hang up by pressing the
81 <replaceable>*</replaceable> DTMF digit.</para>
84 <para>Allow the called party to enable parking of the call by sending
85 the DTMF sequence defined for call parking in features.conf.</para>
88 <para>Allow the calling party to enable parking of the call by sending
89 the DTMF sequence defined for call parking in features.conf.</para>
91 <option name="L(x[:y][:z])">
92 <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
93 when <replaceable>y</replaceable> ms are left. Repeat the warning every
94 <replaceable>z</replaceable> ms. The following special variables can be
95 used with this option:</para>
97 <variable name="LIMIT_PLAYAUDIO_CALLER">
98 <para>Play sounds to the caller. yes|no (default yes)</para>
100 <variable name="LIMIT_PLAYAUDIO_CALLEE">
101 <para>Play sounds to the callee. yes|no</para>
103 <variable name="LIMIT_TIMEOUT_FILE">
104 <para>File to play when time is up.</para>
106 <variable name="LIMIT_CONNECT_FILE">
107 <para>File to play when call begins.</para>
109 <variable name="LIMIT_WARNING_FILE">
110 <para>File to play as warning if <replaceable>y</replaceable> is
111 defined. The default is to say the time remaining.</para>
116 <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
119 <para>Allow the called party to transfer the calling party by sending the
120 DTMF sequence defined in features.conf.</para>
123 <para>Allow the calling party to transfer the called party by sending the
124 DTMF sequence defined in features.conf.</para>
127 <para>Allow the called party to enable recording of the call by sending
128 the DTMF sequence defined for one-touch recording in features.conf.</para>
131 <para>Allow the calling party to enable recording of the call by sending
132 the DTMF sequence defined for one-touch recording in features.conf.</para>
135 <para>Cause the called party to be hung up after the bridge, instead of being
136 restarted in the dialplan.</para>
142 <para>Allows the ability to bridge two channels via the dialplan.</para>
143 <para>This application sets the following channel variable upon completion:</para>
145 <variable name="BRIDGERESULT">
146 <para>The result of the bridge attempt as a text string.</para>
147 <value name="SUCCESS" />
148 <value name="FAILURE" />
149 <value name="LOOP" />
150 <value name="NONEXISTENT" />
151 <value name="INCOMPATIBLE" />
156 <application name="ParkedCall" language="en_US">
158 Answer a parked call.
161 <parameter name="exten" required="true" />
164 <para>Used to connect to a parked call. This application is always
165 registered internally and does not need to be explicitly added
166 into the dialplan, although you should include the <literal>parkedcalls</literal>
167 context. If no extension is provided, then the first available
168 parked call will be acquired.</para>
171 <ref type="application">Park</ref>
172 <ref type="application">ParkAndAnnounce</ref>
175 <application name="Park" language="en_US">
180 <parameter name="timeout">
181 <para>A custom parking timeout for this parked call.</para>
183 <parameter name="return_context">
184 <para>The context to return the call to after it times out.</para>
186 <parameter name="return_exten">
187 <para>The extension to return the call to after it times out.</para>
189 <parameter name="return_priority">
190 <para>The priority to return the call to after it times out.</para>
192 <parameter name="options">
193 <para>A list of options for this parked call.</para>
196 <para>Send ringing instead of MOH to the parked call.</para>
199 <para>Randomize the selection of a parking space.</para>
202 <para>Silence announcement of the parking space number.</para>
208 <para>Used to park yourself (typically in combination with a supervised
209 transfer to know the parking space). This application is always
210 registered internally and does not need to be explicitly added
211 into the dialplan, although you should include the <literal>parkedcalls</literal>
212 context (or the context specified in <filename>features.conf</filename>).</para>
213 <para>If you set the <variable>PARKINGLOT</variable> variable, the call will be parked
214 in the specifed parking context. Note setting this variable overrides the <variable>
215 PARKINGLOT</variable> set by the <literal>CHANNEL</literal> function.</para>
216 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
217 parking context, Park() will park the call on that extension, unless
218 it already exists. In that case, execution will continue at next priority.</para>
219 <para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
220 in that parkinglot.</para>
221 <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
222 will be used as template for the newly created dynamic lot.</para>
223 <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
224 parking lot will use this context.</para>
225 <para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
226 will use those parking postitions.</para>
229 <ref type="application">ParkAndAnnounce</ref>
230 <ref type="application">ParkedCall</ref>
233 <manager name="ParkedCalls" language="en_US">
238 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
241 <para>List parked calls.</para>
244 <manager name="Park" language="en_US">
249 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
250 <parameter name="Channel" required="true">
251 <para>Channel name to park.</para>
253 <parameter name="Channel2" required="true">
254 <para>Channel to announce park info to (and return to if timeout).</para>
256 <parameter name="Timeout">
257 <para>Number of milliseconds to wait before callback.</para>
261 <para>Park a channel.</para>
264 <manager name="Bridge" language="en_US">
266 Bridge two channels already in the PBX.
269 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
270 <parameter name="Channel1" required="true">
271 <para>Channel to Bridge to Channel2.</para>
273 <parameter name="Channel2" required="true">
274 <para>Channel to Bridge to Channel1.</para>
276 <parameter name="Tone">
277 <para>Play courtesy tone to Channel 2.</para>
285 <para>Bridge together two channels already in the PBX.</para>
290 #define DEFAULT_PARK_TIME 45000
291 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
292 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000
293 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
294 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
295 #define DEFAULT_ATXFER_DROP_CALL 0
296 #define DEFAULT_ATXFER_LOOP_DELAY 10000
297 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
299 #define AST_MAX_WATCHERS 256
300 #define MAX_DIAL_FEATURE_OPTIONS 30
302 struct feature_group_exten {
303 AST_LIST_ENTRY(feature_group_exten) entry;
304 AST_DECLARE_STRING_FIELDS(
305 AST_STRING_FIELD(exten);
307 struct ast_call_feature *feature;
310 struct feature_group {
311 AST_LIST_ENTRY(feature_group) entry;
312 AST_DECLARE_STRING_FIELDS(
313 AST_STRING_FIELD(gname);
315 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
318 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
320 static char *parkedcall = "ParkedCall";
322 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
324 /*! \brief Description of one parked call, added to a list while active, then removed.
325 The list belongs to a parkinglot
328 struct ast_channel *chan; /*!< Parking channel */
329 struct timeval start; /*!< Time the parking started */
330 int parkingnum; /*!< Parking lot */
331 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
332 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
333 char exten[AST_MAX_EXTENSION];
335 int parkingtime; /*!< Maximum length in parking lot before return */
336 unsigned int notquiteyet:1;
337 unsigned int options_specified:1;
339 unsigned char moh_trys;
340 struct ast_parkinglot *parkinglot;
341 AST_LIST_ENTRY(parkeduser) list;
344 /*! \brief Structure for parking lots which are put in a container. */
345 struct ast_parkinglot {
346 char name[AST_MAX_CONTEXT];
347 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
348 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
349 int parking_start; /*!< First available extension for parking */
350 int parking_stop; /*!< Last available extension for parking */
353 int parkingtime; /*!< Default parking time */
354 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
355 int parkaddhints; /*!< Add parking hints automatically */
356 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
357 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
358 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
359 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
360 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
363 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
364 static struct ao2_container *parkinglots;
366 struct ast_parkinglot *default_parkinglot;
367 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
369 static char courtesytone[256]; /*!< Courtesy tone */
370 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
371 static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
372 static char xfersound[256]; /*!< Call transfer sound */
373 static char xferfailsound[256]; /*!< Call transfer failure sound */
374 static char pickupsound[256]; /*!< Pickup sound */
375 static char pickupfailsound[256]; /*!< Pickup failure sound */
379 static int transferdigittimeout;
380 static int featuredigittimeout;
381 static int comebacktoorigin = 1;
383 static int atxfernoanswertimeout;
384 static unsigned int atxferdropcall;
385 static unsigned int atxferloopdelay;
386 static unsigned int atxfercallbackretries;
388 static char *registrar = "features"; /*!< Registrar for operations */
390 /* module and CLI command definitions */
391 static char *parkcall = PARK_APP_NAME;
393 static struct ast_app *monitor_app = NULL;
394 static int monitor_ok = 1;
396 static struct ast_app *mixmonitor_app = NULL;
397 static int mixmonitor_ok = 1;
399 static struct ast_app *stopmixmonitor_app = NULL;
400 static int stopmixmonitor_ok = 1;
402 static pthread_t parking_thread;
403 struct ast_dial_features {
404 struct ast_flags features_caller;
405 struct ast_flags features_callee;
409 static void *dial_features_duplicate(void *data)
411 struct ast_dial_features *df = data, *df_copy;
413 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
417 memcpy(df_copy, df, sizeof(*df));
422 static void dial_features_destroy(void *data)
424 struct ast_dial_features *df = data;
430 static const struct ast_datastore_info dial_features_info = {
431 .type = "dial-features",
432 .destroy = dial_features_destroy,
433 .duplicate = dial_features_duplicate,
436 /* Forward declarations */
437 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
438 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
439 static void parkinglot_destroy(void *obj);
440 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
441 struct ast_parkinglot *find_parkinglot(const char *name);
442 static struct ast_parkinglot *create_parkinglot(const char *name);
443 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
445 const char *ast_parking_ext(void)
450 const char *ast_pickup_ext(void)
455 struct ast_bridge_thread_obj
457 struct ast_bridge_config bconfig;
458 struct ast_channel *chan;
459 struct ast_channel *peer;
460 unsigned int return_to_pbx:1;
463 static int parkinglot_hash_cb(const void *obj, const int flags)
465 const struct ast_parkinglot *parkinglot = obj;
467 return ast_str_case_hash(parkinglot->name);
470 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
472 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
474 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
478 * \brief store context, extension and priority
479 * \param chan, context, ext, pri
481 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
483 ast_copy_string(chan->context, context, sizeof(chan->context));
484 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
485 chan->priority = pri;
489 * \brief Check goto on transfer
492 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
493 * When found make sure the types are compatible. Check if channel is valid
494 * if so start the new channel else hangup the call.
496 static void check_goto_on_transfer(struct ast_channel *chan)
498 struct ast_channel *xferchan;
499 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
500 char *x, *goto_on_transfer;
503 if (ast_strlen_zero(val))
506 goto_on_transfer = ast_strdupa(val);
508 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", chan->linkedid, 0, "%s", chan->name)))
511 for (x = goto_on_transfer; x && *x; x++) {
515 /* Make formats okay */
516 xferchan->readformat = chan->readformat;
517 xferchan->writeformat = chan->writeformat;
518 ast_channel_masquerade(xferchan, chan);
519 ast_parseable_goto(xferchan, goto_on_transfer);
520 xferchan->_state = AST_STATE_UP;
521 ast_clear_flag(xferchan, AST_FLAGS_ALL);
522 xferchan->_softhangup = 0;
523 if ((f = ast_read(xferchan))) {
526 ast_pbx_start(xferchan);
528 ast_hangup(xferchan);
532 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);
535 * \brief bridge the call
536 * \param data thread bridge.
538 * Set Last Data for respective channels, reset cdr for channels
539 * bridge call, check if we're going back to dialplan
540 * if not hangup both legs of the call
542 static void *bridge_call_thread(void *data)
544 struct ast_bridge_thread_obj *tobj = data;
547 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
548 tobj->chan->data = tobj->peer->name;
549 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
550 tobj->peer->data = tobj->chan->name;
552 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
554 if (tobj->return_to_pbx) {
555 if (!ast_check_hangup(tobj->peer)) {
556 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
557 res = ast_pbx_start(tobj->peer);
558 if (res != AST_PBX_SUCCESS)
559 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
561 ast_hangup(tobj->peer);
562 if (!ast_check_hangup(tobj->chan)) {
563 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
564 res = ast_pbx_start(tobj->chan);
565 if (res != AST_PBX_SUCCESS)
566 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
568 ast_hangup(tobj->chan);
570 ast_hangup(tobj->chan);
571 ast_hangup(tobj->peer);
580 * \brief create thread for the parked call
583 * Create thread and attributes, call bridge_call_thread
585 static void bridge_call_thread_launch(void *data)
589 struct sched_param sched;
591 pthread_attr_init(&attr);
592 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
593 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
594 pthread_attr_destroy(&attr);
595 memset(&sched, 0, sizeof(sched));
596 pthread_setschedparam(thread, SCHED_RR, &sched);
600 * \brief Announce call parking by ADSI
602 * \param parkingexten .
603 * Create message to show for ADSI, display message.
604 * \retval 0 on success.
605 * \retval -1 on failure.
607 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
610 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
612 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
614 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
616 res = ast_adsi_load_session(chan, NULL, 0, 1);
619 return ast_adsi_print(chan, message, justify, 1);
622 /*! \brief Find parking lot name from channel */
623 static const char *findparkinglotname(struct ast_channel *chan)
625 const char *temp, *parkinglot = NULL;
627 /* Check if the channel has a parking lot */
628 if (!ast_strlen_zero(chan->parkinglot))
629 parkinglot = chan->parkinglot;
631 /* Channel variables override everything */
633 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
639 /*! \brief Notify metermaids that we've changed an extension */
640 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
642 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
643 exten, context, ast_devstate2str(state));
645 ast_devstate_changed(state, "park:%s@%s", exten, context);
648 /*! \brief metermaids callback from devicestate.c */
649 static enum ast_device_state metermaidstate(const char *data)
654 context = ast_strdupa(data);
656 exten = strsep(&context, "@");
658 return AST_DEVICE_INVALID;
660 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
662 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
663 return AST_DEVICE_NOT_INUSE;
665 return AST_DEVICE_INUSE;
668 /*! Options to pass to park_call_full */
669 enum ast_park_call_options {
670 /*! Provide ringing to the parked caller instead of music on hold */
671 AST_PARK_OPT_RINGING = (1 << 0),
672 /*! Randomly choose a parking spot for the caller instead of choosing
673 * the first one that is available. */
674 AST_PARK_OPT_RANDOMIZE = (1 << 1),
675 /*! Do not announce the parking number */
676 AST_PARK_OPT_SILENCE = (1 << 2),
679 struct ast_park_call_args {
680 /*! How long to wait in the parking lot before the call gets sent back
681 * to the specified return extension (or a best guess at where it came
682 * from if not explicitly specified). */
684 /*! An output parameter to store the parking space where the parked caller
687 const char *orig_chan_name;
688 const char *return_con;
689 const char *return_ext;
692 /*! Parked user that has already obtained a parking space */
693 struct parkeduser *pu;
696 static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
698 struct parkeduser *pu;
699 int i, parking_space = -1, parking_range;
700 const char *parkinglotname = NULL;
701 const char *parkingexten;
702 struct ast_parkinglot *parkinglot = NULL;
705 parkinglotname = findparkinglotname(peer);
706 else /* peer was NULL, check chan (ParkAndAnnounce / res_agi) */
707 parkinglotname = findparkinglotname(chan);
709 if (parkinglotname) {
710 ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglotname);
711 parkinglot = find_parkinglot(parkinglotname);
715 /* Dynamically create parkinglot */
716 if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
717 const char *dyn_context, *dyn_range;
718 const char *parkinglotname_copy = NULL;
719 struct ast_parkinglot *parkinglot_copy = NULL;
720 int dyn_start, dyn_end;
722 ast_channel_lock(chan);
723 parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
724 dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
725 dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
726 ast_channel_unlock(chan);
728 if (!ast_strlen_zero(parkinglotname_copy)) {
729 parkinglot_copy = find_parkinglot(parkinglotname_copy);
731 if (!parkinglot_copy) {
732 parkinglot_copy = parkinglot_addref(default_parkinglot);
733 ast_debug(1, "Using default parking lot for copy\n");
735 if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
736 ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
738 if (!ast_strlen_zero(dyn_context)) {
739 ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
741 if (!ast_strlen_zero(dyn_range)) {
742 if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
743 ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
745 parkinglot->parking_start = dyn_start;
746 parkinglot->parking_stop = dyn_end;
749 ao2_link(parkinglots, parkinglot);
752 if (parkinglot_copy) {
753 /* unref our tempory copy */
754 parkinglot_unref(parkinglot_copy);
755 parkinglot_copy = NULL;
760 parkinglot = parkinglot_addref(default_parkinglot);
764 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
766 /* Allocate memory for parking data */
767 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
768 parkinglot_unref(parkinglot);
772 /* Lock parking list */
773 AST_LIST_LOCK(&parkinglot->parkings);
774 /* Check for channel variable PARKINGEXTEN */
775 ast_channel_lock(chan);
776 parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
777 ast_channel_unlock(chan);
778 if (!ast_strlen_zero(parkingexten)) {
779 /*!\note The API forces us to specify a numeric parking slot, even
780 * though the architecture would tend to support non-numeric extensions
781 * (as are possible with SIP, for example). Hence, we enforce that
782 * limitation here. If extout was not numeric, we could permit
783 * arbitrary non-numeric extensions.
785 if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space < 0) {
786 AST_LIST_UNLOCK(&parkinglot->parkings);
787 parkinglot_unref(parkinglot);
789 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
792 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
794 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
795 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
796 AST_LIST_UNLOCK(&parkinglot->parkings);
797 parkinglot_unref(parkinglot);
803 struct parkeduser *cur = NULL;
805 /* Select parking space within range */
806 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
808 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
809 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
811 start = parkinglot->parking_start;
814 for (i = start; 1; i++) {
815 if (i == parkinglot->parking_stop + 1) {
816 i = parkinglot->parking_start - 1;
820 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
821 if (cur->parkingnum == i) {
831 if (i == start - 1 && cur) {
832 ast_log(LOG_WARNING, "No more parking spaces\n");
834 AST_LIST_UNLOCK(&parkinglot->parkings);
835 parkinglot_unref(parkinglot);
838 /* Set pointer for next parking */
839 if (parkinglot->parkfindnext)
840 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
841 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
845 pu->parkingnum = parking_space;
846 pu->parkinglot = parkinglot_addref(parkinglot);
847 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
848 parkinglot_unref(parkinglot);
854 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
856 struct ast_context *con;
858 struct parkeduser *pu = args->pu;
859 const char *event_from;
862 args->pu = pu = park_space_reserve(chan, peer, args);
864 return 1; /* Continue execution if possible */
866 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
868 chan->appl = "Parked Call";
873 /* Put the parked channel on hold if we have two different channels */
875 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
876 ast_indicate(pu->chan, AST_CONTROL_RINGING);
878 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
879 S_OR(pu->parkinglot->mohclass, NULL),
880 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
884 pu->start = ast_tvnow();
885 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
886 parkingnum_copy = pu->parkingnum;
888 *(args->extout) = pu->parkingnum;
891 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
892 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
893 and we need the callback name to be that of transferer. Since local,1/2 have the same
894 name we can be tricky and just grab the bridged channel from the other side of the local
896 if (!strcasecmp(peer->tech->type, "Local")) {
897 struct ast_channel *tmpchan, *base_peer;
898 char other_side[AST_CHANNEL_NAME];
900 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
901 if ((c = strrchr(other_side, ';'))) {
904 if ((tmpchan = ast_channel_get_by_name(other_side))) {
905 ast_channel_lock(tmpchan);
906 if ((base_peer = ast_bridged_channel(tmpchan))) {
907 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
909 ast_channel_unlock(tmpchan);
910 tmpchan = ast_channel_unref(tmpchan);
913 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
917 /* Remember what had been dialed, so that if the parking
918 expires, we try to come back to the same place */
920 pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
922 /* If extension has options specified, they override all other possibilities
923 such as the returntoorigin flag and transferred context. Information on
924 extension options is lost here, so we set a flag */
926 ast_copy_string(pu->context,
927 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
928 sizeof(pu->context));
929 ast_copy_string(pu->exten,
930 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
932 pu->priority = args->return_pri ? args->return_pri :
933 (chan->macropriority ? chan->macropriority : chan->priority);
935 /* If parking a channel directly, don't quiet yet get parking running on it.
936 * All parking lot entries are put into the parking lot with notquiteyet on. */
940 /* Wake up the (presumably select()ing) thread */
941 pthread_kill(parking_thread, SIGURG);
942 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));
944 ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
947 event_from = peer->name;
949 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
952 ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
958 "CallerIDNum: %s\r\n"
959 "CallerIDName: %s\r\n"
961 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
962 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
963 S_OR(pu->chan->cid.cid_num, "<unknown>"),
964 S_OR(pu->chan->cid.cid_name, "<unknown>"),
968 if (peer && adsipark && ast_adsi_available(peer)) {
969 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
970 ast_adsi_unload_session(peer);
973 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
974 if (!con) /* Still no context? Bad */
975 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
977 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
978 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
981 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
983 /* Only say number if it's a number and the channel hasn't been masqueraded away */
984 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
985 /* 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. */
986 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
987 /* Tell the peer channel the number of the parking space */
988 ast_say_digits(peer, pu->parkingnum, "", peer->language);
989 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
991 if (peer == chan) { /* pu->notquiteyet = 1 */
992 /* Wake up parking thread if we're really done */
993 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
994 S_OR(pu->parkinglot->mohclass, NULL),
995 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
997 pthread_kill(parking_thread, SIGURG);
1002 /*! \brief Park a call */
1003 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
1005 struct ast_park_call_args args = {
1010 return park_call_full(chan, peer, &args);
1013 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)
1015 struct ast_channel *chan;
1016 struct ast_frame *f;
1018 struct ast_park_call_args park_args = {0,};
1022 args->timeout = timeout;
1023 args->extout = extout;
1026 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
1028 ast_stream_and_wait(peer, "beeperr", "");
1029 return AST_FEATURE_RETURN_PARKFAILED;
1032 /* Make a new, fake channel that we'll use to masquerade in the real one */
1033 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))) {
1034 ast_log(LOG_WARNING, "Unable to create parked channel\n");
1038 /* Make formats okay */
1039 chan->readformat = rchan->readformat;
1040 chan->writeformat = rchan->writeformat;
1041 ast_channel_masquerade(chan, rchan);
1043 /* Setup the extensions and such */
1044 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
1046 /* Setup the macro extension and such */
1047 ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
1048 ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
1049 chan->macropriority = rchan->macropriority;
1051 /* Make the masq execute */
1052 if ((f = ast_read(chan)))
1055 if (peer == rchan) {
1059 if (peer && (!play_announcement && args == &park_args)) {
1060 args->orig_chan_name = ast_strdupa(peer->name);
1063 park_status = park_call_full(chan, peer, args);
1064 if (park_status == 1) {
1065 /* would be nice to play "invalid parking extension" */
1073 /* Park call via masqueraded channel */
1074 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1076 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
1079 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
1081 return masq_park_call(rchan, peer, 0, NULL, 1, args);
1084 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1086 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
1089 #ifdef TEST_FRAMEWORK
1090 static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
1095 static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
1097 struct ast_channel *test_channel1;
1098 if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1099 NULL, NULL, 0, 0, "TestChannel1"))) {
1103 /* normally this is done in the channel driver */
1104 test_channel1->nativeformats = AST_FORMAT_GSM;
1105 test_channel1->writeformat = AST_FORMAT_GSM;
1106 test_channel1->rawwriteformat = AST_FORMAT_GSM;
1107 test_channel1->readformat = AST_FORMAT_GSM;
1108 test_channel1->rawreadformat = AST_FORMAT_GSM;
1109 test_channel1->tech = fake_tech;
1111 return test_channel1;
1114 static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
1116 struct ast_context *con;
1117 struct parkeduser *pu_toremove;
1118 args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
1119 AST_LIST_LOCK(&args->pu->parkinglot->parkings);
1120 AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
1121 con = ast_context_find(args->pu->parkinglot->parking_con);
1123 if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
1124 ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
1127 notify_metermaids(args->pu->parkingexten, pu_toremove->parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
1130 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1133 if (pu_toremove == args->pu) {
1134 AST_LIST_REMOVE_CURRENT(list);
1138 AST_LIST_TRAVERSE_SAFE_END;
1139 AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
1141 /* the only way this would be unsafe is if a timeout occurred, which is set at 45 sec */
1145 ast_hangup(toremove);
1149 AST_TEST_DEFINE(features_test)
1151 int saved_parkeddynamic;
1152 struct ast_channel *test_channel1 = NULL;
1153 struct ast_channel *parked_chan = NULL;
1154 struct ast_parkinglot *dynlot = NULL;
1155 struct ast_park_call_args args = {
1156 .timeout = DEFAULT_PARK_TIME,
1161 static const struct ast_channel_tech fake_tech = {
1162 .fixup = fake_fixup, /* silence warning from masquerade */
1165 static const char unique_parkinglot[] = "myuniquetestparkinglot3141592654";
1166 static const char parkinglot_range[] = "750-760";
1170 info->name = "features_test";
1171 info->category = "main/features/";
1172 info->summary = "Features unit test";
1174 "Tests whether parking respects PARKINGLOT settings";
1175 return AST_TEST_NOT_RUN;
1180 /* changing a config option is a bad practice, but must be done in this case */
1181 saved_parkeddynamic = parkeddynamic;
1184 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1185 goto exit_features_test;
1188 ast_test_status_update(test, "Test parking functionality with defaults\n");
1189 if (park_call_full(test_channel1, NULL, &args)) {
1190 goto exit_features_test;
1192 if (unpark_test_channel(test_channel1, &args)) {
1193 goto exit_features_test;
1196 ast_test_status_update(test, "Check that certain parking options are respected\n");
1197 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1198 goto exit_features_test;
1200 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1201 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1202 if (park_call_full(test_channel1, NULL, &args)) {
1203 goto exit_features_test;
1205 /* grab newly created parking lot for destruction in the end */
1206 dynlot = args.pu->parkinglot;
1207 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1208 ast_test_status_update(test, "Parking settings were not respected\n");
1209 goto exit_features_test;
1211 ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
1213 if (unpark_test_channel(test_channel1, &args)) {
1214 goto exit_features_test;
1217 ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
1218 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1219 goto exit_features_test;
1221 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1222 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1223 if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args) == AST_FEATURE_RETURN_PARKFAILED) {
1224 goto exit_features_test;
1226 /* hangup zombie channel */
1227 ast_hangup(test_channel1);
1228 test_channel1 = NULL;
1229 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1230 ast_test_status_update(test, "Parking settings were not respected\n");
1231 goto exit_features_test;
1233 ast_test_status_update(test, "Parking settings for masquerading park verified\n");
1235 /* find the real channel */
1236 parked_chan = ast_channel_get_by_name("TestChannel1");
1237 if (unpark_test_channel(parked_chan, &args)) {
1238 goto exit_features_test;
1245 if (test_channel1) {
1246 ast_hangup(test_channel1);
1249 /* careful, if PARKINGDYNCONTEXT is tested, need to delete context */
1250 ao2_unlink(parkinglots, dynlot);
1251 parkeddynamic = saved_parkeddynamic;
1252 return res ? AST_TEST_FAIL : AST_TEST_PASS;
1258 * \brief set caller and callee according to the direction
1259 * \param caller, callee, peer, chan, sense
1261 * Detect who triggered feature and set callee/caller variables accordingly
1263 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
1264 struct ast_channel *peer, struct ast_channel *chan, int sense)
1266 if (sense == FEATURE_SENSE_PEER) {
1276 * \brief support routing for one touch call parking
1277 * \param chan channel parking call
1278 * \param peer channel to be parked
1279 * \param config unsed
1280 * \param code unused
1281 * \param sense feature options
1284 * Setup channel, set return exten,priority to 's,1'
1285 * answer chan, sleep chan, park call
1287 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1289 struct ast_channel *parker;
1290 struct ast_channel *parkee;
1293 set_peers(&parker, &parkee, peer, chan, sense);
1294 /* we used to set chan's exten and priority to "s" and 1
1295 here, but this generates (in some cases) an invalid
1296 extension, and if "s" exists, could errantly
1297 cause execution of extensions you don't expect. It
1298 makes more sense to let nature take its course
1299 when chan finishes, and let the pbx do its thing
1300 and hang up when the park is over.
1302 if (chan->_state != AST_STATE_UP)
1303 res = ast_answer(chan);
1305 res = ast_safe_sleep(chan, 1000);
1307 if (!res) { /* one direction used to call park_call.... */
1308 res = masq_park_call_announce(parkee, parker, 0, NULL);
1309 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
1315 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1316 other channel during the message, so please don't use this for very long messages
1318 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1320 /* First play for caller, put other channel on auto service */
1321 if (ast_autoservice_start(callee_chan))
1323 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
1324 ast_log(LOG_WARNING, "Failed to play automon message!\n");
1325 ast_autoservice_stop(callee_chan);
1328 if (ast_autoservice_stop(callee_chan))
1330 /* Then play for callee, put other channel on auto service */
1331 if (ast_autoservice_start(caller_chan))
1333 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
1334 ast_log(LOG_WARNING, "Failed to play automon message !\n");
1335 ast_autoservice_stop(caller_chan);
1338 if (ast_autoservice_stop(caller_chan))
1344 * \brief Monitor a channel by DTMF
1345 * \param chan channel requesting monitor
1346 * \param peer channel to be monitored
1349 * \param sense feature options
1352 * Check monitor app enabled, setup channels, both caller/callee chans not null
1353 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
1354 * \retval AST_FEATURE_RETURN_SUCCESS on success.
1355 * \retval -1 on error.
1357 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1359 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1362 struct ast_channel *caller_chan, *callee_chan;
1363 const char *automon_message_start = NULL;
1364 const char *automon_message_stop = NULL;
1367 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1371 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1373 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1377 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1378 if (caller_chan) { /* Find extra messages */
1379 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1380 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1383 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1384 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1389 if (callee_chan->monitor) {
1390 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1391 if (!ast_strlen_zero(automon_message_stop)) {
1392 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1394 callee_chan->monitor->stop(callee_chan, 1);
1395 return AST_FEATURE_RETURN_SUCCESS;
1398 if (caller_chan && callee_chan) {
1399 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1400 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1401 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1404 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1407 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1409 if (!touch_monitor_prefix)
1410 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1412 if (touch_monitor) {
1413 len = strlen(touch_monitor) + 50;
1415 touch_filename = alloca(len);
1416 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1417 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1419 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1420 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1421 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1423 touch_filename = alloca(len);
1424 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1425 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1428 for(x = 0; x < strlen(args); x++) {
1433 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1435 pbx_exec(callee_chan, monitor_app, args);
1436 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1437 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1439 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1440 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1443 return AST_FEATURE_RETURN_SUCCESS;
1446 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1450 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1452 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1455 struct ast_channel *caller_chan, *callee_chan;
1456 const char *mixmonitor_spy_type = "MixMonitor";
1459 if (!mixmonitor_ok) {
1460 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1464 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1466 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1470 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1472 if (!ast_strlen_zero(courtesytone)) {
1473 if (ast_autoservice_start(callee_chan))
1475 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1476 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1477 ast_autoservice_stop(callee_chan);
1480 if (ast_autoservice_stop(callee_chan))
1484 ast_channel_lock(callee_chan);
1485 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1486 ast_channel_unlock(callee_chan);
1488 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1491 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1493 /* Make sure they are running */
1494 ast_channel_lock(callee_chan);
1495 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1496 ast_channel_unlock(callee_chan);
1498 if (!stopmixmonitor_ok) {
1499 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1502 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1503 stopmixmonitor_ok = 0;
1504 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1507 pbx_exec(callee_chan, stopmixmonitor_app, "");
1508 return AST_FEATURE_RETURN_SUCCESS;
1512 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1515 if (caller_chan && callee_chan) {
1516 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1517 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1520 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1523 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1525 if (touch_monitor) {
1526 len = strlen(touch_monitor) + 50;
1528 touch_filename = alloca(len);
1529 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1530 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1532 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1533 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1534 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1536 touch_filename = alloca(len);
1537 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1538 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1541 for( x = 0; x < strlen(args); x++) {
1546 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1548 pbx_exec(callee_chan, mixmonitor_app, args);
1549 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1550 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1551 return AST_FEATURE_RETURN_SUCCESS;
1555 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1560 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1562 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1563 return AST_FEATURE_RETURN_HANGUP;
1566 static int finishup(struct ast_channel *chan)
1568 ast_indicate(chan, AST_CONTROL_UNHOLD);
1570 return ast_autoservice_stop(chan);
1574 * \brief Find the context for the transfer
1578 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1579 * \return a context string
1581 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1583 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1584 if (ast_strlen_zero(s)) {
1585 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1587 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1588 s = transferer->macrocontext;
1590 if (ast_strlen_zero(s)) {
1591 s = transferer->context;
1597 * \brief Blind transfer user to another extension
1598 * \param chan channel to be transfered
1599 * \param peer channel initiated blind transfer
1603 * \param sense feature options
1605 * Place chan on hold, check if transferred to parkinglot extension,
1606 * otherwise check extension exists and transfer caller.
1607 * \retval AST_FEATURE_RETURN_SUCCESS.
1608 * \retval -1 on failure.
1610 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1612 struct ast_channel *transferer;
1613 struct ast_channel *transferee;
1614 const char *transferer_real_context;
1616 int res, parkstatus = 0;
1618 set_peers(&transferer, &transferee, peer, chan, sense);
1619 transferer_real_context = real_ctx(transferer, transferee);
1620 /* Start autoservice on chan while we talk to the originator */
1621 ast_autoservice_start(transferee);
1622 ast_indicate(transferee, AST_CONTROL_HOLD);
1624 memset(xferto, 0, sizeof(xferto));
1627 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1629 finishup(transferee);
1630 return -1; /* error ? */
1632 if (res > 0) /* If they've typed a digit already, handle it */
1633 xferto[0] = (char) res;
1635 ast_stopstream(transferer);
1636 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1637 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1638 finishup(transferee);
1641 if (!strcmp(xferto, ast_parking_ext())) {
1642 res = finishup(transferee);
1645 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1646 /* We return non-zero, but tell the PBX not to hang the channel when
1647 the thread dies -- We have to be careful now though. We are responsible for
1648 hanging up the channel, else it will never be hung up! */
1652 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1654 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1655 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1656 ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
1657 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1658 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1659 res=finishup(transferee);
1660 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1661 transferer->cdr=ast_cdr_alloc();
1662 if (transferer->cdr) {
1663 ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
1664 ast_cdr_start(transferer->cdr);
1667 if (transferer->cdr) {
1668 struct ast_cdr *swap = transferer->cdr;
1669 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1670 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1671 transferer->cdr->channel, transferer->cdr->dstchannel);
1672 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1673 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1674 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1675 /* swap cdrs-- it will save us some time & work */
1676 transferer->cdr = transferee->cdr;
1677 transferee->cdr = swap;
1679 if (!transferee->pbx) {
1680 /* Doh! Use our handy async_goto functions */
1681 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1682 ,transferee->name, xferto, transferer_real_context);
1683 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1684 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1686 /* Set the channel's new extension, since it exists, using transferer context */
1687 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1688 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1689 if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
1690 ast_channel_update_connected_line(transferee, &transferer->connected);
1692 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1694 check_goto_on_transfer(transferer);
1697 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1699 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1700 finishup(transferee);
1703 ast_stopstream(transferer);
1704 res = finishup(transferee);
1706 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1709 return AST_FEATURE_RETURN_SUCCESS;
1713 * \brief make channels compatible
1716 * \retval 0 on success.
1717 * \retval -1 on failure.
1719 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1721 if (ast_channel_make_compatible(c, newchan) < 0) {
1722 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1723 c->name, newchan->name);
1724 ast_hangup(newchan);
1731 * \brief Attended transfer
1732 * \param chan transfered user
1733 * \param peer person transfering call
1736 * \param sense feature options
1739 * Get extension to transfer to, if you cannot generate channel (or find extension)
1740 * return to host channel. After called channel answered wait for hangup of transferer,
1741 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1743 * \return -1 on failure
1745 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1747 struct ast_channel *transferer;
1748 struct ast_channel *transferee;
1749 const char *transferer_real_context;
1750 char xferto[256] = "";
1753 struct ast_channel *newchan;
1754 struct ast_channel *xferchan;
1755 struct ast_bridge_thread_obj *tobj;
1756 struct ast_bridge_config bconfig;
1757 struct ast_frame *f;
1759 struct ast_party_connected_line connected_line;
1760 struct ast_datastore *features_datastore;
1761 struct ast_dial_features *dialfeatures = NULL;
1763 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1764 set_peers(&transferer, &transferee, peer, chan, sense);
1765 transferer_real_context = real_ctx(transferer, transferee);
1766 /* Start autoservice on chan while we talk to the originator */
1767 ast_autoservice_start(transferee);
1768 ast_indicate(transferee, AST_CONTROL_HOLD);
1771 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1773 finishup(transferee);
1776 if (res > 0) /* If they've typed a digit already, handle it */
1777 xferto[0] = (char) res;
1779 /* this is specific of atxfer */
1780 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1781 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1782 finishup(transferee);
1786 ast_log(LOG_WARNING, "Did not read data.\n");
1787 finishup(transferee);
1788 if (ast_stream_and_wait(transferer, "beeperr", ""))
1790 return AST_FEATURE_RETURN_SUCCESS;
1793 /* valid extension, res == 1 */
1794 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1795 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1796 finishup(transferee);
1797 if (ast_stream_and_wait(transferer, "beeperr", ""))
1799 return AST_FEATURE_RETURN_SUCCESS;
1802 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1803 * the different variables for handling this properly with a builtin_atxfer */
1804 if (!strcmp(xferto, ast_parking_ext())) {
1805 finishup(transferee);
1806 return builtin_parkcall(chan, peer, config, code, sense, data);
1810 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1812 /* If we are performing an attended transfer and we have two channels involved then
1813 copy sound file information to play upon attended transfer completion */
1815 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1816 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1818 if (!ast_strlen_zero(chan1_attended_sound)) {
1819 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1821 if (!ast_strlen_zero(chan2_attended_sound)) {
1822 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1826 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1827 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1829 ast_party_connected_line_init(&connected_line);
1830 if (!ast_check_hangup(transferer)) {
1831 /* Transferer is up - old behaviour */
1832 ast_indicate(transferer, -1);
1834 finishup(transferee);
1835 /* any reason besides user requested cancel and busy triggers the failed sound */
1836 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1837 ast_stream_and_wait(transferer, xferfailsound, ""))
1839 if (ast_stream_and_wait(transferer, xfersound, ""))
1840 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1841 return AST_FEATURE_RETURN_SUCCESS;
1844 if (check_compat(transferer, newchan)) {
1845 /* we do mean transferee here, NOT transferer */
1846 finishup(transferee);
1849 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1850 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1851 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1852 /* We need to get the transferer's connected line information copied
1853 * at this point because he is likely to hang up during the bridge with
1854 * newchan. This info will be used down below before bridging the
1855 * transferee and newchan
1857 * As a result, we need to be sure to free this data before returning
1858 * or overwriting it.
1860 ast_channel_lock(transferer);
1861 ast_party_connected_line_copy(&connected_line, &transferer->connected);
1862 ast_channel_unlock(transferer);
1863 res = ast_bridge_call(transferer, newchan, &bconfig);
1864 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1865 ast_hangup(newchan);
1866 if (ast_stream_and_wait(transferer, xfersound, ""))
1867 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1868 finishup(transferee);
1869 transferer->_softhangup = 0;
1870 ast_party_connected_line_free(&connected_line);
1871 return AST_FEATURE_RETURN_SUCCESS;
1874 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
1876 if (check_compat(transferee, newchan)) {
1877 finishup(transferee);
1878 ast_party_connected_line_free(&connected_line);
1881 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1883 if ((ast_autoservice_stop(transferee) < 0)
1884 || (ast_waitfordigit(transferee, 100) < 0)
1885 || (ast_waitfordigit(newchan, 100) < 0)
1886 || ast_check_hangup(transferee)
1887 || ast_check_hangup(newchan)) {
1888 ast_hangup(newchan);
1889 ast_party_connected_line_free(&connected_line);
1892 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
1894 ast_hangup(newchan);
1895 ast_party_connected_line_free(&connected_line);
1898 /* Make formats okay */
1899 xferchan->visible_indication = transferer->visible_indication;
1900 xferchan->readformat = transferee->readformat;
1901 xferchan->writeformat = transferee->writeformat;
1902 ast_channel_masquerade(xferchan, transferee);
1903 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1904 xferchan->_state = AST_STATE_UP;
1905 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1906 xferchan->_softhangup = 0;
1907 if ((f = ast_read(xferchan)))
1909 newchan->_state = AST_STATE_UP;
1910 ast_clear_flag(newchan, AST_FLAGS_ALL);
1911 newchan->_softhangup = 0;
1912 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1913 ast_hangup(xferchan);
1914 ast_hangup(newchan);
1915 ast_party_connected_line_free(&connected_line);
1919 ast_channel_lock(newchan);
1920 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1921 dialfeatures = features_datastore->data;
1923 ast_channel_unlock(newchan);
1926 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1927 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1928 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1929 dialfeatures = NULL;
1932 ast_channel_lock(xferchan);
1933 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1934 dialfeatures = features_datastore->data;
1936 ast_channel_unlock(xferchan);
1939 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1942 tobj->chan = newchan;
1943 tobj->peer = xferchan;
1944 tobj->bconfig = *config;
1946 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1947 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1950 /* Due to a limitation regarding when callerID is set on a Local channel,
1951 * we use the transferer's connected line information here.
1954 /* xferchan is transferee, and newchan is the transfer target
1955 * So...in a transfer, who is the caller and who is the callee?
1957 * When the call is originally made, it is clear who is caller and callee.
1958 * When a transfer occurs, it is my humble opinion that the transferee becomes
1959 * the caller, and the transfer target is the callee.
1961 * The problem is that these macros were set with the intention of the original
1962 * caller and callee taking those roles. A transfer can totally mess things up,
1963 * to be technical. What sucks even more is that you can't effectively change
1964 * the macros in the dialplan during the call from the transferer to the transfer
1965 * target because the transferee is stuck with whatever role he originally had.
1967 * I think the answer here is just to make sure that it is well documented that
1968 * during a transfer, the transferee is the "caller" and the transfer target
1971 * This means that if party A calls party B, and party A transfers party B to
1972 * party C, then B has switched roles for the call. Now party B will have the
1973 * caller macro called on his channel instead of the callee macro.
1975 * Luckily, the method by which the bridge is launched here ensures that the
1976 * transferee is the "chan" on the bridge and the transfer target is the "peer,"
1977 * so my idea for the roles post-transfer does not require extensive code changes.
1979 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1980 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1981 ast_channel_update_connected_line(xferchan, &connected_line);
1983 ast_channel_lock(xferchan);
1984 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1985 ast_channel_unlock(xferchan);
1986 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1987 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1988 ast_channel_update_connected_line(newchan, &connected_line);
1990 ast_party_connected_line_free(&connected_line);
1992 if (ast_stream_and_wait(newchan, xfersound, ""))
1993 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1994 bridge_call_thread_launch(tobj);
1995 return -1; /* XXX meaning the channel is bridged ? */
1996 } else if (!ast_check_hangup(transferee)) {
1997 /* act as blind transfer */
1998 if (ast_autoservice_stop(transferee) < 0) {
1999 ast_hangup(newchan);
2004 unsigned int tries = 0;
2005 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
2007 transferer_tech = strsep(&transferer_name, "/");
2008 transferer_name = strsep(&transferer_name, "-");
2010 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
2011 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
2012 if (ast_stream_and_wait(transferee, "beeperr", ""))
2014 return AST_FEATURE_RETURN_SUCCESS;
2017 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
2018 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
2019 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
2020 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
2021 /* Trying to transfer again */
2022 ast_autoservice_start(transferee);
2023 ast_indicate(transferee, AST_CONTROL_HOLD);
2025 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
2026 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
2027 if (ast_autoservice_stop(transferee) < 0) {
2029 ast_hangup(newchan);
2033 /* Transfer failed, sleeping */
2034 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
2035 ast_safe_sleep(transferee, atxferloopdelay);
2036 ast_debug(1, "Trying to callback...\n");
2037 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
2038 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
2046 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
2048 /* newchan is up, we should prepare transferee and bridge them */
2049 if (check_compat(transferee, newchan)) {
2050 finishup(transferee);
2053 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2055 if ((ast_waitfordigit(transferee, 100) < 0)
2056 || (ast_waitfordigit(newchan, 100) < 0)
2057 || ast_check_hangup(transferee)
2058 || ast_check_hangup(newchan)) {
2059 ast_hangup(newchan);
2063 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
2065 ast_hangup(newchan);
2068 /* Make formats okay */
2069 xferchan->visible_indication = transferer->visible_indication;
2070 xferchan->readformat = transferee->readformat;
2071 xferchan->writeformat = transferee->writeformat;
2072 ast_channel_masquerade(xferchan, transferee);
2073 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
2074 xferchan->_state = AST_STATE_UP;
2075 ast_clear_flag(xferchan, AST_FLAGS_ALL);
2076 xferchan->_softhangup = 0;
2077 if ((f = ast_read(xferchan)))
2079 newchan->_state = AST_STATE_UP;
2080 ast_clear_flag(newchan, AST_FLAGS_ALL);
2081 newchan->_softhangup = 0;
2082 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
2083 ast_hangup(xferchan);
2084 ast_hangup(newchan);
2087 tobj->chan = newchan;
2088 tobj->peer = xferchan;
2089 tobj->bconfig = *config;
2091 if (tobj->bconfig.end_bridge_callback_data_fixup) {
2092 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
2095 ast_channel_lock(newchan);
2096 ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
2097 ast_channel_unlock(newchan);
2098 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2099 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
2100 ast_channel_update_connected_line(xferchan, &connected_line);
2102 ast_channel_lock(xferchan);
2103 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
2104 ast_channel_unlock(xferchan);
2105 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2106 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
2107 ast_channel_update_connected_line(newchan, &connected_line);
2110 ast_party_connected_line_free(&connected_line);
2112 if (ast_stream_and_wait(newchan, xfersound, ""))
2113 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2114 bridge_call_thread_launch(tobj);
2115 return -1; /* XXX meaning the channel is bridged ? */
2117 /* Transferee hung up */
2118 finishup(transferee);
2123 /* add atxfer and automon as undefined so you can only use em if you configure them */
2124 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
2126 AST_RWLOCK_DEFINE_STATIC(features_lock);
2128 static struct ast_call_feature builtin_features[] = {
2129 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2130 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2131 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2132 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2133 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2134 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2138 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
2140 /*! \brief register new feature into feature_list*/
2141 void ast_register_feature(struct ast_call_feature *feature)
2144 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
2148 AST_RWLIST_WRLOCK(&feature_list);
2149 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
2150 AST_RWLIST_UNLOCK(&feature_list);
2152 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
2156 * \brief Add new feature group
2157 * \param fgname feature group name.
2159 * Add new feature group to the feature group list insert at head of list.
2160 * \note This function MUST be called while feature_groups is locked.
2162 static struct feature_group* register_group(const char *fgname)
2164 struct feature_group *fg;
2167 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
2171 if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128)))
2174 ast_string_field_set(fg, gname, fgname);
2176 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
2178 ast_verb(2, "Registered group '%s'\n", fg->gname);
2184 * \brief Add feature to group
2185 * \param fg feature group
2187 * \param feature feature to add.
2189 * Check fg and feature specified, add feature to list
2190 * \note This function MUST be called while feature_groups is locked.
2192 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
2194 struct feature_group_exten *fge;
2197 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
2202 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
2206 if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128)))
2209 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
2211 fge->feature = feature;
2213 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
2215 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
2216 feature->sname, fg->gname, exten);
2219 void ast_unregister_feature(struct ast_call_feature *feature)
2225 AST_RWLIST_WRLOCK(&feature_list);
2226 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
2227 AST_RWLIST_UNLOCK(&feature_list);
2232 /*! \brief Remove all features in the list */
2233 static void ast_unregister_features(void)
2235 struct ast_call_feature *feature;
2237 AST_RWLIST_WRLOCK(&feature_list);
2238 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
2241 AST_RWLIST_UNLOCK(&feature_list);
2244 /*! \brief find a call feature by name */
2245 static struct ast_call_feature *find_dynamic_feature(const char *name)
2247 struct ast_call_feature *tmp;
2249 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
2250 if (!strcasecmp(tmp->sname, name)) {
2258 /*! \brief Remove all feature groups in the list */
2259 static void ast_unregister_groups(void)
2261 struct feature_group *fg;
2262 struct feature_group_exten *fge;
2264 AST_RWLIST_WRLOCK(&feature_groups);
2265 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
2266 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
2267 ast_string_field_free_memory(fge);
2271 ast_string_field_free_memory(fg);
2274 AST_RWLIST_UNLOCK(&feature_groups);
2278 * \brief Find a group by name
2279 * \param name feature name
2280 * \retval feature group on success.
2281 * \retval NULL on failure.
2283 static struct feature_group *find_group(const char *name) {
2284 struct feature_group *fg = NULL;
2286 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
2287 if (!strcasecmp(fg->gname, name))
2294 void ast_rdlock_call_features(void)
2296 ast_rwlock_rdlock(&features_lock);
2299 void ast_unlock_call_features(void)
2301 ast_rwlock_unlock(&features_lock);
2304 struct ast_call_feature *ast_find_call_feature(const char *name)
2307 for (x = 0; x < FEATURES_COUNT; x++) {
2308 if (!strcasecmp(name, builtin_features[x].sname))
2309 return &builtin_features[x];
2315 * \brief exec an app by feature
2316 * \param chan,peer,config,code,sense,data
2318 * Find a feature, determine which channel activated
2319 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
2321 * \retval -2 when an application cannot be found.
2323 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)
2325 struct ast_app *app;
2326 struct ast_call_feature *feature = data;
2327 struct ast_channel *work, *idle;
2330 if (!feature) { /* shouldn't ever happen! */
2331 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
2335 if (sense == FEATURE_SENSE_CHAN) {
2336 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2337 return AST_FEATURE_RETURN_KEEPTRYING;
2338 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2346 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2347 return AST_FEATURE_RETURN_KEEPTRYING;
2348 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2357 if (!(app = pbx_findapp(feature->app))) {
2358 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
2362 ast_autoservice_start(idle);
2365 pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", idle->name);
2366 pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", work->name);
2367 pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
2368 pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
2371 if (!ast_strlen_zero(feature->moh_class))
2372 ast_moh_start(idle, feature->moh_class, NULL);
2374 res = pbx_exec(work, app, feature->app_args);
2376 if (!ast_strlen_zero(feature->moh_class))
2379 ast_autoservice_stop(idle);
2382 return AST_FEATURE_RETURN_SUCCESSBREAK;
2384 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
2387 static void unmap_features(void)
2391 ast_rwlock_wrlock(&features_lock);
2392 for (x = 0; x < FEATURES_COUNT; x++)
2393 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
2394 ast_rwlock_unlock(&features_lock);
2397 static int remap_feature(const char *name, const char *value)
2401 ast_rwlock_wrlock(&features_lock);
2402 for (x = 0; x < FEATURES_COUNT; x++) {
2403 if (strcasecmp(builtin_features[x].sname, name))
2406 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
2410 ast_rwlock_unlock(&features_lock);
2416 * \brief Helper function for feature_interpret and ast_feature_detect
2417 * \param chan,peer,config,code,sense,dynamic_features char buf,feature flags,operation,feature
2419 * Lock features list, browse for code, unlock list
2420 * If a feature is found and the operation variable is set, that feature's
2421 * operation is executed. The first feature found is copied to the feature parameter.
2422 * \retval res on success.
2423 * \retval -1 on failure.
2425 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
2426 struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
2427 struct ast_flags *features, int operation, struct ast_call_feature *feature)
2430 struct feature_group *fg = NULL;
2431 struct feature_group_exten *fge;
2432 struct ast_call_feature *tmpfeature;
2434 int res = AST_FEATURE_RETURN_PASSDIGITS;
2435 int feature_detected = 0;
2437 if (!(peer && chan && config) && operation) {
2438 return -1; /* can not run feature operation */
2441 ast_rwlock_rdlock(&features_lock);
2442 for (x = 0; x < FEATURES_COUNT; x++) {
2443 if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
2444 !ast_strlen_zero(builtin_features[x].exten)) {
2445 /* Feature is up for consideration */
2446 if (!strcmp(builtin_features[x].exten, code)) {
2447 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2449 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2451 memcpy(feature, &builtin_features[x], sizeof(feature));
2452 feature_detected = 1;
2454 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2455 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2456 res = AST_FEATURE_RETURN_STOREDIGITS;
2460 ast_rwlock_unlock(&features_lock);
2462 if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
2466 tmp = dynamic_features_buf;
2468 while ((tok = strsep(&tmp, "#"))) {
2469 AST_RWLIST_RDLOCK(&feature_groups);
2471 fg = find_group(tok);
2474 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2475 if (strcasecmp(fge->exten, code))
2478 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2480 memcpy(feature, fge->feature, sizeof(feature));
2481 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2482 AST_RWLIST_UNLOCK(&feature_groups);
2485 res = AST_FEATURE_RETURN_PASSDIGITS;
2491 AST_RWLIST_UNLOCK(&feature_groups);
2493 AST_RWLIST_RDLOCK(&feature_list);
2495 if (!(tmpfeature = find_dynamic_feature(tok))) {
2496 AST_RWLIST_UNLOCK(&feature_list);
2500 /* Feature is up for consideration */
2501 if (!strcmp(tmpfeature->exten, code)) {
2502 ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
2504 res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
2506 memcpy(feature, tmpfeature, sizeof(feature));
2507 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2508 AST_RWLIST_UNLOCK(&feature_list);
2511 res = AST_FEATURE_RETURN_PASSDIGITS;
2512 } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
2513 res = AST_FEATURE_RETURN_STOREDIGITS;
2515 AST_RWLIST_UNLOCK(&feature_list);
2522 * \brief Check the dynamic features
2523 * \param chan,peer,config,code,sense
2525 * \retval res on success.
2526 * \retval -1 on failure.
2529 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
2531 char dynamic_features_buf[128];
2532 const char *peer_dynamic_features, *chan_dynamic_features;
2533 struct ast_flags features;
2534 struct ast_call_feature feature;
2535 if (sense == FEATURE_SENSE_CHAN) {
2536 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
2539 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
2542 ast_channel_lock(peer);
2543 peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
2544 ast_channel_unlock(peer);
2546 ast_channel_lock(chan);
2547 chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
2548 ast_channel_unlock(chan);
2550 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,""));
2552 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);
2554 return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, 1, &feature);
2558 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
2560 return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
2563 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2567 ast_clear_flag(config, AST_FLAGS_ALL);
2569 ast_rwlock_rdlock(&features_lock);
2570 for (x = 0; x < FEATURES_COUNT; x++) {
2571 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2574 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2575 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2577 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2578 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2580 ast_rwlock_unlock(&features_lock);
2582 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2583 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2585 if (dynamic_features) {
2586 char *tmp = ast_strdupa(dynamic_features);
2588 struct ast_call_feature *feature;
2590 /* while we have a feature */
2591 while ((tok = strsep(&tmp, "#"))) {
2592 AST_RWLIST_RDLOCK(&feature_list);
2593 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2594 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2595 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2596 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2597 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2599 AST_RWLIST_UNLOCK(&feature_list);
2606 * \brief Get feature and dial
2607 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
2609 * Request channel, set channel variables, initiate call,check if they want to disconnect
2610 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2611 * check for answer break loop, set cdr return channel.
2613 * \todo XXX Check - this is very similar to the code in channel.c
2614 * \return always a channel
2616 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)
2621 struct ast_channel *chan;
2622 struct ast_channel *monitor_chans[2];
2623 struct ast_channel *active_channel;
2624 int res = 0, ready = 0;
2625 struct timeval started;
2627 char *disconnect_code = NULL, *dialed_code = NULL;
2629 if (!(chan = ast_request(type, format, caller, data, &cause))) {
2630 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2632 case AST_CAUSE_BUSY:
2633 state = AST_CONTROL_BUSY;
2635 case AST_CAUSE_CONGESTION:
2636 state = AST_CONTROL_CONGESTION;
2642 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2643 ast_string_field_set(chan, language, language);
2644 ast_channel_inherit_variables(caller, chan);
2645 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2647 ast_channel_lock(chan);
2648 ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
2649 ast_channel_unlock(chan);
2651 if (ast_call(chan, data, timeout)) {
2652 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2656 ast_indicate(caller, AST_CONTROL_RINGING);
2657 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2658 ast_rwlock_rdlock(&features_lock);
2659 for (x = 0; x < FEATURES_COUNT; x++) {
2660 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2663 disconnect_code = builtin_features[x].exten;
2664 len = strlen(disconnect_code) + 1;
2665 dialed_code = alloca(len);
2666 memset(dialed_code, 0, len);
2669 ast_rwlock_unlock(&features_lock);
2671 started = ast_tvnow();
2674 ast_poll_channel_add(caller, chan);
2676 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2677 struct ast_frame *f = NULL;
2679 monitor_chans[0] = caller;
2680 monitor_chans[1] = chan;
2681 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2683 /* see if the timeout has been violated */
2684 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2685 state = AST_CONTROL_UNHOLD;
2686 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2687 break; /*doh! timeout*/
2690 if (!active_channel)
2693 if (chan && (chan == active_channel)){
2694 if (!ast_strlen_zero(chan->call_forward)) {
2695 if (!(chan = ast_call_forward(caller, chan, &to, format, NULL, outstate))) {
2701 if (f == NULL) { /*doh! where'd he go?*/
2702 state = AST_CONTROL_HANGUP;
2707 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2708 if (f->subclass.integer == AST_CONTROL_RINGING) {
2709 state = f->subclass.integer;
2710 ast_verb(3, "%s is ringing\n", chan->name);
2711 ast_indicate(caller, AST_CONTROL_RINGING);
2712 } else if ((f->subclass.integer == AST_CONTROL_BUSY) || (f->subclass.integer == AST_CONTROL_CONGESTION)) {
2713 state = f->subclass.integer;
2714 ast_verb(3, "%s is busy\n", chan->name);
2715 ast_indicate(caller, AST_CONTROL_BUSY);
2719 } else if (f->subclass.integer == AST_CONTROL_ANSWER) {
2720 /* This is what we are hoping for */
2721 state = f->subclass.integer;
2726 } else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
2727 if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) {
2728 ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
2730 } else if (f->subclass.integer != -1 && f->subclass.integer != AST_CONTROL_PROGRESS) {
2731 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass.integer);
2733 /* else who cares */
2734 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2735 ast_write(caller, f);
2738 } else if (caller && (active_channel == caller)) {
2739 f = ast_read(caller);
2740 if (f == NULL) { /*doh! where'd he go?*/
2741 if (!igncallerstate) {
2742 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2743 /* make this a blind transfer */
2747 state = AST_CONTROL_HANGUP;
2753 if (f->frametype == AST_FRAME_DTMF) {
2754 dialed_code[x++] = f->subclass.integer;
2755 dialed_code[x] = '\0';
2756 if (strlen(dialed_code) == len) {
2758 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2760 dialed_code[x] = '\0';
2762 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2763 /* Caller Canceled the call */
2764 state = AST_CONTROL_UNHOLD;
2769 } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
2778 ast_poll_channel_del(caller, chan);
2781 ast_indicate(caller, -1);
2782 if (chan && ready) {
2783 if (chan->_state == AST_STATE_UP)
2784 state = AST_CONTROL_ANSWER;
2800 void ast_channel_log(char *title, struct ast_channel *chan);
2802 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
2804 ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long)chan);
2805 ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
2806 chan->name, chan->appl, chan->data, chan->context, chan->exten, chan->priority);
2807 ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
2808 chan->accountcode, chan->dialcontext, chan->amaflags, chan->macrocontext, chan->macroexten, chan->macropriority);
2809 ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; _bridge: %p; uniqueID: %s; linkedID:%s\n",
2810 chan->masq, chan->masqr,
2811 chan->_bridge, chan->uniqueid, chan->linkedid);
2813 ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
2814 chan->masqr->name, chan->masqr->cdr);
2816 ast_log(LOG_NOTICE, "CHAN: Bridged to %s\n", chan->_bridge->name);
2818 ast_log(LOG_NOTICE, "===== done ====\n");
2822 * \brief return the first unlocked cdr in a possible chain
2824 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2826 struct ast_cdr *cdr_orig = cdr;
2828 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2832 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2835 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2837 const char *feature;
2839 if (ast_strlen_zero(features)) {
2843 for (feature = features; *feature; feature++) {
2847 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2851 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2855 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2859 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2862 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2867 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2869 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2870 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2872 ast_channel_lock(caller);
2873 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2874 ast_channel_unlock(caller);
2875 if (!ds_caller_features) {
2876 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2877 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2880 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2881 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2882 ast_datastore_free(ds_caller_features);
2885 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2886 caller_features->is_caller = 1;
2887 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2888 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2889 ds_caller_features->data = caller_features;
2890 ast_channel_lock(caller);
2891 ast_channel_datastore_add(caller, ds_caller_features);
2892 ast_channel_unlock(caller);
2894 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2895 * flags over from the atxfer to the caller */
2899 ast_channel_lock(callee);
2900 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2901 ast_channel_unlock(callee);
2902 if (!ds_callee_features) {
2903 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2904 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2907 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2908 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2909 ast_datastore_free(ds_callee_features);
2912 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2913 callee_features->is_caller = 0;
2914 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2915 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2916 ds_callee_features->data = callee_features;
2917 ast_channel_lock(callee);
2918 ast_channel_datastore_add(callee, ds_callee_features);
2919 ast_channel_unlock(callee);
2926 * \brief bridge the call and set CDR
2927 * \param chan,peer,config
2929 * Set start time, check for two channels,check if monitor on
2930 * check for feature activation, create new CDR
2931 * \retval res on success.
2932 * \retval -1 on failure to bridge.
2934 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2936 /* Copy voice back and forth between the two channels. Give the peer
2937 the ability to transfer calls with '#<extension' syntax. */
2938 struct ast_frame *f;
2939 struct ast_channel *who;
2940 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2941 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2942 char orig_channame[AST_MAX_EXTENSION];
2943 char orig_peername[AST_MAX_EXTENSION];
2949 struct ast_option_header *aoh;
2950 struct ast_cdr *bridge_cdr = NULL;
2951 struct ast_cdr *orig_peer_cdr = NULL;
2952 struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2953 struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2954 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2955 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2958 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2959 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2961 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2964 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
2965 add_features_datastores(chan, peer, config);
2967 /* This is an interesting case. One example is if a ringing channel gets redirected to
2968 * an extension that picks up a parked call. This will make sure that the call taken
2969 * out of parking gets told that the channel it just got bridged to is still ringing. */
2970 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
2971 ast_indicate(peer, AST_CONTROL_RINGING);
2975 const char *monitor_exec;
2976 struct ast_channel *src = NULL;
2978 if (!(monitor_app = pbx_findapp("Monitor")))
2981 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
2983 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2985 if (monitor_app && src) {
2986 char *tmp = ast_strdupa(monitor_exec);
2987 pbx_exec(src, monitor_app, tmp);
2991 set_config_flags(chan, peer, config);
2993 /* Answer if need be */
2994 if (chan->_state != AST_STATE_UP) {
2995 if (ast_raw_answer(chan, 1)) {
3001 /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
3002 ast_channel_log("Pre-bridge CHAN Channel info", chan);
3003 ast_channel_log("Pre-bridge PEER Channel info", peer);
3005 /* two channels are being marked as linked here */
3006 ast_channel_set_linkgroup(chan,peer);
3008 /* copy the userfield from the B-leg to A-leg if applicable */
3009 if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
3011 if (!ast_strlen_zero(chan->cdr->userfield)) {
3012 snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
3013 ast_cdr_appenduserfield(chan, tmp);
3015 ast_cdr_setuserfield(chan, peer->cdr->userfield);
3016 /* free the peer's cdr without ast_cdr_free complaining */
3017 ast_free(peer->cdr);
3020 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
3021 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
3022 orig_peer_cdr = peer_cdr;
3024 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
3027 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
3028 ast_cdr_update(chan);
3029 bridge_cdr = ast_cdr_dup_unique_swap(chan_cdr);
3030 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
3031 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
3032 if (peer_cdr && !ast_strlen_zero(peer_cdr->userfield)) {
3033 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
3035 if (peer_cdr && ast_strlen_zero(peer->accountcode)) {
3036 ast_cdr_setaccount(peer, chan->accountcode);
3040 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
3041 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
3042 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
3043 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
3044 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
3045 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
3046 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
3047 ast_cdr_setcid(bridge_cdr, chan);
3048 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
3049 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
3050 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
3051 /* Destination information */
3052 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
3053 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
3055 bridge_cdr->start = peer_cdr->start;
3056 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
3058 ast_cdr_start(bridge_cdr);
3061 ast_debug(4,"bridge answer set, chan answer set\n");
3062 /* peer_cdr->answer will be set when a macro runs on the peer;
3063 in that case, the bridge answer will be delayed while the
3064 macro plays on the peer channel. The peer answered the call
3065 before the macro started playing. To the phone system,
3066 this is billable time for the call, even tho the caller
3067 hears nothing but ringing while the macro does its thing. */
3069 /* Another case where the peer cdr's time will be set, is when
3070 A self-parks by pickup up phone and dialing 700, then B
3071 picks up A by dialing its parking slot; there may be more
3072 practical paths that get the same result, tho... in which
3073 case you get the previous answer time from the Park... which
3074 is before the bridge's start time, so I added in the
3075 tvcmp check to the if below */
3077 if (peer_cdr && !ast_tvzero(peer_cdr->answer) && ast_tvcmp(peer_cdr->answer, bridge_cdr->start) >= 0) {
3078 bridge_cdr->answer = peer_cdr->answer;
3079 bridge_cdr->disposition = peer_cdr->disposition;
3081 chan_cdr->answer = peer_cdr->answer;
3082 chan_cdr->disposition = peer_cdr->disposition;
3085 ast_cdr_answer(bridge_cdr);
3087 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
3090 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
3092 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
3095 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
3099 ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, NULL);
3101 struct ast_channel *other; /* used later */
3103 res = ast_channel_bridge(chan, peer, config, &f, &who);
3105 /* When frame is not set, we are probably involved in a situation
3106 where we've timed out.
3107 When frame is set, we'll come this code twice; once for DTMF_BEGIN
3108 and also for DTMF_END. If we flow into the following 'if' for both, then
3109 our wait times are cut in half, as both will subtract from the
3110 feature_timer. Not good!
3112 if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
3113 /* Update feature timer for next pass */
3114 diff = ast_tvdiff_ms(ast_tvnow(), config->feature_start_time);
3115 if (res == AST_BRIDGE_RETRY) {
3116 /* The feature fully timed out but has not been updated. Skip
3117 * the potential round error from the diff calculation and
3118 * explicitly set to expired. */
3119 config->feature_timer = -1;
3121 config->feature_timer -= diff;
3125 if (config->feature_timer <= 0) {
3126 /* Not *really* out of time, just out of time for
3127 digits to come in for features. */
3128 ast_debug(1, "Timed out for feature!\n");
3129 if (!ast_strlen_zero(peer_featurecode)) {
3130 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
3131 memset(peer_featurecode, 0, sizeof(peer_featurecode));
3133 if (!ast_strlen_zero(chan_featurecode)) {
3134 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
3135 memset(chan_featurecode, 0, sizeof(chan_featurecode));
3139 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
3141 /* No more digits expected - reset the timer */
3142 config->feature_timer = 0;
3144 hadfeatures = hasfeatures;
3145 /* Continue as we were */
3148 /* The bridge returned without a frame and there is a feature in progress.
3149 * However, we don't think the feature has quite yet timed out, so just
3150 * go back into the bridge. */
3154 if (config->feature_timer <=0) {
3155 /* We ran out of time */
3156 config->feature_timer = 0;
3166 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer)) {
3167 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
3172 if (!f || (f->frametype == AST_FRAME_CONTROL &&
3173 (f->subclass.integer == AST_CONTROL_HANGUP || f->subclass.integer == AST_CONTROL_BUSY ||
3174 f->subclass.integer == AST_CONTROL_CONGESTION))) {
3178 /* many things should be sent to the 'other' channel */
3179 other = (who == chan) ? peer : chan;
3180 if (f->frametype == AST_FRAME_CONTROL) {
3181 switch (f->subclass.integer) {
3182 case AST_CONTROL_RINGING:
3183 case AST_CONTROL_FLASH:
3185 ast_indicate(other, f->subclass.integer);
3187 case AST_CONTROL_CONNECTED_LINE:
3188 if (!ast_channel_connected_line_macro(who, other, f, who != chan, 1)) {
3191 /* The implied "else" falls through purposely */
3192 case AST_CONTROL_HOLD:
3193 case AST_CONTROL_UNHOLD:
3194 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
3196 case AST_CONTROL_OPTION:
3198 /* Forward option Requests */
3199 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
3200 ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
3201 f->datalen - sizeof(struct ast_option_header), 0);
3205 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
3207 } else if (f->frametype == AST_FRAME_DTMF) {
3211 hadfeatures = hasfeatures;
3212 /* This cannot overrun because the longest feature is one shorter than our buffer */
3214 sense = FEATURE_SENSE_CHAN;
3215 featurecode = chan_featurecode;
3217 sense = FEATURE_SENSE_PEER;
3218 featurecode = peer_featurecode;
3220 /*! append the event to featurecode. we rely on the string being zero-filled, and
3221 * not overflowing it.
3222 * \todo XXX how do we guarantee the latter ?
3224 featurecode[strlen(featurecode)] = f->subclass.integer;
3225 /* Get rid of the frame before we start doing "stuff" with the channels */
3228 config->feature_timer = 0;
3229 res = feature_interpret(chan, peer, config, featurecode, sense);
3231 case AST_FEATURE_RETURN_PASSDIGITS:
3232 ast_dtmf_stream(other, who, featurecode, 0, 0);
3234 case AST_FEATURE_RETURN_SUCCESS:
3235 memset(featurecode, 0, sizeof(chan_featurecode));
3238 if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
3243 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
3244 if (hadfeatures && !hasfeatures) {
3245 /* Feature completed or timed out */
3246 config->feature_timer = 0;
3247 } else if (hasfeatures) {
3248 if (config->timelimit) {
3249 /* No warning next time - we are waiting for future */
3250 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
3252 config->feature_start_time = ast_tvnow();
3253 config->feature_timer = featuredigittimeout;
3254 ast_debug(1, "Set feature timer to %ld\n", config->feature_timer);
3261 ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, NULL);
3264 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
3265 ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
3267 ast_cdr_discard(bridge_cdr);
3268 /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
3270 return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
3273 if (config->end_bridge_callback) {
3274 config->end_bridge_callback(config->end_bridge_callback_data);
3277 /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
3278 * if it were, then chan belongs to a different thread now, and might have been hung up long
3281 if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
3282 ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
3283 struct ast_cdr *swapper = NULL;
3284 char savelastapp[AST_MAX_EXTENSION];
3285 char savelastdata[AST_MAX_EXTENSION];
3286 char save_exten[AST_MAX_EXTENSION];
3288 int found = 0; /* set if we find at least one match */
3289 int spawn_error = 0;
3291 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
3292 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
3293 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
3294 ast_cdr_end(bridge_cdr);
3296 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
3297 dialplan code operate on it */
3298 ast_channel_lock(chan);
3300 swapper = chan->cdr;
3301 ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
3302 ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
3303 chan->cdr = bridge_cdr;
3305 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
3306 save_prio = chan->priority;
3307 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
3309 ast_channel_unlock(chan);
3310 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
3313 if (spawn_error && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num) || ast_check_hangup(chan))) {
3314 /* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
3317 if (found && spawn_error) {
3318 /* Something bad happened, or a hangup has been requested. */
3319 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
3320 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
3323 ast_channel_lock(chan);
3324 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
3325 chan->priority = save_prio;
3327 if (chan->cdr == bridge_cdr) {
3328 chan->cdr = swapper;
3334 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
3336 ast_channel_unlock(chan);
3337 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
3339 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
3340 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
3342 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
3345 /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
3346 new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
3347 if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
3348 ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
3350 /* we can post the bridge CDR at this point */
3352 ast_cdr_end(bridge_cdr);
3353 ast_cdr_detach(bridge_cdr);
3356 /* do a specialized reset on the beginning channel
3357 CDR's, if they still exist, so as not to mess up
3358 issues in future bridges;
3360 Here are the rules of the game:
3361 1. The chan and peer channel pointers will not change
3362 during the life of the bridge.
3363 2. But, in transfers, the channel names will change.
3364 between the time the bridge is started, and the
3365 time the channel ends.
3366 Usually, when a channel changes names, it will
3367 also change CDR pointers.
3368 3. Usually, only one of the two channels (chan or peer)
3370 4. Usually, if a channel changes names during a bridge,
3371 it is because of a transfer. Usually, in these situations,
3372 it is normal to see 2 bridges running simultaneously, and
3373 it is not unusual to see the two channels that change
3374 swapped between bridges.
3375 5. After a bridge occurs, we have 2 or 3 channels' CDRs
3376 to attend to; if the chan or peer changed names,
3377 we have the before and after attached CDR's.
3381 struct ast_channel *chan_ptr = NULL;
3383 if (strcasecmp(orig_channame, chan->name) != 0) {
3385 if ((chan_ptr = ast_channel_get_by_name(orig_channame))) {
3386 ast_channel_lock(chan_ptr);
3387 if (!ast_bridged_channel(chan_ptr)) {
3388 struct ast_cdr *cur;
3389 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
3390 if (cur == chan_cdr) {
3395 ast_cdr_specialized_reset(chan_cdr, 0);
3398 ast_channel_unlock(chan_ptr);
3399 chan_ptr = ast_channel_unref(chan_ptr);
3402 ast_cdr_specialized_reset(new_chan_cdr, 0);