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"
60 <application name="Bridge" language="en_US">
65 <parameter name="channel" required="true">
66 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
68 <parameter name="options">
71 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
77 <para>Allows the ability to bridge two channels via the dialplan.</para>
78 <para>This application sets the following channel variable upon completion:</para>
80 <variable name="BRIDGERESULT">
81 <para>The result of the bridge attempt as a text string.</para>
82 <value name="SUCCESS" />
83 <value name="FAILURE" />
85 <value name="NONEXISTENT" />
86 <value name="INCOMPATIBLE" />
91 <application name="ParkedCall" language="en_US">
96 <parameter name="exten" required="true" />
99 <para>Used to connect to a parked call. This application is always
100 registered internally and does not need to be explicitly added
101 into the dialplan, although you should include the <literal>parkedcalls</literal>
102 context. If no extension is provided, then the first available
103 parked call will be acquired.</para>
106 <ref type="application">Park</ref>
107 <ref type="application">ParkAndAnnounce</ref>
110 <application name="Park" language="en_US">
115 <parameter name="timeout">
116 <para>A custom parking timeout for this parked call.</para>
118 <parameter name="return_context">
119 <para>The context to return the call to after it times out.</para>
121 <parameter name="return_exten">
122 <para>The extension to return the call to after it times out.</para>
124 <parameter name="return_priority">
125 <para>The priority to return the call to after it times out.</para>
127 <parameter name="options">
128 <para>A list of options for this parked call.</para>
131 <para>Send ringing instead of MOH to the parked call.</para>
134 <para>Randomize the selection of a parking space.</para>
137 <para>Silence announcement of the parking space number.</para>
143 <para>Used to park yourself (typically in combination with a supervised
144 transfer to know the parking space). This application is always
145 registered internally and does not need to be explicitly added
146 into the dialplan, although you should include the <literal>parkedcalls</literal>
147 context (or the context specified in <filename>features.conf</filename>).</para>
148 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
149 parking context, Park() will park the call on that extension, unless
150 it already exists. In that case, execution will continue at next priority.</para>
153 <ref type="application">ParkAndAnnounce</ref>
154 <ref type="application">ParkedCall</ref>
159 #define DEFAULT_PARK_TIME 45000
160 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
161 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 2000
162 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
163 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
164 #define DEFAULT_ATXFER_DROP_CALL 0
165 #define DEFAULT_ATXFER_LOOP_DELAY 10000
166 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
168 #define AST_MAX_WATCHERS 256
169 #define MAX_DIAL_FEATURE_OPTIONS 30
171 struct feature_group_exten {
172 AST_LIST_ENTRY(feature_group_exten) entry;
173 AST_DECLARE_STRING_FIELDS(
174 AST_STRING_FIELD(exten);
176 struct ast_call_feature *feature;
179 struct feature_group {
180 AST_LIST_ENTRY(feature_group) entry;
181 AST_DECLARE_STRING_FIELDS(
182 AST_STRING_FIELD(gname);
184 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
187 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
189 static char *parkedcall = "ParkedCall";
191 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
193 /*! \brief Description of one parked call, added to a list while active, then removed.
194 The list belongs to a parkinglot
197 struct ast_channel *chan; /*!< Parking channel */
198 struct timeval start; /*!< Time the parking started */
199 int parkingnum; /*!< Parking lot */
200 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
201 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
202 char exten[AST_MAX_EXTENSION];
204 int parkingtime; /*!< Maximum length in parking lot before return */
207 unsigned char moh_trys;
208 struct ast_parkinglot *parkinglot;
209 AST_LIST_ENTRY(parkeduser) list;
212 /*! \brief Structure for parking lots which are put in a container. */
213 struct ast_parkinglot {
214 char name[AST_MAX_CONTEXT];
215 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
216 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
217 int parking_start; /*!< First available extension for parking */
218 int parking_stop; /*!< Last available extension for parking */
221 int parkingtime; /*!< Default parking time */
222 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
223 int parkaddhints; /*!< Add parking hints automatically */
224 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
225 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
226 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
227 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
228 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
231 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
232 static struct ao2_container *parkinglots;
234 struct ast_parkinglot *default_parkinglot;
235 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
237 static char courtesytone[256]; /*!< Courtesy tone */
238 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
239 static char xfersound[256]; /*!< Call transfer sound */
240 static char xferfailsound[256]; /*!< Call transfer failure sound */
244 static int transferdigittimeout;
245 static int featuredigittimeout;
246 static int comebacktoorigin = 1;
248 static int atxfernoanswertimeout;
249 static unsigned int atxferdropcall;
250 static unsigned int atxferloopdelay;
251 static unsigned int atxfercallbackretries;
253 static char *registrar = "features"; /*!< Registrar for operations */
255 /* module and CLI command definitions */
256 static char *parkcall = PARK_APP_NAME;
258 static struct ast_app *monitor_app = NULL;
259 static int monitor_ok = 1;
261 static struct ast_app *mixmonitor_app = NULL;
262 static int mixmonitor_ok = 1;
264 static struct ast_app *stopmixmonitor_app = NULL;
265 static int stopmixmonitor_ok = 1;
267 static pthread_t parking_thread;
268 struct ast_dial_features {
269 struct ast_flags features_caller;
270 struct ast_flags features_callee;
274 static void *dial_features_duplicate(void *data)
276 struct ast_dial_features *df = data, *df_copy;
278 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
282 memcpy(df_copy, df, sizeof(*df));
287 static void dial_features_destroy(void *data)
289 struct ast_dial_features *df = data;
295 const struct ast_datastore_info dial_features_info = {
296 .type = "dial-features",
297 .destroy = dial_features_destroy,
298 .duplicate = dial_features_duplicate,
301 /* Forward declarations */
302 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
303 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
304 static void parkinglot_destroy(void *obj);
305 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
306 struct ast_parkinglot *find_parkinglot(const char *name);
309 const char *ast_parking_ext(void)
314 const char *ast_pickup_ext(void)
319 struct ast_bridge_thread_obj
321 struct ast_bridge_config bconfig;
322 struct ast_channel *chan;
323 struct ast_channel *peer;
324 unsigned int return_to_pbx:1;
327 static int parkinglot_hash_cb(const void *obj, const int flags)
329 const struct ast_parkinglot *parkinglot = obj;
331 return ast_str_case_hash(parkinglot->name);
334 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
336 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
338 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
342 * \brief store context, extension and priority
343 * \param chan, context, ext, pri
345 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
347 ast_copy_string(chan->context, context, sizeof(chan->context));
348 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
349 chan->priority = pri;
353 * \brief Check goto on transfer
356 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
357 * When found make sure the types are compatible. Check if channel is valid
358 * if so start the new channel else hangup the call.
360 static void check_goto_on_transfer(struct ast_channel *chan)
362 struct ast_channel *xferchan;
363 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
364 char *x, *goto_on_transfer;
367 if (ast_strlen_zero(val))
370 goto_on_transfer = ast_strdupa(val);
372 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", chan->name)))
375 for (x = goto_on_transfer; x && *x; x++) {
379 /* Make formats okay */
380 xferchan->readformat = chan->readformat;
381 xferchan->writeformat = chan->writeformat;
382 ast_channel_masquerade(xferchan, chan);
383 ast_parseable_goto(xferchan, goto_on_transfer);
384 xferchan->_state = AST_STATE_UP;
385 ast_clear_flag(xferchan, AST_FLAGS_ALL);
386 xferchan->_softhangup = 0;
387 if ((f = ast_read(xferchan))) {
390 ast_pbx_start(xferchan);
392 ast_hangup(xferchan);
396 static struct ast_channel *ast_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);
399 * \brief bridge the call
400 * \param data thread bridge.
402 * Set Last Data for respective channels, reset cdr for channels
403 * bridge call, check if we're going back to dialplan
404 * if not hangup both legs of the call
406 static void *ast_bridge_call_thread(void *data)
408 struct ast_bridge_thread_obj *tobj = data;
411 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
412 tobj->chan->data = tobj->peer->name;
413 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
414 tobj->peer->data = tobj->chan->name;
416 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
418 if (tobj->return_to_pbx) {
419 if (!ast_check_hangup(tobj->peer)) {
420 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
421 res = ast_pbx_start(tobj->peer);
422 if (res != AST_PBX_SUCCESS)
423 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
425 ast_hangup(tobj->peer);
426 if (!ast_check_hangup(tobj->chan)) {
427 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
428 res = ast_pbx_start(tobj->chan);
429 if (res != AST_PBX_SUCCESS)
430 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
432 ast_hangup(tobj->chan);
434 ast_hangup(tobj->chan);
435 ast_hangup(tobj->peer);
444 * \brief create thread for the parked call
447 * Create thread and attributes, call ast_bridge_call_thread
449 static void ast_bridge_call_thread_launch(void *data)
453 struct sched_param sched;
455 pthread_attr_init(&attr);
456 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
457 ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
458 pthread_attr_destroy(&attr);
459 memset(&sched, 0, sizeof(sched));
460 pthread_setschedparam(thread, SCHED_RR, &sched);
464 * \brief Announce call parking by ADSI
466 * \param parkingexten .
467 * Create message to show for ADSI, display message.
468 * \retval 0 on success.
469 * \retval -1 on failure.
471 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
474 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
476 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
478 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
480 res = ast_adsi_load_session(chan, NULL, 0, 1);
483 return ast_adsi_print(chan, message, justify, 1);
486 /*! \brief Find parking lot name from channel */
487 static const char *findparkinglotname(struct ast_channel *chan)
489 const char *temp, *parkinglot = NULL;
491 /* Check if the channel has a parking lot */
492 if (!ast_strlen_zero(chan->parkinglot))
493 parkinglot = chan->parkinglot;
495 /* Channel variables override everything */
497 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
503 /*! \brief Notify metermaids that we've changed an extension */
504 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
506 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
507 exten, context, ast_devstate2str(state));
509 ast_devstate_changed(state, "park:%s@%s", exten, context);
512 /*! \brief metermaids callback from devicestate.c */
513 static enum ast_device_state metermaidstate(const char *data)
518 context = ast_strdupa(data);
520 exten = strsep(&context, "@");
522 return AST_DEVICE_INVALID;
524 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
526 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
527 return AST_DEVICE_NOT_INUSE;
529 return AST_DEVICE_INUSE;
532 /*! Options to pass to ast_park_call_full */
533 enum ast_park_call_options {
534 /*! Provide ringing to the parked caller instead of music on hold */
535 AST_PARK_OPT_RINGING = (1 << 0),
536 /*! Randomly choose a parking spot for the caller instead of choosing
537 * the first one that is available. */
538 AST_PARK_OPT_RANDOMIZE = (1 << 1),
539 /*! Do not announce the parking number */
540 AST_PARK_OPT_SILENCE = (1 << 2),
543 struct ast_park_call_args {
544 /*! How long to wait in the parking lot before the call gets sent back
545 * to the specified return extension (or a best guess at where it came
546 * from if not explicitly specified). */
548 /*! An output parameter to store the parking space where the parked caller
551 const char *orig_chan_name;
552 const char *return_con;
553 const char *return_ext;
556 /*! Parked user that has already obtained a parking space */
557 struct parkeduser *pu;
560 static struct parkeduser *park_space_reserve(struct ast_channel *chan,
561 struct ast_channel *peer, struct ast_park_call_args *args)
563 struct parkeduser *pu;
564 int i, parking_space = -1, parking_range;
565 const char *parkinglotname = NULL;
566 const char *parkingexten;
567 struct ast_parkinglot *parkinglot = NULL;
570 parkinglotname = findparkinglotname(peer);
572 if (parkinglotname) {
574 ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
575 parkinglot = find_parkinglot(parkinglotname);
578 parkinglot = default_parkinglot;
580 parkinglot_addref(parkinglot);
582 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
584 /* Allocate memory for parking data */
585 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
586 parkinglot_unref(parkinglot);
590 /* Lock parking list */
591 AST_LIST_LOCK(&parkinglot->parkings);
592 /* Check for channel variable PARKINGEXTEN */
593 parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
594 if (!ast_strlen_zero(parkingexten)) {
595 /*!\note The API forces us to specify a numeric parking slot, even
596 * though the architecture would tend to support non-numeric extensions
597 * (as are possible with SIP, for example). Hence, we enforce that
598 * limitation here. If extout was not numeric, we could permit
599 * arbitrary non-numeric extensions.
601 if (sscanf(parkingexten, "%d", &parking_space) != 1 || parking_space < 0) {
602 AST_LIST_UNLOCK(&parkinglot->parkings);
603 parkinglot_unref(parkinglot);
605 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
608 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
610 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
611 AST_LIST_UNLOCK(&parkinglot->parkings);
612 parkinglot_unref(parkinglot);
614 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
619 struct parkeduser *cur = NULL;
621 /* Select parking space within range */
622 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
624 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
625 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
627 start = parkinglot->parking_start;
630 for (i = start; 1; i++) {
631 if (i == parkinglot->parking_stop + 1) {
632 i = parkinglot->parking_start - 1;
636 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
637 if (cur->parkingnum == i) {
642 if (!cur || i == start - 1) {
648 if (i == start - 1 && cur) {
649 ast_log(LOG_WARNING, "No more parking spaces\n");
651 AST_LIST_UNLOCK(&parkinglot->parkings);
652 parkinglot_unref(parkinglot);
655 /* Set pointer for next parking */
656 if (parkinglot->parkfindnext)
657 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
658 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
662 pu->parkingnum = parking_space;
663 pu->parkinglot = parkinglot;
664 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
665 parkinglot_unref(parkinglot);
671 static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
673 struct ast_context *con;
675 struct parkeduser *pu = args->pu;
676 const char *event_from;
679 pu = park_space_reserve(chan, peer, args);
681 return 1; /* Continue execution if possible */
683 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
685 chan->appl = "Parked Call";
690 /* Put the parked channel on hold if we have two different channels */
692 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
693 ast_indicate(pu->chan, AST_CONTROL_RINGING);
695 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
696 S_OR(pu->parkinglot->mohclass, NULL),
697 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
701 pu->start = ast_tvnow();
702 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
703 parkingnum_copy = pu->parkingnum;
705 *(args->extout) = pu->parkingnum;
708 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
709 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
710 and we need the callback name to be that of transferer. Since local,1/2 have the same
711 name we can be tricky and just grab the bridged channel from the other side of the local
713 if (!strcasecmp(peer->tech->type, "Local")) {
714 struct ast_channel *tmpchan, *base_peer;
715 char other_side[AST_CHANNEL_NAME];
717 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
718 if ((c = strrchr(other_side, ';'))) {
721 if ((tmpchan = ast_get_channel_by_name_locked(other_side))) {
722 if ((base_peer = ast_bridged_channel(tmpchan))) {
723 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
725 ast_channel_unlock(tmpchan);
728 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
732 /* Remember what had been dialed, so that if the parking
733 expires, we try to come back to the same place */
734 ast_copy_string(pu->context,
735 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
736 sizeof(pu->context));
737 ast_copy_string(pu->exten,
738 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
740 pu->priority = pu->priority ? pu->priority :
741 (chan->macropriority ? chan->macropriority : chan->priority);
743 /* If parking a channel directly, don't quiet yet get parking running on it.
744 * All parking lot entries are put into the parking lot with notquiteyet on. */
748 /* Wake up the (presumably select()ing) thread */
749 pthread_kill(parking_thread, SIGURG);
750 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));
753 event_from = peer->name;
755 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
758 manager_event(EVENT_FLAG_CALL, "ParkedCall",
764 "CallerIDNum: %s\r\n"
765 "CallerIDName: %s\r\n"
767 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
768 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
769 S_OR(pu->chan->cid.cid_num, "<unknown>"),
770 S_OR(pu->chan->cid.cid_name, "<unknown>"),
774 if (peer && adsipark && ast_adsi_available(peer)) {
775 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
776 ast_adsi_unload_session(peer);
779 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
780 if (!con) /* Still no context? Bad */
781 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
783 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
784 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
787 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
789 /* Only say number if it's a number and the channel hasn't been masqueraded away */
790 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
791 /* 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. */
792 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
793 /* Tell the peer channel the number of the parking space */
794 ast_say_digits(peer, pu->parkingnum, "", peer->language);
795 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
797 if (peer == chan) { /* pu->notquiteyet = 1 */
798 /* Wake up parking thread if we're really done */
799 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
800 S_OR(pu->parkinglot->mohclass, NULL),
801 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
803 pthread_kill(parking_thread, SIGURG);
808 /*! \brief Park a call */
809 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
811 struct ast_park_call_args args = {
816 return ast_park_call_full(chan, peer, &args);
819 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)
821 struct ast_channel *chan;
824 struct ast_park_call_args park_args = {0,};
828 args->timeout = timeout;
829 args->extout = extout;
832 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
834 ast_stream_and_wait(peer, "beeperr", "");
835 return AST_FEATURE_RETURN_PARKFAILED;
838 /* Make a new, fake channel that we'll use to masquerade in the real one */
839 if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
840 ast_log(LOG_WARNING, "Unable to create parked channel\n");
844 /* Make formats okay */
845 chan->readformat = rchan->readformat;
846 chan->writeformat = rchan->writeformat;
847 ast_channel_masquerade(chan, rchan);
849 /* Setup the extensions and such */
850 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
852 /* Make the masq execute */
853 if ((f = ast_read(chan)))
860 if (!play_announcement && args == &park_args) {
861 args->orig_chan_name = ast_strdupa(chan->name);
864 park_status = ast_park_call_full(chan, peer, args);
865 if (park_status == 1) {
866 /* would be nice to play "invalid parking extension" */
874 /* Park call via masquraded channel */
875 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
877 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
880 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
882 return masq_park_call(rchan, peer, 0, NULL, 1, args);
885 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
887 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
890 #define FEATURE_SENSE_CHAN (1 << 0)
891 #define FEATURE_SENSE_PEER (1 << 1)
894 * \brief set caller and callee according to the direction
895 * \param caller, callee, peer, chan, sense
897 * Detect who triggered feature and set callee/caller variables accordingly
899 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
900 struct ast_channel *peer, struct ast_channel *chan, int sense)
902 if (sense == FEATURE_SENSE_PEER) {
912 * \brief support routing for one touch call parking
913 * \param chan channel parking call
914 * \param peer channel to be parked
915 * \param config unsed
917 * \param sense feature options
920 * Setup channel, set return exten,priority to 's,1'
921 * answer chan, sleep chan, park call
923 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
925 struct ast_channel *parker;
926 struct ast_channel *parkee;
929 set_peers(&parker, &parkee, peer, chan, sense);
930 /* we used to set chan's exten and priority to "s" and 1
931 here, but this generates (in some cases) an invalid
932 extension, and if "s" exists, could errantly
933 cause execution of extensions you don't expect. It
934 makes more sense to let nature take its course
935 when chan finishes, and let the pbx do its thing
936 and hang up when the park is over.
938 if (chan->_state != AST_STATE_UP)
939 res = ast_answer(chan);
941 res = ast_safe_sleep(chan, 1000);
943 if (!res) { /* one direction used to call park_call.... */
944 res = masq_park_call_announce(parkee, parker, 0, NULL);
945 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
951 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
952 other channel during the message, so please don't use this for very long messages
954 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
956 /* First play for caller, put other channel on auto service */
957 if (ast_autoservice_start(callee_chan))
959 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
960 ast_log(LOG_WARNING, "Failed to play automon message!\n");
961 ast_autoservice_stop(callee_chan);
964 if (ast_autoservice_stop(callee_chan))
966 /* Then play for callee, put other channel on auto service */
967 if (ast_autoservice_start(caller_chan))
969 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
970 ast_log(LOG_WARNING, "Failed to play automon message !\n");
971 ast_autoservice_stop(caller_chan);
974 if (ast_autoservice_stop(caller_chan))
980 * \brief Monitor a channel by DTMF
981 * \param chan channel requesting monitor
982 * \param peer channel to be monitored
985 * \param sense feature options
988 * Check monitor app enabled, setup channels, both caller/callee chans not null
989 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
990 * \retval AST_FEATURE_RETURN_SUCCESS on success.
991 * \retval -1 on error.
993 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
995 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
998 struct ast_channel *caller_chan, *callee_chan;
999 const char *automon_message_start = NULL;
1000 const char *automon_message_stop = NULL;
1003 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1007 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1009 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1013 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1014 if (caller_chan) { /* Find extra messages */
1015 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1016 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1019 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1020 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1025 if (callee_chan->monitor) {
1026 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1027 if (!ast_strlen_zero(automon_message_stop)) {
1028 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1030 callee_chan->monitor->stop(callee_chan, 1);
1031 return AST_FEATURE_RETURN_SUCCESS;
1034 if (caller_chan && callee_chan) {
1035 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1036 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1037 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1040 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1043 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1045 if (!touch_monitor_prefix)
1046 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1048 if (touch_monitor) {
1049 len = strlen(touch_monitor) + 50;
1051 touch_filename = alloca(len);
1052 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1053 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1055 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1056 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1057 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1059 touch_filename = alloca(len);
1060 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1061 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1064 for(x = 0; x < strlen(args); x++) {
1069 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1071 pbx_exec(callee_chan, monitor_app, args);
1072 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1073 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1075 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1076 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1079 return AST_FEATURE_RETURN_SUCCESS;
1082 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1086 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1088 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1091 struct ast_channel *caller_chan, *callee_chan;
1092 const char *mixmonitor_spy_type = "MixMonitor";
1095 if (!mixmonitor_ok) {
1096 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1100 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1102 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1106 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1108 if (!ast_strlen_zero(courtesytone)) {
1109 if (ast_autoservice_start(callee_chan))
1111 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1112 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1113 ast_autoservice_stop(callee_chan);
1116 if (ast_autoservice_stop(callee_chan))
1120 ast_channel_lock(callee_chan);
1121 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1122 ast_channel_unlock(callee_chan);
1124 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1127 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1129 /* Make sure they are running */
1130 ast_channel_lock(callee_chan);
1131 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1132 ast_channel_unlock(callee_chan);
1134 if (!stopmixmonitor_ok) {
1135 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1138 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1139 stopmixmonitor_ok = 0;
1140 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1143 pbx_exec(callee_chan, stopmixmonitor_app, "");
1144 return AST_FEATURE_RETURN_SUCCESS;
1148 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1151 if (caller_chan && callee_chan) {
1152 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1153 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1156 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1159 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1161 if (touch_monitor) {
1162 len = strlen(touch_monitor) + 50;
1164 touch_filename = alloca(len);
1165 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1166 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1168 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1169 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1170 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1172 touch_filename = alloca(len);
1173 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1174 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1177 for( x = 0; x < strlen(args); x++) {
1182 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1184 pbx_exec(callee_chan, mixmonitor_app, args);
1185 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1186 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1187 return AST_FEATURE_RETURN_SUCCESS;
1191 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1196 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1198 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1199 return AST_FEATURE_RETURN_HANGUP;
1202 static int finishup(struct ast_channel *chan)
1204 ast_indicate(chan, AST_CONTROL_UNHOLD);
1206 return ast_autoservice_stop(chan);
1210 * \brief Find the context for the transfer
1214 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1215 * \return a context string
1217 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1219 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1220 if (ast_strlen_zero(s)) {
1221 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1223 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1224 s = transferer->macrocontext;
1226 if (ast_strlen_zero(s)) {
1227 s = transferer->context;
1233 * \brief Blind transfer user to another extension
1234 * \param chan channel to be transfered
1235 * \param peer channel initiated blind transfer
1239 * \param sense feature options
1241 * Place chan on hold, check if transferred to parkinglot extension,
1242 * otherwise check extension exists and transfer caller.
1243 * \retval AST_FEATURE_RETURN_SUCCESS.
1244 * \retval -1 on failure.
1246 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1248 struct ast_channel *transferer;
1249 struct ast_channel *transferee;
1250 const char *transferer_real_context;
1252 int res, parkstatus = 0;
1254 set_peers(&transferer, &transferee, peer, chan, sense);
1255 transferer_real_context = real_ctx(transferer, transferee);
1256 /* Start autoservice on chan while we talk to the originator */
1257 ast_autoservice_start(transferee);
1258 ast_indicate(transferee, AST_CONTROL_HOLD);
1260 memset(xferto, 0, sizeof(xferto));
1263 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1265 finishup(transferee);
1266 return -1; /* error ? */
1268 if (res > 0) /* If they've typed a digit already, handle it */
1269 xferto[0] = (char) res;
1271 ast_stopstream(transferer);
1272 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1273 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1274 finishup(transferee);
1277 if (!strcmp(xferto, ast_parking_ext())) {
1278 res = finishup(transferee);
1281 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1282 /* We return non-zero, but tell the PBX not to hang the channel when
1283 the thread dies -- We have to be careful now though. We are responsible for
1284 hanging up the channel, else it will never be hung up! */
1288 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1290 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1291 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1292 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1293 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1294 res=finishup(transferee);
1295 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1296 transferer->cdr=ast_cdr_alloc();
1297 if (transferer->cdr) {
1298 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
1299 ast_cdr_start(transferer->cdr);
1302 if (transferer->cdr) {
1303 struct ast_cdr *swap = transferer->cdr;
1304 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1305 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1306 transferer->cdr->channel, transferer->cdr->dstchannel);
1307 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1308 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1309 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1310 /* swap cdrs-- it will save us some time & work */
1311 transferer->cdr = transferee->cdr;
1312 transferee->cdr = swap;
1314 if (!transferee->pbx) {
1315 /* Doh! Use our handy async_goto functions */
1316 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1317 ,transferee->name, xferto, transferer_real_context);
1318 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1319 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1321 /* Set the channel's new extension, since it exists, using transferer context */
1322 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1323 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1324 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1326 check_goto_on_transfer(transferer);
1329 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1331 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1332 finishup(transferee);
1335 ast_stopstream(transferer);
1336 res = finishup(transferee);
1338 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1341 return AST_FEATURE_RETURN_SUCCESS;
1345 * \brief make channels compatible
1348 * \retval 0 on success.
1349 * \retval -1 on failure.
1351 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1353 if (ast_channel_make_compatible(c, newchan) < 0) {
1354 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1355 c->name, newchan->name);
1356 ast_hangup(newchan);
1363 * \brief Attended transfer
1364 * \param chan transfered user
1365 * \param peer person transfering call
1368 * \param sense feature options
1371 * Get extension to transfer to, if you cannot generate channel (or find extension)
1372 * return to host channel. After called channel answered wait for hangup of transferer,
1373 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1375 * \return -1 on failure
1377 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1379 struct ast_channel *transferer;
1380 struct ast_channel *transferee;
1381 const char *transferer_real_context;
1382 char xferto[256] = "";
1385 struct ast_channel *newchan;
1386 struct ast_channel *xferchan;
1387 struct ast_bridge_thread_obj *tobj;
1388 struct ast_bridge_config bconfig;
1389 struct ast_frame *f;
1391 struct ast_datastore *features_datastore;
1392 struct ast_dial_features *dialfeatures = NULL;
1394 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1395 set_peers(&transferer, &transferee, peer, chan, sense);
1396 transferer_real_context = real_ctx(transferer, transferee);
1397 /* Start autoservice on chan while we talk to the originator */
1398 ast_autoservice_start(transferee);
1399 ast_indicate(transferee, AST_CONTROL_HOLD);
1402 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1404 finishup(transferee);
1407 if (res > 0) /* If they've typed a digit already, handle it */
1408 xferto[0] = (char) res;
1410 /* this is specific of atxfer */
1411 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1412 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1413 finishup(transferee);
1417 ast_log(LOG_WARNING, "Did not read data.\n");
1418 finishup(transferee);
1419 if (ast_stream_and_wait(transferer, "beeperr", ""))
1421 return AST_FEATURE_RETURN_SUCCESS;
1424 /* valid extension, res == 1 */
1425 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1426 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1427 finishup(transferee);
1428 if (ast_stream_and_wait(transferer, "beeperr", ""))
1430 return AST_FEATURE_RETURN_SUCCESS;
1433 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1434 * the different variables for handling this properly with a builtin_atxfer */
1435 if (!strcmp(xferto, ast_parking_ext())) {
1436 finishup(transferee);
1437 return builtin_parkcall(chan, peer, config, code, sense, data);
1441 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1443 /* If we are performing an attended transfer and we have two channels involved then
1444 copy sound file information to play upon attended transfer completion */
1446 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1447 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1449 if (!ast_strlen_zero(chan1_attended_sound)) {
1450 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1452 if (!ast_strlen_zero(chan2_attended_sound)) {
1453 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1457 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1458 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1460 if (!ast_check_hangup(transferer)) {
1461 /* Transferer is up - old behaviour */
1462 ast_indicate(transferer, -1);
1464 finishup(transferee);
1465 /* any reason besides user requested cancel and busy triggers the failed sound */
1466 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1467 ast_stream_and_wait(transferer, xferfailsound, ""))
1469 if (ast_stream_and_wait(transferer, xfersound, ""))
1470 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1471 return AST_FEATURE_RETURN_SUCCESS;
1474 if (check_compat(transferer, newchan)) {
1475 /* we do mean transferee here, NOT transferer */
1476 finishup(transferee);
1479 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1480 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1481 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1482 res = ast_bridge_call(transferer, newchan, &bconfig);
1483 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1484 ast_hangup(newchan);
1485 if (ast_stream_and_wait(transferer, xfersound, ""))
1486 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1487 finishup(transferee);
1488 transferer->_softhangup = 0;
1489 return AST_FEATURE_RETURN_SUCCESS;
1491 if (check_compat(transferee, newchan)) {
1492 finishup(transferee);
1495 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1497 if ((ast_autoservice_stop(transferee) < 0)
1498 || (ast_waitfordigit(transferee, 100) < 0)
1499 || (ast_waitfordigit(newchan, 100) < 0)
1500 || ast_check_hangup(transferee)
1501 || ast_check_hangup(newchan)) {
1502 ast_hangup(newchan);
1505 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1507 ast_hangup(newchan);
1510 /* Make formats okay */
1511 xferchan->visible_indication = transferer->visible_indication;
1512 xferchan->readformat = transferee->readformat;
1513 xferchan->writeformat = transferee->writeformat;
1514 ast_channel_masquerade(xferchan, transferee);
1515 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1516 xferchan->_state = AST_STATE_UP;
1517 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1518 xferchan->_softhangup = 0;
1519 if ((f = ast_read(xferchan)))
1521 newchan->_state = AST_STATE_UP;
1522 ast_clear_flag(newchan, AST_FLAGS_ALL);
1523 newchan->_softhangup = 0;
1524 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1525 ast_hangup(xferchan);
1526 ast_hangup(newchan);
1530 ast_channel_lock(newchan);
1531 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1532 dialfeatures = features_datastore->data;
1534 ast_channel_unlock(newchan);
1537 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1538 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1539 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1540 dialfeatures = NULL;
1543 ast_channel_lock(xferchan);
1544 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1545 dialfeatures = features_datastore->data;
1547 ast_channel_unlock(xferchan);
1550 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1553 tobj->chan = newchan;
1554 tobj->peer = xferchan;
1555 tobj->bconfig = *config;
1557 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1558 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1561 if (ast_stream_and_wait(newchan, xfersound, ""))
1562 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1563 ast_bridge_call_thread_launch(tobj);
1564 return -1; /* XXX meaning the channel is bridged ? */
1565 } else if (!ast_check_hangup(transferee)) {
1566 /* act as blind transfer */
1567 if (ast_autoservice_stop(transferee) < 0) {
1568 ast_hangup(newchan);
1573 unsigned int tries = 0;
1574 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1576 transferer_tech = strsep(&transferer_name, "/");
1577 transferer_name = strsep(&transferer_name, "-");
1579 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1580 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1581 if (ast_stream_and_wait(transferee, "beeperr", ""))
1583 return AST_FEATURE_RETURN_SUCCESS;
1586 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1587 newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1588 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1589 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1590 /* Trying to transfer again */
1591 ast_autoservice_start(transferee);
1592 ast_indicate(transferee, AST_CONTROL_HOLD);
1594 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1595 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1596 if (ast_autoservice_stop(transferee) < 0) {
1598 ast_hangup(newchan);
1602 /* Transfer failed, sleeping */
1603 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1604 ast_safe_sleep(transferee, atxferloopdelay);
1605 ast_debug(1, "Trying to callback...\n");
1606 newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1607 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1615 /* newchan is up, we should prepare transferee and bridge them */
1616 if (check_compat(transferee, newchan)) {
1617 finishup(transferee);
1620 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1622 if ((ast_waitfordigit(transferee, 100) < 0)
1623 || (ast_waitfordigit(newchan, 100) < 0)
1624 || ast_check_hangup(transferee)
1625 || ast_check_hangup(newchan)) {
1626 ast_hangup(newchan);
1630 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1632 ast_hangup(newchan);
1635 /* Make formats okay */
1636 xferchan->visible_indication = transferer->visible_indication;
1637 xferchan->readformat = transferee->readformat;
1638 xferchan->writeformat = transferee->writeformat;
1639 ast_channel_masquerade(xferchan, transferee);
1640 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1641 xferchan->_state = AST_STATE_UP;
1642 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1643 xferchan->_softhangup = 0;
1644 if ((f = ast_read(xferchan)))
1646 newchan->_state = AST_STATE_UP;
1647 ast_clear_flag(newchan, AST_FLAGS_ALL);
1648 newchan->_softhangup = 0;
1649 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1650 ast_hangup(xferchan);
1651 ast_hangup(newchan);
1654 tobj->chan = newchan;
1655 tobj->peer = xferchan;
1656 tobj->bconfig = *config;
1658 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1659 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1662 if (ast_stream_and_wait(newchan, xfersound, ""))
1663 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1664 ast_bridge_call_thread_launch(tobj);
1665 return -1; /* XXX meaning the channel is bridged ? */
1667 /* Transferee hung up */
1668 finishup(transferee);
1673 /* add atxfer and automon as undefined so you can only use em if you configure them */
1674 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1676 AST_RWLOCK_DEFINE_STATIC(features_lock);
1678 static struct ast_call_feature builtin_features[] =
1680 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1681 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1682 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1683 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1684 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1685 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1689 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
1691 /*! \brief register new feature into feature_list*/
1692 void ast_register_feature(struct ast_call_feature *feature)
1695 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1699 AST_RWLIST_WRLOCK(&feature_list);
1700 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1701 AST_RWLIST_UNLOCK(&feature_list);
1703 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1707 * \brief Add new feature group
1708 * \param fgname feature group name.
1710 * Add new feature group to the feature group list insert at head of list.
1711 * \note This function MUST be called while feature_groups is locked.
1713 static struct feature_group* register_group(const char *fgname)
1715 struct feature_group *fg;
1718 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1722 if (!(fg = ast_calloc(1, sizeof(*fg))))
1725 if (ast_string_field_init(fg, 128)) {
1730 ast_string_field_set(fg, gname, fgname);
1732 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
1734 ast_verb(2, "Registered group '%s'\n", fg->gname);
1740 * \brief Add feature to group
1741 * \param fg feature group
1743 * \param feature feature to add.
1745 * Check fg and feature specified, add feature to list
1746 * \note This function MUST be called while feature_groups is locked.
1748 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
1750 struct feature_group_exten *fge;
1753 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
1758 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
1762 if (!(fge = ast_calloc(1, sizeof(*fge))))
1765 if (ast_string_field_init(fge, 128)) {
1770 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
1772 fge->feature = feature;
1774 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
1776 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
1777 feature->sname, fg->gname, exten);
1780 void ast_unregister_feature(struct ast_call_feature *feature)
1786 AST_RWLIST_WRLOCK(&feature_list);
1787 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
1788 AST_RWLIST_UNLOCK(&feature_list);
1793 /*! \brief Remove all features in the list */
1794 static void ast_unregister_features(void)
1796 struct ast_call_feature *feature;
1798 AST_RWLIST_WRLOCK(&feature_list);
1799 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
1802 AST_RWLIST_UNLOCK(&feature_list);
1805 /*! \brief find a call feature by name */
1806 static struct ast_call_feature *find_dynamic_feature(const char *name)
1808 struct ast_call_feature *tmp;
1810 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
1811 if (!strcasecmp(tmp->sname, name)) {
1819 /*! \brief Remove all feature groups in the list */
1820 static void ast_unregister_groups(void)
1822 struct feature_group *fg;
1823 struct feature_group_exten *fge;
1825 AST_RWLIST_WRLOCK(&feature_groups);
1826 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
1827 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
1828 ast_string_field_free_memory(fge);
1832 ast_string_field_free_memory(fg);
1835 AST_RWLIST_UNLOCK(&feature_groups);
1839 * \brief Find a group by name
1840 * \param name feature name
1841 * \retval feature group on success.
1842 * \retval NULL on failure.
1844 static struct feature_group *find_group(const char *name) {
1845 struct feature_group *fg = NULL;
1847 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
1848 if (!strcasecmp(fg->gname, name))
1855 void ast_rdlock_call_features(void)
1857 ast_rwlock_rdlock(&features_lock);
1860 void ast_unlock_call_features(void)
1862 ast_rwlock_unlock(&features_lock);
1865 struct ast_call_feature *ast_find_call_feature(const char *name)
1868 for (x = 0; x < FEATURES_COUNT; x++) {
1869 if (!strcasecmp(name, builtin_features[x].sname))
1870 return &builtin_features[x];
1876 * \brief exec an app by feature
1877 * \param chan,peer,config,code,sense,data
1879 * Find a feature, determine which channel activated
1880 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
1882 * \retval -2 when an application cannot be found.
1884 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1886 struct ast_app *app;
1887 struct ast_call_feature *feature = data;
1888 struct ast_channel *work, *idle;
1891 if (!feature) { /* shouldn't ever happen! */
1892 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
1896 if (sense == FEATURE_SENSE_CHAN) {
1897 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1898 return AST_FEATURE_RETURN_KEEPTRYING;
1899 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1907 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1908 return AST_FEATURE_RETURN_KEEPTRYING;
1909 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1918 if (!(app = pbx_findapp(feature->app))) {
1919 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
1923 ast_autoservice_start(idle);
1925 if (!ast_strlen_zero(feature->moh_class))
1926 ast_moh_start(idle, feature->moh_class, NULL);
1928 res = pbx_exec(work, app, feature->app_args);
1930 if (!ast_strlen_zero(feature->moh_class))
1933 ast_autoservice_stop(idle);
1936 return AST_FEATURE_RETURN_SUCCESSBREAK;
1938 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
1941 static void unmap_features(void)
1945 ast_rwlock_wrlock(&features_lock);
1946 for (x = 0; x < FEATURES_COUNT; x++)
1947 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
1948 ast_rwlock_unlock(&features_lock);
1951 static int remap_feature(const char *name, const char *value)
1955 ast_rwlock_wrlock(&features_lock);
1956 for (x = 0; x < FEATURES_COUNT; x++) {
1957 if (strcasecmp(builtin_features[x].sname, name))
1960 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1964 ast_rwlock_unlock(&features_lock);
1970 * \brief Check the dynamic features
1971 * \param chan,peer,config,code,sense
1973 * Lock features list, browse for code, unlock list
1974 * \retval res on success.
1975 * \retval -1 on failure.
1977 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1980 struct ast_flags features;
1981 struct ast_call_feature *feature;
1982 struct feature_group *fg = NULL;
1983 struct feature_group_exten *fge;
1984 const char *dynamic_features;
1986 int res = AST_FEATURE_RETURN_PASSDIGITS;
1987 int feature_detected = 0;
1989 if (sense == FEATURE_SENSE_CHAN) {
1990 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
1991 dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1994 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
1995 dynamic_features = pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES");
1997 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);
1999 ast_rwlock_rdlock(&features_lock);
2000 for (x = 0; x < FEATURES_COUNT; x++) {
2001 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
2002 !ast_strlen_zero(builtin_features[x].exten)) {
2003 /* Feature is up for consideration */
2004 if (!strcmp(builtin_features[x].exten, code)) {
2005 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2006 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2007 feature_detected = 1;
2009 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2010 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2011 res = AST_FEATURE_RETURN_STOREDIGITS;
2015 ast_rwlock_unlock(&features_lock);
2017 if (ast_strlen_zero(dynamic_features) || feature_detected)
2020 tmp = ast_strdupa(dynamic_features);
2022 while ((tok = strsep(&tmp, "#"))) {
2023 AST_RWLIST_RDLOCK(&feature_groups);
2025 fg = find_group(tok);
2028 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2029 if (strcasecmp(fge->exten, code))
2032 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2033 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2034 AST_RWLIST_UNLOCK(&feature_groups);
2037 res = AST_FEATURE_RETURN_PASSDIGITS;
2043 AST_RWLIST_UNLOCK(&feature_groups);
2045 AST_RWLIST_RDLOCK(&feature_list);
2047 if (!(feature = find_dynamic_feature(tok))) {
2048 AST_RWLIST_UNLOCK(&feature_list);
2052 /* Feature is up for consideration */
2053 if (!strcmp(feature->exten, code)) {
2054 ast_verb(3, " Feature Found: %s exten: %s\n",feature->sname, tok);
2055 res = feature->operation(chan, peer, config, code, sense, feature);
2056 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2057 AST_RWLIST_UNLOCK(&feature_list);
2060 res = AST_FEATURE_RETURN_PASSDIGITS;
2061 } else if (!strncmp(feature->exten, code, strlen(code)))
2062 res = AST_FEATURE_RETURN_STOREDIGITS;
2064 AST_RWLIST_UNLOCK(&feature_list);
2070 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2074 ast_clear_flag(config, AST_FLAGS_ALL);
2076 ast_rwlock_rdlock(&features_lock);
2077 for (x = 0; x < FEATURES_COUNT; x++) {
2078 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2081 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2082 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2084 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2085 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2087 ast_rwlock_unlock(&features_lock);
2089 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2090 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2092 if (dynamic_features) {
2093 char *tmp = ast_strdupa(dynamic_features);
2095 struct ast_call_feature *feature;
2097 /* while we have a feature */
2098 while ((tok = strsep(&tmp, "#"))) {
2099 AST_RWLIST_RDLOCK(&feature_list);
2100 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2101 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2102 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2103 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2104 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2106 AST_RWLIST_UNLOCK(&feature_list);
2113 * \brief Get feature and dial
2114 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
2116 * Request channel, set channel variables, initiate call,check if they want to disconnect
2117 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2118 * check for answer break loop, set cdr return channel.
2120 * \todo XXX Check - this is very similar to the code in channel.c
2121 * \return always a channel
2123 static struct ast_channel *ast_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)
2128 struct ast_channel *chan;
2129 struct ast_channel *monitor_chans[2];
2130 struct ast_channel *active_channel;
2131 int res = 0, ready = 0;
2132 struct timeval started;
2134 char *disconnect_code = NULL, *dialed_code = NULL;
2136 if (!(chan = ast_request(type, format, data, &cause))) {
2137 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2139 case AST_CAUSE_BUSY:
2140 state = AST_CONTROL_BUSY;
2142 case AST_CAUSE_CONGESTION:
2143 state = AST_CONTROL_CONGESTION;
2149 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2150 ast_string_field_set(chan, language, language);
2151 ast_channel_inherit_variables(caller, chan);
2152 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2154 if (ast_call(chan, data, timeout)) {
2155 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2159 ast_indicate(caller, AST_CONTROL_RINGING);
2160 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2161 ast_rwlock_rdlock(&features_lock);
2162 for (x = 0; x < FEATURES_COUNT; x++) {
2163 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2166 disconnect_code = builtin_features[x].exten;
2167 len = strlen(disconnect_code) + 1;
2168 dialed_code = alloca(len);
2169 memset(dialed_code, 0, len);
2172 ast_rwlock_unlock(&features_lock);
2174 started = ast_tvnow();
2177 ast_poll_channel_add(caller, chan);
2179 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2180 struct ast_frame *f = NULL;
2182 monitor_chans[0] = caller;
2183 monitor_chans[1] = chan;
2184 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2186 /* see if the timeout has been violated */
2187 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2188 state = AST_CONTROL_UNHOLD;
2189 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2190 break; /*doh! timeout*/
2193 if (!active_channel)
2196 if (chan && (chan == active_channel)){
2198 if (f == NULL) { /*doh! where'd he go?*/
2199 state = AST_CONTROL_HANGUP;
2204 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2205 if (f->subclass == AST_CONTROL_RINGING) {
2206 state = f->subclass;
2207 ast_verb(3, "%s is ringing\n", chan->name);
2208 ast_indicate(caller, AST_CONTROL_RINGING);
2209 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
2210 state = f->subclass;
2211 ast_verb(3, "%s is busy\n", chan->name);
2212 ast_indicate(caller, AST_CONTROL_BUSY);
2216 } else if (f->subclass == AST_CONTROL_ANSWER) {
2217 /* This is what we are hoping for */
2218 state = f->subclass;
2223 } else if (f->subclass != -1) {
2224 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
2226 /* else who cares */
2229 } else if (caller && (active_channel == caller)) {
2230 f = ast_read(caller);
2231 if (f == NULL) { /*doh! where'd he go?*/
2232 if (!igncallerstate) {
2233 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2234 /* make this a blind transfer */
2238 state = AST_CONTROL_HANGUP;
2244 if (f->frametype == AST_FRAME_DTMF) {
2245 dialed_code[x++] = f->subclass;
2246 dialed_code[x] = '\0';
2247 if (strlen(dialed_code) == len) {
2249 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2251 dialed_code[x] = '\0';
2253 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2254 /* Caller Canceled the call */
2255 state = AST_CONTROL_UNHOLD;
2267 ast_poll_channel_del(caller, chan);
2270 ast_indicate(caller, -1);
2271 if (chan && ready) {
2272 if (chan->_state == AST_STATE_UP)
2273 state = AST_CONTROL_ANSWER;
2290 * \brief return the first unlocked cdr in a possible chain
2292 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2294 struct ast_cdr *cdr_orig = cdr;
2296 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2300 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2303 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2305 const char *feature;
2307 if (ast_strlen_zero(features)) {
2311 for (feature = features; *feature; feature++) {
2315 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2319 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2323 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2327 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2330 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2335 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2337 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2338 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2340 ast_channel_lock(caller);
2341 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2342 ast_channel_unlock(caller);
2343 if (!ds_caller_features) {
2344 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2345 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2348 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2349 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2350 ast_datastore_free(ds_caller_features);
2353 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2354 caller_features->is_caller = 1;
2355 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2356 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2357 ds_caller_features->data = caller_features;
2358 ast_channel_lock(caller);
2359 ast_channel_datastore_add(caller, ds_caller_features);
2360 ast_channel_unlock(caller);
2362 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2363 * flags over from the atxfer to the caller */
2367 ast_channel_lock(callee);
2368 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2369 ast_channel_unlock(callee);
2370 if (!ds_callee_features) {
2371 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2372 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2375 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2376 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2377 ast_datastore_free(ds_callee_features);
2380 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2381 callee_features->is_caller = 0;
2382 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2383 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2384 ds_callee_features->data = callee_features;
2385 ast_channel_lock(callee);
2386 ast_channel_datastore_add(callee, ds_callee_features);
2387 ast_channel_unlock(callee);
2394 * \brief bridge the call and set CDR
2395 * \param chan,peer,config
2397 * Set start time, check for two channels,check if monitor on
2398 * check for feature activation, create new CDR
2399 * \retval res on success.
2400 * \retval -1 on failure to bridge.
2402 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2404 /* Copy voice back and forth between the two channels. Give the peer
2405 the ability to transfer calls with '#<extension' syntax. */
2406 struct ast_frame *f;
2407 struct ast_channel *who;
2408 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2409 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2410 char orig_channame[AST_MAX_EXTENSION];
2411 char orig_peername[AST_MAX_EXTENSION];
2417 struct ast_option_header *aoh;
2418 struct ast_bridge_config backup_config;
2419 struct ast_cdr *bridge_cdr = NULL;
2420 struct ast_cdr *orig_peer_cdr = NULL;
2421 struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2422 struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2423 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2424 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2426 memset(&backup_config, 0, sizeof(backup_config));
2428 config->start_time = ast_tvnow();
2431 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2432 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2434 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2437 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
2438 add_features_datastores(chan, peer, config);
2440 /* This is an interesting case. One example is if a ringing channel gets redirected to
2441 * an extension that picks up a parked call. This will make sure that the call taken
2442 * out of parking gets told that the channel it just got bridged to is still ringing. */
2443 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
2444 ast_indicate(peer, AST_CONTROL_RINGING);
2448 const char *monitor_exec;
2449 struct ast_channel *src = NULL;
2451 if (!(monitor_app = pbx_findapp("Monitor")))
2454 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
2456 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2458 if (monitor_app && src) {
2459 char *tmp = ast_strdupa(monitor_exec);
2460 pbx_exec(src, monitor_app, tmp);
2464 set_config_flags(chan, peer, config);
2465 config->firstpass = 1;
2467 /* Answer if need be */
2468 if (ast_answer(chan))
2471 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
2472 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
2473 orig_peer_cdr = peer_cdr;
2475 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2478 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
2479 ast_cdr_update(chan);
2480 bridge_cdr = ast_cdr_dup(chan_cdr);
2481 ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2482 ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2484 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
2485 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
2486 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
2487 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
2488 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
2489 ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2490 ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2491 ast_cdr_setcid(bridge_cdr, chan);
2492 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
2493 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
2494 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
2495 /* Destination information */
2496 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
2497 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
2499 bridge_cdr->start = peer_cdr->start;
2500 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2502 ast_cdr_start(bridge_cdr);
2505 ast_debug(4,"bridge answer set, chan answer set\n");
2506 /* peer_cdr->answer will be set when a macro runs on the peer;
2507 in that case, the bridge answer will be delayed while the
2508 macro plays on the peer channel. The peer answered the call
2509 before the macro started playing. To the phone system,
2510 this is billable time for the call, even tho the caller
2511 hears nothing but ringing while the macro does its thing. */
2512 if (peer_cdr && !ast_tvzero(peer_cdr->answer)) {
2513 bridge_cdr->answer = peer_cdr->answer;
2514 chan_cdr->answer = peer_cdr->answer;
2515 bridge_cdr->disposition = peer_cdr->disposition;
2516 chan_cdr->disposition = peer_cdr->disposition;
2518 ast_cdr_answer(bridge_cdr);
2519 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
2521 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
2522 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
2524 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
2529 struct ast_channel *other; /* used later */
2531 res = ast_channel_bridge(chan, peer, config, &f, &who);
2533 if (config->feature_timer) {
2534 /* Update time limit for next pass */
2535 diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
2536 config->feature_timer -= diff;
2538 /* Running on backup config, meaning a feature might be being
2539 activated, but that's no excuse to keep things going
2541 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
2542 ast_debug(1, "Timed out, realtime this time!\n");
2543 config->feature_timer = 0;
2549 } else if (config->feature_timer <= 0) {
2550 /* Not *really* out of time, just out of time for
2551 digits to come in for features. */
2552 ast_debug(1, "Timed out for feature!\n");
2553 if (!ast_strlen_zero(peer_featurecode)) {
2554 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
2555 memset(peer_featurecode, 0, sizeof(peer_featurecode));
2557 if (!ast_strlen_zero(chan_featurecode)) {
2558 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
2559 memset(chan_featurecode, 0, sizeof(chan_featurecode));
2563 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2565 /* Restore original (possibly time modified) bridge config */
2566 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2567 memset(&backup_config, 0, sizeof(backup_config));
2569 hadfeatures = hasfeatures;
2570 /* Continue as we were */
2573 /* The bridge returned without a frame and there is a feature in progress.
2574 * However, we don't think the feature has quite yet timed out, so just
2575 * go back into the bridge. */
2579 if (config->feature_timer <=0) {
2580 /* We ran out of time */
2581 config->feature_timer = 0;
2591 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer))
2592 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
2596 if (!f || (f->frametype == AST_FRAME_CONTROL &&
2597 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY ||
2598 f->subclass == AST_CONTROL_CONGESTION))) {
2602 /* many things should be sent to the 'other' channel */
2603 other = (who == chan) ? peer : chan;
2604 if (f->frametype == AST_FRAME_CONTROL) {
2605 switch (f->subclass) {
2606 case AST_CONTROL_RINGING:
2607 case AST_CONTROL_FLASH:
2609 ast_indicate(other, f->subclass);
2611 case AST_CONTROL_HOLD:
2612 case AST_CONTROL_UNHOLD:
2613 ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
2615 case AST_CONTROL_OPTION:
2617 /* Forward option Requests */
2618 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2619 ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
2620 f->datalen - sizeof(struct ast_option_header), 0);
2624 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
2626 } else if (f->frametype == AST_FRAME_DTMF) {
2630 hadfeatures = hasfeatures;
2631 /* This cannot overrun because the longest feature is one shorter than our buffer */
2633 sense = FEATURE_SENSE_CHAN;
2634 featurecode = chan_featurecode;
2636 sense = FEATURE_SENSE_PEER;
2637 featurecode = peer_featurecode;
2639 /*! append the event to featurecode. we rely on the string being zero-filled, and
2640 * not overflowing it.
2641 * \todo XXX how do we guarantee the latter ?
2643 featurecode[strlen(featurecode)] = f->subclass;
2644 /* Get rid of the frame before we start doing "stuff" with the channels */
2647 config->feature_timer = backup_config.feature_timer;
2648 res = ast_feature_interpret(chan, peer, config, featurecode, sense);
2650 case AST_FEATURE_RETURN_PASSDIGITS:
2651 ast_dtmf_stream(other, who, featurecode, 0, 0);
2653 case AST_FEATURE_RETURN_SUCCESS:
2654 memset(featurecode, 0, sizeof(chan_featurecode));
2657 if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
2661 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2662 if (hadfeatures && !hasfeatures) {
2663 /* Restore backup */
2664 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2665 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
2666 } else if (hasfeatures) {
2668 /* Backup configuration */
2669 memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
2670 /* Setup temporary config options */
2671 config->play_warning = 0;
2672 ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
2673 ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
2674 config->warning_freq = 0;
2675 config->warning_sound = NULL;
2676 config->end_sound = NULL;
2677 config->start_sound = NULL;
2678 config->firstpass = 0;
2680 config->start_time = ast_tvnow();
2681 config->feature_timer = featuredigittimeout;
2682 ast_debug(1, "Set time limit to %ld\n", config->feature_timer);
2691 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
2692 ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
2694 ast_cdr_discard(bridge_cdr);
2695 /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
2697 return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
2700 if (config->end_bridge_callback) {
2701 config->end_bridge_callback(config->end_bridge_callback_data);
2704 /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
2705 * if it were, then chan belongs to a different thread now, and might have been hung up long
2708 if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
2709 ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
2710 struct ast_cdr *swapper = NULL;
2711 char savelastapp[AST_MAX_EXTENSION];
2712 char savelastdata[AST_MAX_EXTENSION];
2713 char save_exten[AST_MAX_EXTENSION];
2715 int found = 0; /* set if we find at least one match */
2716 int spawn_error = 0;
2718 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
2719 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
2720 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
2721 ast_cdr_end(bridge_cdr);
2723 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
2724 dialplan code operate on it */
2725 ast_channel_lock(chan);
2727 swapper = chan->cdr;
2728 ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
2729 ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
2730 chan->cdr = bridge_cdr;
2732 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
2733 save_prio = chan->priority;
2734 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
2736 ast_channel_unlock(chan);
2737 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
2740 if (found && spawn_error) {
2741 /* Something bad happened, or a hangup has been requested. */
2742 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2743 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2746 ast_channel_lock(chan);
2747 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
2748 chan->priority = save_prio;
2750 chan->cdr = swapper;
2751 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
2752 ast_channel_unlock(chan);
2753 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
2755 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
2756 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
2758 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2761 /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
2762 new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2763 if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
2764 ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
2766 /* we can post the bridge CDR at this point */
2768 ast_cdr_end(bridge_cdr);
2769 ast_cdr_detach(bridge_cdr);
2772 /* do a specialized reset on the beginning channel
2773 CDR's, if they still exist, so as not to mess up
2774 issues in future bridges;
2776 Here are the rules of the game:
2777 1. The chan and peer channel pointers will not change
2778 during the life of the bridge.
2779 2. But, in transfers, the channel names will change.
2780 between the time the bridge is started, and the
2781 time the channel ends.
2782 Usually, when a channel changes names, it will
2783 also change CDR pointers.
2784 3. Usually, only one of the two channels (chan or peer)
2786 4. Usually, if a channel changes names during a bridge,
2787 it is because of a transfer. Usually, in these situations,
2788 it is normal to see 2 bridges running simultaneously, and
2789 it is not unusual to see the two channels that change
2790 swapped between bridges.
2791 5. After a bridge occurs, we have 2 or 3 channels' CDRs
2792 to attend to; if the chan or peer changed names,
2793 we have the before and after attached CDR's.
2797 struct ast_channel *chan_ptr = NULL;
2799 if (strcasecmp(orig_channame, chan->name) != 0) {
2801 chan_ptr = ast_get_channel_by_name_locked(orig_channame);
2803 if (!ast_bridged_channel(chan_ptr)) {
2804 struct ast_cdr *cur;
2805 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2806 if (cur == chan_cdr) {
2811 ast_cdr_specialized_reset(chan_cdr,0);
2813 ast_channel_unlock(chan_ptr);
2816 ast_cdr_specialized_reset(new_chan_cdr,0);
2818 ast_cdr_specialized_reset(chan_cdr,0); /* nothing changed, reset the chan_cdr */
2823 struct ast_channel *chan_ptr = NULL;
2824 new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2825 if (new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED) && new_peer_cdr && !ast_test_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED))
2826 ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
2827 if (strcasecmp(orig_peername, peer->name) != 0) {
2829 chan_ptr = ast_get_channel_by_name_locked(orig_peername);
2831 if (!ast_bridged_channel(chan_ptr)) {
2832 struct ast_cdr *cur;
2833 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2834 if (cur == peer_cdr) {
2839 ast_cdr_specialized_reset(peer_cdr,0);
2841 ast_channel_unlock(chan_ptr);
2844 ast_cdr_specialized_reset(new_peer_cdr,0);
2846 ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr */
2853 /*! \brief Output parking event to manager */
2854 static void post_manager_event(const char *s, struct parkeduser *pu)
2856 manager_event(EVENT_FLAG_CALL, s,
2859 "Parkinglot: %s\r\n"
2860 "CallerIDNum: %s\r\n"
2861 "CallerIDName: %s\r\n"
2862 "UniqueID: %s\r\n\r\n",
2865 pu->parkinglot->name,
2866 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2867 S_OR(pu->chan->cid.cid_name, "<unknown>"),
2872 static char *callback_dialoptions(struct ast_flags *features_callee, struct ast_flags *features_caller, char *options, size_t len)
2876 OPT_CALLEE_REDIRECT = 't',
2877 OPT_CALLER_REDIRECT = 'T',
2878 OPT_CALLEE_AUTOMON = 'w',
2879 OPT_CALLER_AUTOMON = 'W',
2880 OPT_CALLEE_DISCONNECT = 'h',
2881 OPT_CALLER_DISCONNECT = 'H',
2882 OPT_CALLEE_PARKCALL = 'k',
2883 OPT_CALLER_PARKCALL = 'K',
2886 memset(options, 0, len);
2887 if (ast_test_flag(features_caller, AST_FEATURE_REDIRECT) && i < len) {
2888 options[i++] = OPT_CALLER_REDIRECT;
2890 if (ast_test_flag(features_caller, AST_FEATURE_AUTOMON) && i < len) {
2891 options[i++] = OPT_CALLER_AUTOMON;
2893 if (ast_test_flag(features_caller, AST_FEATURE_DISCONNECT) && i < len) {
2894 options[i++] = OPT_CALLER_DISCONNECT;
2896 if (ast_test_flag(features_caller, AST_FEATURE_PARKCALL) && i < len) {
2897 options[i++] = OPT_CALLER_PARKCALL;
2900 if (ast_test_flag(features_callee, AST_FEATURE_REDIRECT) && i < len) {
2901 options[i++] = OPT_CALLEE_REDIRECT;
2903 if (ast_test_flag(features_callee, AST_FEATURE_AUTOMON) && i < len) {
2904 options[i++] = OPT_CALLEE_AUTOMON;
2906 if (ast_test_flag(features_callee, AST_FEATURE_DISCONNECT) && i < len) {
2907 options[i++] = OPT_CALLEE_DISCONNECT;
2909 if (ast_test_flag(features_callee, AST_FEATURE_PARKCALL) && i < len) {
2910 options[i++] = OPT_CALLEE_PARKCALL;
2916 /*! \brief Run management on parkinglots, called once per parkinglot */
2917 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
2920 struct parkeduser *pu;
2922 char parkingslot[AST_MAX_EXTENSION];
2924 /* Lock parking list */
2925 AST_LIST_LOCK(&curlot->parkings);
2926 AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
2927 struct ast_channel *chan = pu->chan; /* shorthand */
2928 int tms; /* timeout for this item */
2929 int x; /* fd index in channel */
2930 struct ast_context *con;
2932 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
2935 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2936 if (tms > pu->parkingtime) {
2937 /* Stop music on hold */
2938 ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
2939 /* Get chan, exten from derived kludge */
2940 if (pu->peername[0]) {
2941 char *peername = ast_strdupa(pu->peername);
2942 char *cp = strrchr(peername, '-');
2943 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
2948 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
2949 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
2950 if (peername_flat[i] == '/')
2951 peername_flat[i]= '0';
2953 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
2955 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
2958 char returnexten[AST_MAX_EXTENSION];
2959 struct ast_datastore *features_datastore;
2960 struct ast_dial_features *dialfeatures = NULL;
2962 ast_channel_lock(chan);
2964 if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2965 dialfeatures = features_datastore->data;
2967 ast_channel_unlock(chan);
2969 if (!strncmp(peername, "Parked/", 7)) {
2974 char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
2975 snprintf(returnexten, sizeof(returnexten), "%s|30|%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
2976 } else { /* Existing default */
2977 ast_log(LOG_WARNING, "Dialfeatures not found on %s, using default!\n", chan->name);
2978 snprintf(returnexten, sizeof(returnexten), "%s|30|t", peername);
2981 ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2983 if (comebacktoorigin) {
2984 set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
2986 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2987 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2988 pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
2989 set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2992 /* They've been waiting too long, send them back to where they came. Theoretically they
2993 should have their original extensions and such, but we copy to be on the safe side */
2994 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2996 post_manager_event("ParkedCallTimeOut", pu);
2998 ast_verb(2, "Timeout for %s parked on %d (%s). Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->chan->context, pu->chan->exten, pu->chan->priority);
2999 /* Start up the PBX, or hang them up */
3000 if (ast_pbx_start(chan)) {
3001 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
3004 /* And take them out of the parking lot */
3005 con = ast_context_find(pu->parkinglot->parking_con);