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>
157 <manager name="ParkedCalls" language="en_US">
162 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
165 <para>List parked calls.</para>
168 <manager name="Park" language="en_US">
173 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
174 <parameter name="Channel" required="true">
175 <para>Channel name to park.</para>
177 <parameter name="Channel2" required="true">
178 <para>Channel to announce park info to (and return to if timeout).</para>
180 <parameter name="Timeout">
181 <para>Number of milliseconds to wait before callback.</para>
185 <para>Park a channel.</para>
188 <manager name="Bridge" language="en_US">
190 Bridge two channels already in the PBX.
193 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
194 <parameter name="Channel1" required="true">
195 <para>Channel to Bridge to Channel2.</para>
197 <parameter name="Channel2" required="true">
198 <para>Channel to Bridge to Channel1.</para>
200 <parameter name="Tone">
201 <para>Play courtesy tone to Channel 2.</para>
209 <para>Bridge together two channels already in the PBX.</para>
214 #define DEFAULT_PARK_TIME 45000
215 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
216 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000
217 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
218 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
219 #define DEFAULT_ATXFER_DROP_CALL 0
220 #define DEFAULT_ATXFER_LOOP_DELAY 10000
221 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
223 #define AST_MAX_WATCHERS 256
224 #define MAX_DIAL_FEATURE_OPTIONS 30
226 struct feature_group_exten {
227 AST_LIST_ENTRY(feature_group_exten) entry;
228 AST_DECLARE_STRING_FIELDS(
229 AST_STRING_FIELD(exten);
231 struct ast_call_feature *feature;
234 struct feature_group {
235 AST_LIST_ENTRY(feature_group) entry;
236 AST_DECLARE_STRING_FIELDS(
237 AST_STRING_FIELD(gname);
239 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
242 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
244 static char *parkedcall = "ParkedCall";
246 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
248 /*! \brief Description of one parked call, added to a list while active, then removed.
249 The list belongs to a parkinglot
252 struct ast_channel *chan; /*!< Parking channel */
253 struct timeval start; /*!< Time the parking started */
254 int parkingnum; /*!< Parking lot */
255 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
256 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
257 char exten[AST_MAX_EXTENSION];
259 int parkingtime; /*!< Maximum length in parking lot before return */
262 unsigned char moh_trys;
263 struct ast_parkinglot *parkinglot;
264 AST_LIST_ENTRY(parkeduser) list;
267 /*! \brief Structure for parking lots which are put in a container. */
268 struct ast_parkinglot {
269 char name[AST_MAX_CONTEXT];
270 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
271 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
272 int parking_start; /*!< First available extension for parking */
273 int parking_stop; /*!< Last available extension for parking */
276 int parkingtime; /*!< Default parking time */
277 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
278 int parkaddhints; /*!< Add parking hints automatically */
279 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
280 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
281 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
282 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
283 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
286 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
287 static struct ao2_container *parkinglots;
289 struct ast_parkinglot *default_parkinglot;
290 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
292 static char courtesytone[256]; /*!< Courtesy tone */
293 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
294 static char xfersound[256]; /*!< Call transfer sound */
295 static char xferfailsound[256]; /*!< Call transfer failure sound */
296 static char pickupsound[256]; /*!< Pickup sound */
297 static char pickupfailsound[256]; /*!< Pickup failure sound */
301 static int transferdigittimeout;
302 static int featuredigittimeout;
303 static int comebacktoorigin = 1;
305 static int atxfernoanswertimeout;
306 static unsigned int atxferdropcall;
307 static unsigned int atxferloopdelay;
308 static unsigned int atxfercallbackretries;
310 static char *registrar = "features"; /*!< Registrar for operations */
312 /* module and CLI command definitions */
313 static char *parkcall = PARK_APP_NAME;
315 static struct ast_app *monitor_app = NULL;
316 static int monitor_ok = 1;
318 static struct ast_app *mixmonitor_app = NULL;
319 static int mixmonitor_ok = 1;
321 static struct ast_app *stopmixmonitor_app = NULL;
322 static int stopmixmonitor_ok = 1;
324 static pthread_t parking_thread;
325 struct ast_dial_features {
326 struct ast_flags features_caller;
327 struct ast_flags features_callee;
331 static void *dial_features_duplicate(void *data)
333 struct ast_dial_features *df = data, *df_copy;
335 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
339 memcpy(df_copy, df, sizeof(*df));
344 static void dial_features_destroy(void *data)
346 struct ast_dial_features *df = data;
352 static const struct ast_datastore_info dial_features_info = {
353 .type = "dial-features",
354 .destroy = dial_features_destroy,
355 .duplicate = dial_features_duplicate,
358 /* Forward declarations */
359 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
360 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
361 static void parkinglot_destroy(void *obj);
362 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
363 struct ast_parkinglot *find_parkinglot(const char *name);
366 const char *ast_parking_ext(void)
371 const char *ast_pickup_ext(void)
376 struct ast_bridge_thread_obj
378 struct ast_bridge_config bconfig;
379 struct ast_channel *chan;
380 struct ast_channel *peer;
381 unsigned int return_to_pbx:1;
384 static int parkinglot_hash_cb(const void *obj, const int flags)
386 const struct ast_parkinglot *parkinglot = obj;
388 return ast_str_case_hash(parkinglot->name);
391 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
393 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
395 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
399 * \brief store context, extension and priority
400 * \param chan, context, ext, pri
402 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
404 ast_copy_string(chan->context, context, sizeof(chan->context));
405 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
406 chan->priority = pri;
410 * \brief Check goto on transfer
413 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
414 * When found make sure the types are compatible. Check if channel is valid
415 * if so start the new channel else hangup the call.
417 static void check_goto_on_transfer(struct ast_channel *chan)
419 struct ast_channel *xferchan;
420 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
421 char *x, *goto_on_transfer;
424 if (ast_strlen_zero(val))
427 goto_on_transfer = ast_strdupa(val);
429 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", chan->name)))
432 for (x = goto_on_transfer; x && *x; x++) {
436 /* Make formats okay */
437 xferchan->readformat = chan->readformat;
438 xferchan->writeformat = chan->writeformat;
439 ast_channel_masquerade(xferchan, chan);
440 ast_parseable_goto(xferchan, goto_on_transfer);
441 xferchan->_state = AST_STATE_UP;
442 ast_clear_flag(xferchan, AST_FLAGS_ALL);
443 xferchan->_softhangup = 0;
444 if ((f = ast_read(xferchan))) {
447 ast_pbx_start(xferchan);
449 ast_hangup(xferchan);
453 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language);
456 * \brief bridge the call
457 * \param data thread bridge.
459 * Set Last Data for respective channels, reset cdr for channels
460 * bridge call, check if we're going back to dialplan
461 * if not hangup both legs of the call
463 static void *bridge_call_thread(void *data)
465 struct ast_bridge_thread_obj *tobj = data;
468 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
469 tobj->chan->data = tobj->peer->name;
470 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
471 tobj->peer->data = tobj->chan->name;
473 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
475 if (tobj->return_to_pbx) {
476 if (!ast_check_hangup(tobj->peer)) {
477 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
478 res = ast_pbx_start(tobj->peer);
479 if (res != AST_PBX_SUCCESS)
480 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
482 ast_hangup(tobj->peer);
483 if (!ast_check_hangup(tobj->chan)) {
484 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
485 res = ast_pbx_start(tobj->chan);
486 if (res != AST_PBX_SUCCESS)
487 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
489 ast_hangup(tobj->chan);
491 ast_hangup(tobj->chan);
492 ast_hangup(tobj->peer);
501 * \brief create thread for the parked call
504 * Create thread and attributes, call bridge_call_thread
506 static void bridge_call_thread_launch(void *data)
510 struct sched_param sched;
512 pthread_attr_init(&attr);
513 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
514 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
515 pthread_attr_destroy(&attr);
516 memset(&sched, 0, sizeof(sched));
517 pthread_setschedparam(thread, SCHED_RR, &sched);
521 * \brief Announce call parking by ADSI
523 * \param parkingexten .
524 * Create message to show for ADSI, display message.
525 * \retval 0 on success.
526 * \retval -1 on failure.
528 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
531 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
533 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
535 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
537 res = ast_adsi_load_session(chan, NULL, 0, 1);
540 return ast_adsi_print(chan, message, justify, 1);
543 /*! \brief Find parking lot name from channel */
544 static const char *findparkinglotname(struct ast_channel *chan)
546 const char *temp, *parkinglot = NULL;
548 /* Check if the channel has a parking lot */
549 if (!ast_strlen_zero(chan->parkinglot))
550 parkinglot = chan->parkinglot;
552 /* Channel variables override everything */
554 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
560 /*! \brief Notify metermaids that we've changed an extension */
561 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
563 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
564 exten, context, ast_devstate2str(state));
566 ast_devstate_changed(state, "park:%s@%s", exten, context);
569 /*! \brief metermaids callback from devicestate.c */
570 static enum ast_device_state metermaidstate(const char *data)
575 context = ast_strdupa(data);
577 exten = strsep(&context, "@");
579 return AST_DEVICE_INVALID;
581 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
583 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
584 return AST_DEVICE_NOT_INUSE;
586 return AST_DEVICE_INUSE;
589 /*! Options to pass to park_call_full */
590 enum ast_park_call_options {
591 /*! Provide ringing to the parked caller instead of music on hold */
592 AST_PARK_OPT_RINGING = (1 << 0),
593 /*! Randomly choose a parking spot for the caller instead of choosing
594 * the first one that is available. */
595 AST_PARK_OPT_RANDOMIZE = (1 << 1),
596 /*! Do not announce the parking number */
597 AST_PARK_OPT_SILENCE = (1 << 2),
600 struct ast_park_call_args {
601 /*! How long to wait in the parking lot before the call gets sent back
602 * to the specified return extension (or a best guess at where it came
603 * from if not explicitly specified). */
605 /*! An output parameter to store the parking space where the parked caller
608 const char *orig_chan_name;
609 const char *return_con;
610 const char *return_ext;
613 /*! Parked user that has already obtained a parking space */
614 struct parkeduser *pu;
617 static struct parkeduser *park_space_reserve(struct ast_channel *chan,
618 struct ast_channel *peer, struct ast_park_call_args *args)
620 struct parkeduser *pu;
621 int i, parking_space = -1, parking_range;
622 const char *parkinglotname = NULL;
623 const char *parkingexten;
624 struct ast_parkinglot *parkinglot = NULL;
627 parkinglotname = findparkinglotname(peer);
629 if (parkinglotname) {
631 ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
632 parkinglot = find_parkinglot(parkinglotname);
635 parkinglot = default_parkinglot;
637 parkinglot_addref(parkinglot);
639 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
641 /* Allocate memory for parking data */
642 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
643 parkinglot_unref(parkinglot);
647 /* Lock parking list */
648 AST_LIST_LOCK(&parkinglot->parkings);
649 /* Check for channel variable PARKINGEXTEN */
650 parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
651 if (!ast_strlen_zero(parkingexten)) {
652 /*!\note The API forces us to specify a numeric parking slot, even
653 * though the architecture would tend to support non-numeric extensions
654 * (as are possible with SIP, for example). Hence, we enforce that
655 * limitation here. If extout was not numeric, we could permit
656 * arbitrary non-numeric extensions.
658 if (sscanf(parkingexten, "%d", &parking_space) != 1 || parking_space < 0) {
659 AST_LIST_UNLOCK(&parkinglot->parkings);
660 parkinglot_unref(parkinglot);
662 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
665 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
667 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
668 AST_LIST_UNLOCK(&parkinglot->parkings);
669 parkinglot_unref(parkinglot);
671 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
676 struct parkeduser *cur = NULL;
678 /* Select parking space within range */
679 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
681 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
682 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
684 start = parkinglot->parking_start;
687 for (i = start; 1; i++) {
688 if (i == parkinglot->parking_stop + 1) {
689 i = parkinglot->parking_start - 1;
693 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
694 if (cur->parkingnum == i) {
699 if (!cur || i == start - 1) {
705 if (i == start - 1 && cur) {
706 ast_log(LOG_WARNING, "No more parking spaces\n");
708 AST_LIST_UNLOCK(&parkinglot->parkings);
709 parkinglot_unref(parkinglot);
712 /* Set pointer for next parking */
713 if (parkinglot->parkfindnext)
714 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
715 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
719 pu->parkingnum = parking_space;
720 pu->parkinglot = parkinglot;
721 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
722 parkinglot_unref(parkinglot);
728 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
730 struct ast_context *con;
732 struct parkeduser *pu = args->pu;
733 const char *event_from;
736 pu = park_space_reserve(chan, peer, args);
738 return 1; /* Continue execution if possible */
740 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
742 chan->appl = "Parked Call";
747 /* Put the parked channel on hold if we have two different channels */
749 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
750 ast_indicate(pu->chan, AST_CONTROL_RINGING);
752 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
753 S_OR(pu->parkinglot->mohclass, NULL),
754 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
758 pu->start = ast_tvnow();
759 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
760 parkingnum_copy = pu->parkingnum;
762 *(args->extout) = pu->parkingnum;
765 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
766 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
767 and we need the callback name to be that of transferer. Since local,1/2 have the same
768 name we can be tricky and just grab the bridged channel from the other side of the local
770 if (!strcasecmp(peer->tech->type, "Local")) {
771 struct ast_channel *tmpchan, *base_peer;
772 char other_side[AST_CHANNEL_NAME];
774 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
775 if ((c = strrchr(other_side, ';'))) {
778 if ((tmpchan = ast_channel_get_by_name(other_side))) {
779 ast_channel_lock(tmpchan);
780 if ((base_peer = ast_bridged_channel(tmpchan))) {
781 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
783 ast_channel_unlock(tmpchan);
784 tmpchan = ast_channel_unref(tmpchan);
787 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
791 /* Remember what had been dialed, so that if the parking
792 expires, we try to come back to the same place */
793 ast_copy_string(pu->context,
794 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
795 sizeof(pu->context));
796 ast_copy_string(pu->exten,
797 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
799 pu->priority = pu->priority ? pu->priority :
800 (chan->macropriority ? chan->macropriority : chan->priority);
802 /* If parking a channel directly, don't quiet yet get parking running on it.
803 * All parking lot entries are put into the parking lot with notquiteyet on. */
807 /* Wake up the (presumably select()ing) thread */
808 pthread_kill(parking_thread, SIGURG);
809 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));
812 event_from = peer->name;
814 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
817 manager_event(EVENT_FLAG_CALL, "ParkedCall",
823 "CallerIDNum: %s\r\n"
824 "CallerIDName: %s\r\n"
826 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
827 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
828 S_OR(pu->chan->cid.cid_num, "<unknown>"),
829 S_OR(pu->chan->cid.cid_name, "<unknown>"),
833 if (peer && adsipark && ast_adsi_available(peer)) {
834 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
835 ast_adsi_unload_session(peer);
838 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
839 if (!con) /* Still no context? Bad */
840 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
842 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
843 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
846 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
848 /* Only say number if it's a number and the channel hasn't been masqueraded away */
849 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
850 /* 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. */
851 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
852 /* Tell the peer channel the number of the parking space */
853 ast_say_digits(peer, pu->parkingnum, "", peer->language);
854 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
856 if (peer == chan) { /* pu->notquiteyet = 1 */
857 /* Wake up parking thread if we're really done */
858 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
859 S_OR(pu->parkinglot->mohclass, NULL),
860 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
862 pthread_kill(parking_thread, SIGURG);
867 /*! \brief Park a call */
868 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
870 struct ast_park_call_args args = {
875 return park_call_full(chan, peer, &args);
878 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)
880 struct ast_channel *chan;
883 struct ast_park_call_args park_args = {0,};
887 args->timeout = timeout;
888 args->extout = extout;
891 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
893 ast_stream_and_wait(peer, "beeperr", "");
894 return AST_FEATURE_RETURN_PARKFAILED;
897 /* Make a new, fake channel that we'll use to masquerade in the real one */
898 if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
899 ast_log(LOG_WARNING, "Unable to create parked channel\n");
903 /* Make formats okay */
904 chan->readformat = rchan->readformat;
905 chan->writeformat = rchan->writeformat;
906 ast_channel_masquerade(chan, rchan);
908 /* Setup the extensions and such */
909 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
911 /* Make the masq execute */
912 if ((f = ast_read(chan)))
919 if (!play_announcement && args == &park_args) {
920 args->orig_chan_name = ast_strdupa(chan->name);
923 park_status = park_call_full(chan, peer, args);
924 if (park_status == 1) {
925 /* would be nice to play "invalid parking extension" */
933 /* Park call via masquraded channel */
934 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
936 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
939 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
941 return masq_park_call(rchan, peer, 0, NULL, 1, args);
944 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
946 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
950 * \brief set caller and callee according to the direction
951 * \param caller, callee, peer, chan, sense
953 * Detect who triggered feature and set callee/caller variables accordingly
955 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
956 struct ast_channel *peer, struct ast_channel *chan, int sense)
958 if (sense == FEATURE_SENSE_PEER) {
968 * \brief support routing for one touch call parking
969 * \param chan channel parking call
970 * \param peer channel to be parked
971 * \param config unsed
973 * \param sense feature options
976 * Setup channel, set return exten,priority to 's,1'
977 * answer chan, sleep chan, park call
979 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
981 struct ast_channel *parker;
982 struct ast_channel *parkee;
985 set_peers(&parker, &parkee, peer, chan, sense);
986 /* we used to set chan's exten and priority to "s" and 1
987 here, but this generates (in some cases) an invalid
988 extension, and if "s" exists, could errantly
989 cause execution of extensions you don't expect. It
990 makes more sense to let nature take its course
991 when chan finishes, and let the pbx do its thing
992 and hang up when the park is over.
994 if (chan->_state != AST_STATE_UP)
995 res = ast_answer(chan);
997 res = ast_safe_sleep(chan, 1000);
999 if (!res) { /* one direction used to call park_call.... */
1000 res = masq_park_call_announce(parkee, parker, 0, NULL);
1001 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
1007 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1008 other channel during the message, so please don't use this for very long messages
1010 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1012 /* First play for caller, put other channel on auto service */
1013 if (ast_autoservice_start(callee_chan))
1015 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
1016 ast_log(LOG_WARNING, "Failed to play automon message!\n");
1017 ast_autoservice_stop(callee_chan);
1020 if (ast_autoservice_stop(callee_chan))
1022 /* Then play for callee, put other channel on auto service */
1023 if (ast_autoservice_start(caller_chan))
1025 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
1026 ast_log(LOG_WARNING, "Failed to play automon message !\n");
1027 ast_autoservice_stop(caller_chan);
1030 if (ast_autoservice_stop(caller_chan))
1036 * \brief Monitor a channel by DTMF
1037 * \param chan channel requesting monitor
1038 * \param peer channel to be monitored
1041 * \param sense feature options
1044 * Check monitor app enabled, setup channels, both caller/callee chans not null
1045 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
1046 * \retval AST_FEATURE_RETURN_SUCCESS on success.
1047 * \retval -1 on error.
1049 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1051 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1054 struct ast_channel *caller_chan, *callee_chan;
1055 const char *automon_message_start = NULL;
1056 const char *automon_message_stop = NULL;
1059 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1063 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1065 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1069 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1070 if (caller_chan) { /* Find extra messages */
1071 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1072 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1075 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1076 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1081 if (callee_chan->monitor) {
1082 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1083 if (!ast_strlen_zero(automon_message_stop)) {
1084 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1086 callee_chan->monitor->stop(callee_chan, 1);
1087 return AST_FEATURE_RETURN_SUCCESS;
1090 if (caller_chan && callee_chan) {
1091 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1092 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1093 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1096 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1099 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1101 if (!touch_monitor_prefix)
1102 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1104 if (touch_monitor) {
1105 len = strlen(touch_monitor) + 50;
1107 touch_filename = alloca(len);
1108 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1109 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1111 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1112 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1113 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1115 touch_filename = alloca(len);
1116 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1117 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1120 for(x = 0; x < strlen(args); x++) {
1125 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1127 pbx_exec(callee_chan, monitor_app, args);
1128 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1129 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1131 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1132 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1135 return AST_FEATURE_RETURN_SUCCESS;
1138 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1142 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1144 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1147 struct ast_channel *caller_chan, *callee_chan;
1148 const char *mixmonitor_spy_type = "MixMonitor";
1151 if (!mixmonitor_ok) {
1152 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1156 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1158 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1162 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1164 if (!ast_strlen_zero(courtesytone)) {
1165 if (ast_autoservice_start(callee_chan))
1167 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1168 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1169 ast_autoservice_stop(callee_chan);
1172 if (ast_autoservice_stop(callee_chan))
1176 ast_channel_lock(callee_chan);
1177 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1178 ast_channel_unlock(callee_chan);
1180 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1183 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1185 /* Make sure they are running */
1186 ast_channel_lock(callee_chan);
1187 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1188 ast_channel_unlock(callee_chan);
1190 if (!stopmixmonitor_ok) {
1191 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1194 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1195 stopmixmonitor_ok = 0;
1196 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1199 pbx_exec(callee_chan, stopmixmonitor_app, "");
1200 return AST_FEATURE_RETURN_SUCCESS;
1204 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1207 if (caller_chan && callee_chan) {
1208 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1209 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1212 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1215 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1217 if (touch_monitor) {
1218 len = strlen(touch_monitor) + 50;
1220 touch_filename = alloca(len);
1221 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1222 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1224 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1225 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1226 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1228 touch_filename = alloca(len);
1229 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1230 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1233 for( x = 0; x < strlen(args); x++) {
1238 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1240 pbx_exec(callee_chan, mixmonitor_app, args);
1241 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1242 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1243 return AST_FEATURE_RETURN_SUCCESS;
1247 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1252 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1254 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1255 return AST_FEATURE_RETURN_HANGUP;
1258 static int finishup(struct ast_channel *chan)
1260 ast_indicate(chan, AST_CONTROL_UNHOLD);
1262 return ast_autoservice_stop(chan);
1266 * \brief Find the context for the transfer
1270 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1271 * \return a context string
1273 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1275 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1276 if (ast_strlen_zero(s)) {
1277 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1279 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1280 s = transferer->macrocontext;
1282 if (ast_strlen_zero(s)) {
1283 s = transferer->context;
1289 * \brief Blind transfer user to another extension
1290 * \param chan channel to be transfered
1291 * \param peer channel initiated blind transfer
1295 * \param sense feature options
1297 * Place chan on hold, check if transferred to parkinglot extension,
1298 * otherwise check extension exists and transfer caller.
1299 * \retval AST_FEATURE_RETURN_SUCCESS.
1300 * \retval -1 on failure.
1302 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1304 struct ast_channel *transferer;
1305 struct ast_channel *transferee;
1306 const char *transferer_real_context;
1308 int res, parkstatus = 0;
1310 set_peers(&transferer, &transferee, peer, chan, sense);
1311 transferer_real_context = real_ctx(transferer, transferee);
1312 /* Start autoservice on chan while we talk to the originator */
1313 ast_autoservice_start(transferee);
1314 ast_indicate(transferee, AST_CONTROL_HOLD);
1316 memset(xferto, 0, sizeof(xferto));
1319 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1321 finishup(transferee);
1322 return -1; /* error ? */
1324 if (res > 0) /* If they've typed a digit already, handle it */
1325 xferto[0] = (char) res;
1327 ast_stopstream(transferer);
1328 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1329 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1330 finishup(transferee);
1333 if (!strcmp(xferto, ast_parking_ext())) {
1334 res = finishup(transferee);
1337 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1338 /* We return non-zero, but tell the PBX not to hang the channel when
1339 the thread dies -- We have to be careful now though. We are responsible for
1340 hanging up the channel, else it will never be hung up! */
1344 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1346 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1347 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1348 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1349 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1350 res=finishup(transferee);
1351 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1352 transferer->cdr=ast_cdr_alloc();
1353 if (transferer->cdr) {
1354 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
1355 ast_cdr_start(transferer->cdr);
1358 if (transferer->cdr) {
1359 struct ast_cdr *swap = transferer->cdr;
1360 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1361 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1362 transferer->cdr->channel, transferer->cdr->dstchannel);
1363 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1364 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1365 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1366 /* swap cdrs-- it will save us some time & work */
1367 transferer->cdr = transferee->cdr;
1368 transferee->cdr = swap;
1370 if (!transferee->pbx) {
1371 /* Doh! Use our handy async_goto functions */
1372 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1373 ,transferee->name, xferto, transferer_real_context);
1374 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1375 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1377 /* Set the channel's new extension, since it exists, using transferer context */
1378 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1379 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1380 if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
1381 ast_channel_update_connected_line(transferee, &transferer->connected);
1383 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1385 check_goto_on_transfer(transferer);
1388 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1390 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1391 finishup(transferee);
1394 ast_stopstream(transferer);
1395 res = finishup(transferee);
1397 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1400 return AST_FEATURE_RETURN_SUCCESS;
1404 * \brief make channels compatible
1407 * \retval 0 on success.
1408 * \retval -1 on failure.
1410 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1412 if (ast_channel_make_compatible(c, newchan) < 0) {
1413 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1414 c->name, newchan->name);
1415 ast_hangup(newchan);
1422 * \brief Attended transfer
1423 * \param chan transfered user
1424 * \param peer person transfering call
1427 * \param sense feature options
1430 * Get extension to transfer to, if you cannot generate channel (or find extension)
1431 * return to host channel. After called channel answered wait for hangup of transferer,
1432 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1434 * \return -1 on failure
1436 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1438 struct ast_channel *transferer;
1439 struct ast_channel *transferee;
1440 const char *transferer_real_context;
1441 char xferto[256] = "";
1444 struct ast_channel *newchan;
1445 struct ast_channel *xferchan;
1446 struct ast_bridge_thread_obj *tobj;
1447 struct ast_bridge_config bconfig;
1448 struct ast_frame *f;
1450 struct ast_party_connected_line connected_line;
1451 struct ast_datastore *features_datastore;
1452 struct ast_dial_features *dialfeatures = NULL;
1454 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1455 set_peers(&transferer, &transferee, peer, chan, sense);
1456 transferer_real_context = real_ctx(transferer, transferee);
1457 /* Start autoservice on chan while we talk to the originator */
1458 ast_autoservice_start(transferee);
1459 ast_indicate(transferee, AST_CONTROL_HOLD);
1462 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1464 finishup(transferee);
1467 if (res > 0) /* If they've typed a digit already, handle it */
1468 xferto[0] = (char) res;
1470 /* this is specific of atxfer */
1471 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1472 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1473 finishup(transferee);
1477 ast_log(LOG_WARNING, "Did not read data.\n");
1478 finishup(transferee);
1479 if (ast_stream_and_wait(transferer, "beeperr", ""))
1481 return AST_FEATURE_RETURN_SUCCESS;
1484 /* valid extension, res == 1 */
1485 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1486 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1487 finishup(transferee);
1488 if (ast_stream_and_wait(transferer, "beeperr", ""))
1490 return AST_FEATURE_RETURN_SUCCESS;
1493 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1494 * the different variables for handling this properly with a builtin_atxfer */
1495 if (!strcmp(xferto, ast_parking_ext())) {
1496 finishup(transferee);
1497 return builtin_parkcall(chan, peer, config, code, sense, data);
1501 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1503 /* If we are performing an attended transfer and we have two channels involved then
1504 copy sound file information to play upon attended transfer completion */
1506 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1507 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1509 if (!ast_strlen_zero(chan1_attended_sound)) {
1510 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1512 if (!ast_strlen_zero(chan2_attended_sound)) {
1513 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1517 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1518 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1520 ast_party_connected_line_init(&connected_line);
1521 if (!ast_check_hangup(transferer)) {
1522 /* Transferer is up - old behaviour */
1523 ast_indicate(transferer, -1);
1525 finishup(transferee);
1526 /* any reason besides user requested cancel and busy triggers the failed sound */
1527 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1528 ast_stream_and_wait(transferer, xferfailsound, ""))
1530 if (ast_stream_and_wait(transferer, xfersound, ""))
1531 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1532 return AST_FEATURE_RETURN_SUCCESS;
1535 if (check_compat(transferer, newchan)) {
1536 /* we do mean transferee here, NOT transferer */
1537 finishup(transferee);
1540 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1541 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1542 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1543 /* We need to get the transferer's connected line information copied
1544 * at this point because he is likely to hang up during the bridge with
1545 * newchan. This info will be used down below before bridging the
1546 * transferee and newchan
1548 * As a result, we need to be sure to free this data before returning
1549 * or overwriting it.
1551 ast_channel_lock(transferer);
1552 ast_party_connected_line_copy(&connected_line, &transferer->connected);
1553 ast_channel_unlock(transferer);
1554 res = ast_bridge_call(transferer, newchan, &bconfig);
1555 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1556 ast_hangup(newchan);
1557 if (ast_stream_and_wait(transferer, xfersound, ""))
1558 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1559 finishup(transferee);
1560 transferer->_softhangup = 0;
1561 ast_party_connected_line_free(&connected_line);
1562 return AST_FEATURE_RETURN_SUCCESS;
1564 if (check_compat(transferee, newchan)) {
1565 finishup(transferee);
1566 ast_party_connected_line_free(&connected_line);
1569 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1571 if ((ast_autoservice_stop(transferee) < 0)
1572 || (ast_waitfordigit(transferee, 100) < 0)
1573 || (ast_waitfordigit(newchan, 100) < 0)
1574 || ast_check_hangup(transferee)
1575 || ast_check_hangup(newchan)) {
1576 ast_hangup(newchan);
1577 ast_party_connected_line_free(&connected_line);
1580 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1582 ast_hangup(newchan);
1583 ast_party_connected_line_free(&connected_line);
1586 /* Make formats okay */
1587 xferchan->visible_indication = transferer->visible_indication;
1588 xferchan->readformat = transferee->readformat;
1589 xferchan->writeformat = transferee->writeformat;
1590 ast_channel_masquerade(xferchan, transferee);
1591 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1592 xferchan->_state = AST_STATE_UP;
1593 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1594 xferchan->_softhangup = 0;
1595 if ((f = ast_read(xferchan)))
1597 newchan->_state = AST_STATE_UP;
1598 ast_clear_flag(newchan, AST_FLAGS_ALL);
1599 newchan->_softhangup = 0;
1600 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1601 ast_hangup(xferchan);
1602 ast_hangup(newchan);
1603 ast_party_connected_line_free(&connected_line);
1607 ast_channel_lock(newchan);
1608 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1609 dialfeatures = features_datastore->data;
1611 ast_channel_unlock(newchan);
1614 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1615 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1616 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1617 dialfeatures = NULL;
1620 ast_channel_lock(xferchan);
1621 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1622 dialfeatures = features_datastore->data;
1624 ast_channel_unlock(xferchan);
1627 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1630 tobj->chan = newchan;
1631 tobj->peer = xferchan;
1632 tobj->bconfig = *config;
1634 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1635 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1638 /* Due to a limitation regarding when callerID is set on a Local channel,
1639 * we use the transferer's connected line information here.
1642 /* xferchan is transferee, and newchan is the transfer target
1643 * So...in a transfer, who is the caller and who is the callee?
1645 * When the call is originally made, it is clear who is caller and callee.
1646 * When a transfer occurs, it is my humble opinion that the transferee becomes
1647 * the caller, and the transfer target is the callee.
1649 * The problem is that these macros were set with the intention of the original
1650 * caller and callee taking those roles. A transfer can totally mess things up,
1651 * to be technical. What sucks even more is that you can't effectively change
1652 * the macros in the dialplan during the call from the transferer to the transfer
1653 * target because the transferee is stuck with whatever role he originally had.
1655 * I think the answer here is just to make sure that it is well documented that
1656 * during a transfer, the transferee is the "caller" and the transfer target
1659 * This means that if party A calls party B, and party A transfers party B to
1660 * party C, then B has switched roles for the call. Now party B will have the
1661 * caller macro called on his channel instead of the callee macro.
1663 * Luckily, the method by which the bridge is launched here ensures that the
1664 * transferee is the "chan" on the bridge and the transfer target is the "peer,"
1665 * so my idea for the roles post-transfer does not require extensive code changes.
1667 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1668 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1669 ast_channel_update_connected_line(xferchan, &connected_line);
1671 ast_channel_lock(xferchan);
1672 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1673 ast_channel_unlock(xferchan);
1674 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1675 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1676 ast_channel_update_connected_line(newchan, &connected_line);
1678 ast_party_connected_line_free(&connected_line);
1680 if (ast_stream_and_wait(newchan, xfersound, ""))
1681 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1682 bridge_call_thread_launch(tobj);
1683 return -1; /* XXX meaning the channel is bridged ? */
1684 } else if (!ast_check_hangup(transferee)) {
1685 /* act as blind transfer */
1686 if (ast_autoservice_stop(transferee) < 0) {
1687 ast_hangup(newchan);
1692 unsigned int tries = 0;
1693 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1695 transferer_tech = strsep(&transferer_name, "/");
1696 transferer_name = strsep(&transferer_name, "-");
1698 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1699 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1700 if (ast_stream_and_wait(transferee, "beeperr", ""))
1702 return AST_FEATURE_RETURN_SUCCESS;
1705 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1706 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1707 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1708 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1709 /* Trying to transfer again */
1710 ast_autoservice_start(transferee);
1711 ast_indicate(transferee, AST_CONTROL_HOLD);
1713 newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1714 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1715 if (ast_autoservice_stop(transferee) < 0) {
1717 ast_hangup(newchan);
1721 /* Transfer failed, sleeping */
1722 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1723 ast_safe_sleep(transferee, atxferloopdelay);
1724 ast_debug(1, "Trying to callback...\n");
1725 newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1726 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1734 /* newchan is up, we should prepare transferee and bridge them */
1735 if (check_compat(transferee, newchan)) {
1736 finishup(transferee);
1739 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1741 if ((ast_waitfordigit(transferee, 100) < 0)
1742 || (ast_waitfordigit(newchan, 100) < 0)
1743 || ast_check_hangup(transferee)
1744 || ast_check_hangup(newchan)) {
1745 ast_hangup(newchan);
1749 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1751 ast_hangup(newchan);
1754 /* Make formats okay */
1755 xferchan->visible_indication = transferer->visible_indication;
1756 xferchan->readformat = transferee->readformat;
1757 xferchan->writeformat = transferee->writeformat;
1758 ast_channel_masquerade(xferchan, transferee);
1759 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1760 xferchan->_state = AST_STATE_UP;
1761 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1762 xferchan->_softhangup = 0;
1763 if ((f = ast_read(xferchan)))
1765 newchan->_state = AST_STATE_UP;
1766 ast_clear_flag(newchan, AST_FLAGS_ALL);
1767 newchan->_softhangup = 0;
1768 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1769 ast_hangup(xferchan);
1770 ast_hangup(newchan);
1773 tobj->chan = newchan;
1774 tobj->peer = xferchan;
1775 tobj->bconfig = *config;
1777 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1778 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1781 ast_channel_lock(newchan);
1782 ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
1783 ast_channel_unlock(newchan);
1784 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1785 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
1786 ast_channel_update_connected_line(xferchan, &connected_line);
1788 ast_channel_lock(xferchan);
1789 ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
1790 ast_channel_unlock(xferchan);
1791 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
1792 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
1793 ast_channel_update_connected_line(newchan, &connected_line);
1796 ast_party_connected_line_free(&connected_line);
1798 if (ast_stream_and_wait(newchan, xfersound, ""))
1799 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1800 bridge_call_thread_launch(tobj);
1801 return -1; /* XXX meaning the channel is bridged ? */
1803 /* Transferee hung up */
1804 finishup(transferee);
1809 /* add atxfer and automon as undefined so you can only use em if you configure them */
1810 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1812 AST_RWLOCK_DEFINE_STATIC(features_lock);
1814 static struct ast_call_feature builtin_features[] = {
1815 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1816 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1817 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1818 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1819 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1820 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1824 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
1826 /*! \brief register new feature into feature_list*/
1827 void ast_register_feature(struct ast_call_feature *feature)
1830 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1834 AST_RWLIST_WRLOCK(&feature_list);
1835 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1836 AST_RWLIST_UNLOCK(&feature_list);
1838 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1842 * \brief Add new feature group
1843 * \param fgname feature group name.
1845 * Add new feature group to the feature group list insert at head of list.
1846 * \note This function MUST be called while feature_groups is locked.
1848 static struct feature_group* register_group(const char *fgname)
1850 struct feature_group *fg;
1853 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1857 if (!(fg = ast_calloc(1, sizeof(*fg))))
1860 if (ast_string_field_init(fg, 128)) {
1865 ast_string_field_set(fg, gname, fgname);
1867 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
1869 ast_verb(2, "Registered group '%s'\n", fg->gname);
1875 * \brief Add feature to group
1876 * \param fg feature group
1878 * \param feature feature to add.
1880 * Check fg and feature specified, add feature to list
1881 * \note This function MUST be called while feature_groups is locked.
1883 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
1885 struct feature_group_exten *fge;
1888 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
1893 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
1897 if (!(fge = ast_calloc(1, sizeof(*fge))))
1900 if (ast_string_field_init(fge, 128)) {
1905 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
1907 fge->feature = feature;
1909 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
1911 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
1912 feature->sname, fg->gname, exten);
1915 void ast_unregister_feature(struct ast_call_feature *feature)
1921 AST_RWLIST_WRLOCK(&feature_list);
1922 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
1923 AST_RWLIST_UNLOCK(&feature_list);
1928 /*! \brief Remove all features in the list */
1929 static void ast_unregister_features(void)
1931 struct ast_call_feature *feature;
1933 AST_RWLIST_WRLOCK(&feature_list);
1934 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
1937 AST_RWLIST_UNLOCK(&feature_list);
1940 /*! \brief find a call feature by name */
1941 static struct ast_call_feature *find_dynamic_feature(const char *name)
1943 struct ast_call_feature *tmp;
1945 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
1946 if (!strcasecmp(tmp->sname, name)) {
1954 /*! \brief Remove all feature groups in the list */
1955 static void ast_unregister_groups(void)
1957 struct feature_group *fg;
1958 struct feature_group_exten *fge;
1960 AST_RWLIST_WRLOCK(&feature_groups);
1961 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
1962 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
1963 ast_string_field_free_memory(fge);
1967 ast_string_field_free_memory(fg);
1970 AST_RWLIST_UNLOCK(&feature_groups);
1974 * \brief Find a group by name
1975 * \param name feature name
1976 * \retval feature group on success.
1977 * \retval NULL on failure.
1979 static struct feature_group *find_group(const char *name) {
1980 struct feature_group *fg = NULL;
1982 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
1983 if (!strcasecmp(fg->gname, name))
1990 void ast_rdlock_call_features(void)
1992 ast_rwlock_rdlock(&features_lock);
1995 void ast_unlock_call_features(void)
1997 ast_rwlock_unlock(&features_lock);
2000 struct ast_call_feature *ast_find_call_feature(const char *name)
2003 for (x = 0; x < FEATURES_COUNT; x++) {
2004 if (!strcasecmp(name, builtin_features[x].sname))
2005 return &builtin_features[x];
2011 * \brief exec an app by feature
2012 * \param chan,peer,config,code,sense,data
2014 * Find a feature, determine which channel activated
2015 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
2017 * \retval -2 when an application cannot be found.
2019 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2021 struct ast_app *app;
2022 struct ast_call_feature *feature = data;
2023 struct ast_channel *work, *idle;
2026 if (!feature) { /* shouldn't ever happen! */
2027 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
2031 if (sense == FEATURE_SENSE_CHAN) {
2032 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2033 return AST_FEATURE_RETURN_KEEPTRYING;
2034 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2042 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2043 return AST_FEATURE_RETURN_KEEPTRYING;
2044 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2053 if (!(app = pbx_findapp(feature->app))) {
2054 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
2058 ast_autoservice_start(idle);
2060 if (!ast_strlen_zero(feature->moh_class))
2061 ast_moh_start(idle, feature->moh_class, NULL);
2063 res = pbx_exec(work, app, feature->app_args);
2065 if (!ast_strlen_zero(feature->moh_class))
2068 ast_autoservice_stop(idle);
2071 return AST_FEATURE_RETURN_SUCCESSBREAK;
2073 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
2076 static void unmap_features(void)
2080 ast_rwlock_wrlock(&features_lock);
2081 for (x = 0; x < FEATURES_COUNT; x++)
2082 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
2083 ast_rwlock_unlock(&features_lock);
2086 static int remap_feature(const char *name, const char *value)
2090 ast_rwlock_wrlock(&features_lock);
2091 for (x = 0; x < FEATURES_COUNT; x++) {
2092 if (strcasecmp(builtin_features[x].sname, name))
2095 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
2099 ast_rwlock_unlock(&features_lock);
2105 * \brief Helper function for feature_interpret and ast_feature_detect
2106 * \param chan,peer,config,code,sense,dynamic_features char buf,feature flags,operation,feature
2108 * Lock features list, browse for code, unlock list
2109 * If a feature is found and the operation variable is set, that feature's
2110 * operation is executed. The first feature found is copied to the feature parameter.
2111 * \retval res on success.
2112 * \retval -1 on failure.
2114 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
2115 struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
2116 struct ast_flags *features, int operation, struct ast_call_feature *feature)
2119 struct feature_group *fg = NULL;
2120 struct feature_group_exten *fge;
2121 struct ast_call_feature *tmpfeature;
2123 int res = AST_FEATURE_RETURN_PASSDIGITS;
2124 int feature_detected = 0;
2126 if (!(peer && chan && config) && operation) {
2127 return -1; /* can not run feature operation */
2130 ast_rwlock_rdlock(&features_lock);
2131 for (x = 0; x < FEATURES_COUNT; x++) {
2132 if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
2133 !ast_strlen_zero(builtin_features[x].exten)) {
2134 /* Feature is up for consideration */
2135 if (!strcmp(builtin_features[x].exten, code)) {
2136 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2138 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2140 memcpy(feature, &builtin_features[x], sizeof(feature));
2141 feature_detected = 1;
2143 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2144 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2145 res = AST_FEATURE_RETURN_STOREDIGITS;
2149 ast_rwlock_unlock(&features_lock);
2151 if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
2155 tmp = dynamic_features_buf;
2157 while ((tok = strsep(&tmp, "#"))) {
2158 AST_RWLIST_RDLOCK(&feature_groups);
2160 fg = find_group(tok);
2163 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2164 if (strcasecmp(fge->exten, code))
2167 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2169 memcpy(feature, fge->feature, sizeof(feature));
2170 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2171 AST_RWLIST_UNLOCK(&feature_groups);
2174 res = AST_FEATURE_RETURN_PASSDIGITS;
2180 AST_RWLIST_UNLOCK(&feature_groups);
2182 AST_RWLIST_RDLOCK(&feature_list);
2184 if (!(tmpfeature = find_dynamic_feature(tok))) {
2185 AST_RWLIST_UNLOCK(&feature_list);
2189 /* Feature is up for consideration */
2190 if (!strcmp(tmpfeature->exten, code)) {
2191 ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
2193 res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
2195 memcpy(feature, tmpfeature, sizeof(feature));
2196 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2197 AST_RWLIST_UNLOCK(&feature_list);
2200 res = AST_FEATURE_RETURN_PASSDIGITS;
2201 } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
2202 res = AST_FEATURE_RETURN_STOREDIGITS;
2204 AST_RWLIST_UNLOCK(&feature_list);
2211 * \brief Check the dynamic features
2212 * \param chan,peer,config,code,sense
2214 * \retval res on success.
2215 * \retval -1 on failure.
2218 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
2220 char dynamic_features_buf[128];
2221 const char *peer_dynamic_features, *chan_dynamic_features;
2222 struct ast_flags features;
2223 struct ast_call_feature feature;
2224 if (sense == FEATURE_SENSE_CHAN) {
2225 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
2228 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
2231 ast_channel_lock(peer);
2232 peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
2233 ast_channel_unlock(peer);
2235 ast_channel_lock(chan);
2236 chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
2237 ast_channel_unlock(chan);
2239 snprintf(dynamic_features_buf, sizeof(dynamic_features_buf), "%s%s%s", S_OR(chan_dynamic_features, ""), chan_dynamic_features && peer_dynamic_features ? "#" : "", S_OR(peer_dynamic_features,""));
2241 ast_debug(3, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features_buf);
2243 return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, 1, &feature);
2247 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
2249 return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
2252 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2256 ast_clear_flag(config, AST_FLAGS_ALL);
2258 ast_rwlock_rdlock(&features_lock);
2259 for (x = 0; x < FEATURES_COUNT; x++) {
2260 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2263 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2264 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2266 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2267 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2269 ast_rwlock_unlock(&features_lock);
2271 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2272 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2274 if (dynamic_features) {
2275 char *tmp = ast_strdupa(dynamic_features);
2277 struct ast_call_feature *feature;
2279 /* while we have a feature */
2280 while ((tok = strsep(&tmp, "#"))) {
2281 AST_RWLIST_RDLOCK(&feature_list);
2282 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2283 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2284 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2285 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2286 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2288 AST_RWLIST_UNLOCK(&feature_list);
2295 * \brief Get feature and dial
2296 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
2298 * Request channel, set channel variables, initiate call,check if they want to disconnect
2299 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2300 * check for answer break loop, set cdr return channel.
2302 * \todo XXX Check - this is very similar to the code in channel.c
2303 * \return always a channel
2305 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language)
2310 struct ast_channel *chan;
2311 struct ast_channel *monitor_chans[2];
2312 struct ast_channel *active_channel;
2313 int res = 0, ready = 0;
2314 struct timeval started;
2316 char *disconnect_code = NULL, *dialed_code = NULL;
2318 if (!(chan = ast_request(type, format, data, &cause))) {
2319 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2321 case AST_CAUSE_BUSY:
2322 state = AST_CONTROL_BUSY;
2324 case AST_CAUSE_CONGESTION:
2325 state = AST_CONTROL_CONGESTION;
2331 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2332 ast_string_field_set(chan, language, language);
2333 ast_channel_inherit_variables(caller, chan);
2334 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2336 ast_channel_lock(chan);
2337 ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
2338 ast_channel_unlock(chan);
2340 if (ast_call(chan, data, timeout)) {
2341 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2345 ast_indicate(caller, AST_CONTROL_RINGING);
2346 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2347 ast_rwlock_rdlock(&features_lock);
2348 for (x = 0; x < FEATURES_COUNT; x++) {
2349 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2352 disconnect_code = builtin_features[x].exten;
2353 len = strlen(disconnect_code) + 1;
2354 dialed_code = alloca(len);
2355 memset(dialed_code, 0, len);
2358 ast_rwlock_unlock(&features_lock);
2360 started = ast_tvnow();
2363 ast_poll_channel_add(caller, chan);
2365 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2366 struct ast_frame *f = NULL;
2368 monitor_chans[0] = caller;
2369 monitor_chans[1] = chan;
2370 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2372 /* see if the timeout has been violated */
2373 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2374 state = AST_CONTROL_UNHOLD;
2375 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2376 break; /*doh! timeout*/
2379 if (!active_channel)
2382 if (chan && (chan == active_channel)){
2383 if (!ast_strlen_zero(chan->call_forward)) {
2384 if (!(chan = ast_call_forward(caller, chan, &to, format, NULL, outstate))) {
2390 if (f == NULL) { /*doh! where'd he go?*/
2391 state = AST_CONTROL_HANGUP;
2396 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2397 if (f->subclass == AST_CONTROL_RINGING) {
2398 state = f->subclass;
2399 ast_verb(3, "%s is ringing\n", chan->name);
2400 ast_indicate(caller, AST_CONTROL_RINGING);
2401 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
2402 state = f->subclass;
2403 ast_verb(3, "%s is busy\n", chan->name);
2404 ast_indicate(caller, AST_CONTROL_BUSY);
2408 } else if (f->subclass == AST_CONTROL_ANSWER) {
2409 /* This is what we are hoping for */
2410 state = f->subclass;
2415 } else if (f->subclass == AST_CONTROL_CONNECTED_LINE) {
2416 if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) {
2417 ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
2419 } else if (f->subclass != -1) {
2420 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
2422 /* else who cares */
2425 } else if (caller && (active_channel == caller)) {
2426 f = ast_read(caller);
2427 if (f == NULL) { /*doh! where'd he go?*/
2428 if (!igncallerstate) {
2429 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2430 /* make this a blind transfer */
2434 state = AST_CONTROL_HANGUP;
2440 if (f->frametype == AST_FRAME_DTMF) {
2441 dialed_code[x++] = f->subclass;
2442 dialed_code[x] = '\0';
2443 if (strlen(dialed_code) == len) {
2445 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2447 dialed_code[x] = '\0';
2449 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2450 /* Caller Canceled the call */
2451 state = AST_CONTROL_UNHOLD;
2463 ast_poll_channel_del(caller, chan);
2466 ast_indicate(caller, -1);
2467 if (chan && ready) {
2468 if (chan->_state == AST_STATE_UP)
2469 state = AST_CONTROL_ANSWER;
2486 * \brief return the first unlocked cdr in a possible chain
2488 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2490 struct ast_cdr *cdr_orig = cdr;
2492 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2496 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2499 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2501 const char *feature;
2503 if (ast_strlen_zero(features)) {
2507 for (feature = features; *feature; feature++) {
2511 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2515 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2519 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2523 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2526 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2531 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2533 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2534 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2536 ast_channel_lock(caller);
2537 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2538 ast_channel_unlock(caller);
2539 if (!ds_caller_features) {
2540 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2541 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2544 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2545 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2546 ast_datastore_free(ds_caller_features);
2549 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2550 caller_features->is_caller = 1;
2551 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2552 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2553 ds_caller_features->data = caller_features;
2554 ast_channel_lock(caller);
2555 ast_channel_datastore_add(caller, ds_caller_features);
2556 ast_channel_unlock(caller);
2558 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2559 * flags over from the atxfer to the caller */
2563 ast_channel_lock(callee);
2564 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2565 ast_channel_unlock(callee);
2566 if (!ds_callee_features) {
2567 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2568 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2571 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2572 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2573 ast_datastore_free(ds_callee_features);
2576 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2577 callee_features->is_caller = 0;
2578 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2579 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2580 ds_callee_features->data = callee_features;
2581 ast_channel_lock(callee);
2582 ast_channel_datastore_add(callee, ds_callee_features);
2583 ast_channel_unlock(callee);
2590 * \brief bridge the call and set CDR
2591 * \param chan,peer,config
2593 * Set start time, check for two channels,check if monitor on
2594 * check for feature activation, create new CDR
2595 * \retval res on success.
2596 * \retval -1 on failure to bridge.
2598 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2600 /* Copy voice back and forth between the two channels. Give the peer
2601 the ability to transfer calls with '#<extension' syntax. */
2602 struct ast_frame *f;
2603 struct ast_channel *who;
2604 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2605 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2606 char orig_channame[AST_MAX_EXTENSION];
2607 char orig_peername[AST_MAX_EXTENSION];
2613 struct ast_option_header *aoh;
2614 struct ast_cdr *bridge_cdr = NULL;
2615 struct ast_cdr *orig_peer_cdr = NULL;
2616 struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2617 struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2618 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2619 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2622 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2623 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2625 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2628 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
2629 add_features_datastores(chan, peer, config);
2631 /* This is an interesting case. One example is if a ringing channel gets redirected to
2632 * an extension that picks up a parked call. This will make sure that the call taken
2633 * out of parking gets told that the channel it just got bridged to is still ringing. */
2634 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
2635 ast_indicate(peer, AST_CONTROL_RINGING);
2639 const char *monitor_exec;
2640 struct ast_channel *src = NULL;
2642 if (!(monitor_app = pbx_findapp("Monitor")))
2645 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
2647 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2649 if (monitor_app && src) {
2650 char *tmp = ast_strdupa(monitor_exec);
2651 pbx_exec(src, monitor_app, tmp);
2655 set_config_flags(chan, peer, config);
2657 /* Answer if need be */
2658 if (chan->_state != AST_STATE_UP) {
2659 if (ast_raw_answer(chan, 1)) {
2664 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
2665 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
2666 orig_peer_cdr = peer_cdr;
2668 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2671 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
2672 ast_cdr_update(chan);
2673 bridge_cdr = ast_cdr_dup(chan_cdr);
2674 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
2675 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
2677 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
2678 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
2679 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
2680 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
2681 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
2682 ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
2683 ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
2684 ast_cdr_setcid(bridge_cdr, chan);
2685 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
2686 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
2687 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
2688 /* Destination information */
2689 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
2690 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
2692 bridge_cdr->start = peer_cdr->start;
2693 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2695 ast_cdr_start(bridge_cdr);
2698 ast_debug(4,"bridge answer set, chan answer set\n");
2699 /* peer_cdr->answer will be set when a macro runs on the peer;
2700 in that case, the bridge answer will be delayed while the
2701 macro plays on the peer channel. The peer answered the call
2702 before the macro started playing. To the phone system,
2703 this is billable time for the call, even tho the caller
2704 hears nothing but ringing while the macro does its thing. */
2705 if (peer_cdr && !ast_tvzero(peer_cdr->answer)) {
2706 bridge_cdr->answer = peer_cdr->answer;
2707 bridge_cdr->disposition = peer_cdr->disposition;
2709 chan_cdr->answer = peer_cdr->answer;
2710 chan_cdr->disposition = peer_cdr->disposition;
2713 ast_cdr_answer(bridge_cdr);
2715 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
2718 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
2720 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
2723 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
2728 struct ast_channel *other; /* used later */
2730 res = ast_channel_bridge(chan, peer, config, &f, &who);
2732 /* When frame is not set, we are probably involved in a situation
2733 where we've timed out.
2734 When frame is set, we'll come this code twice; once for DTMF_BEGIN
2735 and also for DTMF_END. If we flow into the following 'if' for both, then
2736 our wait times are cut in half, as both will subtract from the
2737 feature_timer. Not good!
2739 if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
2740 /* Update feature timer for next pass */
2741 diff = ast_tvdiff_ms(ast_tvnow(), config->feature_start_time);
2742 if (res == AST_BRIDGE_RETRY) {
2743 /* The feature fully timed out but has not been updated. Skip
2744 * the potential round error from the diff calculation and
2745 * explicitly set to expired. */
2746 config->feature_timer = -1;
2748 config->feature_timer -= diff;
2752 if (config->feature_timer <= 0) {
2753 /* Not *really* out of time, just out of time for
2754 digits to come in for features. */
2755 ast_debug(1, "Timed out for feature!\n");
2756 if (!ast_strlen_zero(peer_featurecode)) {
2757 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
2758 memset(peer_featurecode, 0, sizeof(peer_featurecode));
2760 if (!ast_strlen_zero(chan_featurecode)) {
2761 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
2762 memset(chan_featurecode, 0, sizeof(chan_featurecode));
2766 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2768 /* No more digits expected - reset the timer */
2769 config->feature_timer = 0;
2771 hadfeatures = hasfeatures;
2772 /* Continue as we were */
2775 /* The bridge returned without a frame and there is a feature in progress.
2776 * However, we don't think the feature has quite yet timed out, so just
2777 * go back into the bridge. */
2781 if (config->feature_timer <=0) {
2782 /* We ran out of time */
2783 config->feature_timer = 0;
2793 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer)) {
2794 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
2799 if (!f || (f->frametype == AST_FRAME_CONTROL &&
2800 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY ||
2801 f->subclass == AST_CONTROL_CONGESTION))) {
2805 /* many things should be sent to the 'other' channel */
2806 other = (who == chan) ? peer : chan;
2807 if (f->frametype == AST_FRAME_CONTROL) {
2808 switch (f->subclass) {
2809 case AST_CONTROL_RINGING:
2810 case AST_CONTROL_FLASH:
2812 ast_indicate(other, f->subclass);
2814 case AST_CONTROL_CONNECTED_LINE:
2815 if (!ast_channel_connected_line_macro(who, other, f, who != chan, 1)) {
2818 /* The implied "else" falls through purposely */
2819 case AST_CONTROL_HOLD:
2820 case AST_CONTROL_UNHOLD:
2821 ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
2823 case AST_CONTROL_OPTION:
2825 /* Forward option Requests */
2826 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2827 ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
2828 f->datalen - sizeof(struct ast_option_header), 0);
2832 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
2834 } else if (f->frametype == AST_FRAME_DTMF) {
2838 hadfeatures = hasfeatures;
2839 /* This cannot overrun because the longest feature is one shorter than our buffer */
2841 sense = FEATURE_SENSE_CHAN;
2842 featurecode = chan_featurecode;
2844 sense = FEATURE_SENSE_PEER;
2845 featurecode = peer_featurecode;
2847 /*! append the event to featurecode. we rely on the string being zero-filled, and
2848 * not overflowing it.
2849 * \todo XXX how do we guarantee the latter ?
2851 featurecode[strlen(featurecode)] = f->subclass;
2852 /* Get rid of the frame before we start doing "stuff" with the channels */
2855 config->feature_timer = 0;
2856 res = feature_interpret(chan, peer, config, featurecode, sense);
2858 case AST_FEATURE_RETURN_PASSDIGITS:
2859 ast_dtmf_stream(other, who, featurecode, 0, 0);
2861 case AST_FEATURE_RETURN_SUCCESS:
2862 memset(featurecode, 0, sizeof(chan_featurecode));
2865 if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
2870 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2871 if (hadfeatures && !hasfeatures) {
2872 /* Feature completed or timed out */
2873 config->feature_timer = 0;
2874 } else if (hasfeatures) {
2875 if (config->timelimit) {
2876 /* No warning next time - we are waiting for future */
2877 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
2879 config->feature_start_time = ast_tvnow();
2880 config->feature_timer = featuredigittimeout;
2881 ast_debug(1, "Set feature timer to %ld\n", config->feature_timer);
2890 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
2891 ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
2893 ast_cdr_discard(bridge_cdr);
2894 /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
2896 return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
2899 if (config->end_bridge_callback) {
2900 config->end_bridge_callback(config->end_bridge_callback_data);
2903 /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
2904 * if it were, then chan belongs to a different thread now, and might have been hung up long
2907 if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
2908 ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
2909 struct ast_cdr *swapper = NULL;
2910 char savelastapp[AST_MAX_EXTENSION];
2911 char savelastdata[AST_MAX_EXTENSION];
2912 char save_exten[AST_MAX_EXTENSION];
2914 int found = 0; /* set if we find at least one match */
2915 int spawn_error = 0;
2917 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
2918 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
2919 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
2920 ast_cdr_end(bridge_cdr);
2922 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
2923 dialplan code operate on it */
2924 ast_channel_lock(chan);
2926 swapper = chan->cdr;
2927 ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
2928 ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
2929 chan->cdr = bridge_cdr;
2931 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
2932 save_prio = chan->priority;
2933 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
2935 ast_channel_unlock(chan);
2936 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
2939 if (found && spawn_error) {
2940 /* Something bad happened, or a hangup has been requested. */
2941 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2942 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2945 ast_channel_lock(chan);
2946 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
2947 chan->priority = save_prio;
2949 if (chan->cdr == bridge_cdr) {
2950 chan->cdr = swapper;
2955 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
2956 ast_channel_unlock(chan);
2957 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
2959 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
2960 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
2962 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2965 /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
2966 new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2967 if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
2968 ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
2970 /* we can post the bridge CDR at this point */
2972 ast_cdr_end(bridge_cdr);
2973 ast_cdr_detach(bridge_cdr);
2976 /* do a specialized reset on the beginning channel
2977 CDR's, if they still exist, so as not to mess up
2978 issues in future bridges;
2980 Here are the rules of the game:
2981 1. The chan and peer channel pointers will not change
2982 during the life of the bridge.
2983 2. But, in transfers, the channel names will change.
2984 between the time the bridge is started, and the
2985 time the channel ends.
2986 Usually, when a channel changes names, it will
2987 also change CDR pointers.
2988 3. Usually, only one of the two channels (chan or peer)
2990 4. Usually, if a channel changes names during a bridge,
2991 it is because of a transfer. Usually, in these situations,
2992 it is normal to see 2 bridges running simultaneously, and
2993 it is not unusual to see the two channels that change
2994 swapped between bridges.
2995 5. After a bridge occurs, we have 2 or 3 channels' CDRs
2996 to attend to; if the chan or peer changed names,
2997 we have the before and after attached CDR's.
3001 struct ast_channel *chan_ptr = NULL;
3003 if (strcasecmp(orig_channame, chan->name) != 0) {
3005 if ((chan_ptr = ast_channel_get_by_name(orig_channame))) {
3006 ast_channel_lock(chan_ptr);
3007 if (!ast_bridged_channel(chan_ptr)) {
3008 struct ast_cdr *cur;
3009 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
3010 if (cur == chan_cdr) {
3015 ast_cdr_specialized_reset(chan_cdr, 0);
3018 ast_channel_unlock(chan_ptr);
3019 chan_ptr = ast_channel_unref(chan_ptr);
3022 ast_cdr_specialized_reset(new_chan_cdr, 0);
3024 ast_cdr_specialized_reset(chan_cdr, 0); /* nothing changed, reset the chan_cdr */
3029 struct ast_channel *chan_ptr = NULL;
3030 new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
3031 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))
3032 ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
3033 if (strcasecmp(orig_peername, peer->name) != 0) {
3035 if ((chan_ptr = ast_channel_get_by_name(orig_peername))) {
3036 ast_channel_lock(chan_ptr);
3037 if (!ast_bridged_channel(chan_ptr)) {
3038 struct ast_cdr *cur;
3039 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
3040 if (cur == peer_cdr) {
3045 ast_cdr_specialized_reset(peer_cdr, 0);
3048 ast_channel_unlock(chan_ptr);
3049 chan_ptr = ast_channel_unref(chan_ptr);
3052 ast_cdr_specialized_reset(new_peer_cdr, 0);
3054 ast_cdr_specialized_reset(peer_cdr, 0); /* nothing changed, reset the peer_cdr */
3061 /*! \brief Output parking event to manager */
3062 static void post_manager_event(const char *s, struct parkeduser *pu)
3064 manager_event(EVENT_FLAG_CALL, s,
3067 "Parkinglot: %s\r\n"
3068 "CallerIDNum: %s\r\n"
3069 "CallerIDName: %s\r\n"
3070 "UniqueID: %s\r\n\r\n",
3073 pu->parkinglot->name,
3074 S_OR(pu->chan->cid.cid_num, "<unknown>"),
3075 S_OR(pu->chan->cid.cid_name, "<unknown>"),
3080 static char *callback_dialoptions(struct ast_flags *features_callee, struct ast_flags *features_caller, char *options, size_t len)
3084 OPT_CALLEE_REDIRECT = 't',
3085 OPT_CALLER_REDIRECT = 'T',
3086 OPT_CALLEE_AUTOMON = 'w',
3087 OPT_CALLER_AUTOMON = 'W',
3088 OPT_CALLEE_DISCONNECT = 'h',
3089 OPT_CALLER_DISCONNECT = 'H',
3090 OPT_CALLEE_PARKCALL = 'k',
3091 OPT_CALLER_PARKCALL = 'K',
3094 memset(options, 0, len);
3095 if (ast_test_flag(features_caller, AST_FEATURE_REDIRECT) && i < len) {
3096 options[i++] = OPT_CALLER_REDIRECT;
3098 if (ast_test_flag(features_caller, AST_FEATURE_AUTOMON) && i < len) {
3099 options[i++] = OPT_CALLER_AUTOMON;
3101 if (ast_test_flag(features_caller, AST_FEATURE_DISCONNECT) && i < len) {
3102 options[i++] = OPT_CALLER_DISCONNECT;
3104 if (ast_test_flag(features_caller, AST_FEATURE_PARKCALL) && i < len) {
3105 options[i++] = OPT_CALLER_PARKCALL;
3108 if (ast_test_flag(features_callee, AST_FEATURE_REDIRECT) && i < len) {
3109 options[i++] = OPT_CALLEE_REDIRECT;
3111 if (ast_test_flag(features_callee, AST_FEATURE_AUTOMON) && i < len) {
3112 options[i++] = OPT_CALLEE_AUTOMON;
3114 if (ast_test_flag(features_callee, AST_FEATURE_DISCONNECT) && i < len) {
3115 options[i++] = OPT_CALLEE_DISCONNECT;
3117 if (ast_test_flag(features_callee, AST_FEATURE_PARKCALL) && i < len) {
3118 options[i++] = OPT_CALLEE_PARKCALL;
3124 /*! \brief Run management on parkinglots, called once per parkinglot */
3125 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
3128 struct parkeduser *pu;
3130 char parkingslot[AST_MAX_EXTENSION];
3132 /* Lock parking list */
3133 AST_LIST_LOCK(&curlot->parkings);
3134 AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
3135 struct ast_channel *chan = pu->chan; /* shorthand */
3136 int tms; /* timeout for this item */
3137 int x; /* fd index in channel */
3138 struct ast_context *con;
3140 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
3143 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
3144 if (tms > pu->parkingtime) {
3145 /* Stop music on hold */
3146 ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
3147 /* Get chan, exten from derived kludge */
3148 if (pu->peername[0]) {
3149 char *peername = ast_strdupa(pu->peername);
3150 char *cp = strrchr(peername, '-');
3151 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
3156 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
3157 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
3158 if (peername_flat[i] == '/')
3159 peername_flat[i]= '0';
3161 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
3163 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
3166 char returnexten[AST_MAX_EXTENSION];
3167 struct ast_datastore *features_datastore;
3168 struct ast_dial_features *dialfeatures = NULL;
3170 ast_channel_lock(chan);
3172 if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
3173 dialfeatures = features_datastore->data;
3175 ast_channel_unlock(chan);
3177 if (!strncmp(peername, "Parked/", 7)) {
3182 char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
3183 snprintf(returnexten, sizeof(returnexten), "%s,30,%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
3184 } else { /* Existing default */
3185 ast_log(LOG_WARNING, "Dialfeatures not found on %s, using default!\n", chan->name);
3186 snprintf(returnexten, sizeof(returnexten), "%s,30,t", peername);
3189 ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
3191 if (comebacktoorigin) {
3192 set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
3194 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
3195 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
3196 pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
3197 set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
3200 /* They've been waiting too long, send them back to where they came. Theoretically they
3201 should have their original extensions and such, but we copy to be on the safe side */
3202 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
3204 post_manager_event("ParkedCallTimeOut", pu);
3206 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);
3207 /* Start up the PBX, or hang them up */
3208 if (ast_pbx_start(chan)) {
3209 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
3212 /* And take them out of the parking lot */
3213 con = ast_context_find(pu->parkinglot->parking_con);
3215 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
3216 ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
3218 notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
3220 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
3221 AST_LIST_REMOVE_CURRENT(list);
3223 } else { /* still within parking time, process descriptors */
3224 for (x = 0; x < AST_MAX_FDS; x++) {
3225 struct ast_frame *f;
3227 if ((chan->fds[x] == -1) || (!FD_ISSET(chan->fds[x], rfds) && !FD_ISSET(pu->chan->fds[x], efds)))
3230 if (FD_ISSET(chan->fds[x], efds))
3231 ast_set_flag(chan, AST_FLAG_EXCEPTION);
3233 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
3236 /* See if they need servicing */
3237 f = ast_read(pu->chan);
3239 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
3242 post_manager_event("ParkedCallGiveUp", pu);
3244 /* There's a problem, hang them up*/
3245 ast_verb(2, "%s got tired of being parked\n", chan->name);
3247 /* And take them out of the parking lot */
3248 con = ast_context_find(curlot->parking_con);
3250 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
3251 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
3253 notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
3255 ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
3256 AST_LIST_REMOVE_CURRENT(list);
3260 /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
3262 if (pu->moh_trys < 3 && !chan->generatordata) {
3263 ast_debug(1, "MOH on parked call stopped by outside source. Restarting on channel %s.\n", chan->name);
3264 ast_indicate_data(chan, AST_CONTROL_HOLD,
3265 S_OR(curlot->mohclass, NULL),
3266 (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
3269 goto std; /* XXX Ick: jumping into an else statement??? XXX */
3272 if (x >= AST_MAX_FDS) {
3273 std: for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
3274 if (chan->fds[x] > -1) {
3275 FD_SET(chan->fds[x], nrfds);
3276 FD_SET(chan->fds[x], nefds);
3277 if (chan->fds[x] > *max)
3278 *max = chan->fds[x];
3281 /* Keep track of our shortest wait */
3282 if (tms < *ms || *ms < 0)
3287 AST_LIST_TRAVERSE_SAFE_END;
3288 AST_LIST_UNLOCK(&curlot->parkings);
3293 * \brief Take care of parked calls and unpark them if needed
3294 * \param ignore unused var.
3296 * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
3297 * if so, remove channel from parking lot and return it to the extension that parked it.
3298 * Check if parked channel decided to hangup, wait until next FD via select().
3300 static void *do_parking_thread(void *ignore)
3302 fd_set rfds, efds; /* results from previous select, to be preserved across loops. */
3303 fd_set nrfds, nefds; /* args for the next select */
3309 int ms = -1; /* select timeout, uninitialized */
3310 int max = -1; /* max fd, none there yet */
3311 struct ao2_iterator iter;
3312 struct ast_parkinglot *curlot;
3315 iter = ao2_iterator_init(parkinglots, 0);
3317 while ((curlot = ao2_iterator_next(&iter))) {
3318 res = manage_parkinglot(curlot, &rfds, &efds, &nrfds, &nefds, &ms, &max);
3319 ao2_ref(curlot, -1);
3325 struct timeval wait = ast_samp2tv(ms, 1000);
3326 /* Wait for something to happen */
3327 ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &wait : NULL);
3329 pthread_testcancel();
3331 return NULL; /* Never reached */
3334 /*! \brief Find parkinglot by name */
3335 struct ast_parkinglot *find_parkinglot(const char *name)
3337 struct ast_parkinglot *parkinglot = NULL;
3338 struct ast_parkinglot tmp_parkinglot;
3340 if (ast_strlen_zero(name))
3343 ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
3345 parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
3347 if (parkinglot && option_debug)
3348 ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
3353 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
3354 AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
3355 AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
3356 AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
3359 /*! \brief Park a call */
3360 static int park_call_exec(struct ast_channel *chan, const char *data)
3362 /* Cache the original channel name in case we get masqueraded in the middle
3363 * of a park--it is still theoretically possible for a transfer to happen before
3364 * we get here, but it is _really_ unlikely */
3365 char *orig_chan_name = ast_strdupa(chan->name);
3366 char orig_exten[AST_MAX_EXTENSION];
3367 int orig_priority = chan->priority;
3369 /* Data is unused at the moment but could contain a parking
3370 lot context eventually */
3374 AST_DECLARE_APP_ARGS(app_args,
3375 AST_APP_ARG(timeout);
3376 AST_APP_ARG(return_con);
3377 AST_APP_ARG(return_ext);
3378 AST_APP_ARG(return_pri);
3379 AST_APP_ARG(options);
3382 parse = ast_strdupa(data);
3383 AST_STANDARD_APP_ARGS(app_args, parse);
3385 ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
3387 /* Setup the exten/priority to be s/1 since we don't know
3388 where this call should return */
3389 strcpy(chan->exten, "s");
3392 /* Answer if call is not up */
3393 if (chan->_state != AST_STATE_UP)
3394 res = ast_answer(chan);
3396 /* Sleep to allow VoIP streams to settle down */
3398 res = ast_safe_sleep(chan, 1000);
3402 struct ast_park_call_args args = {
3403 .orig_chan_name = orig_chan_name,
3405 struct ast_flags flags =&n