aboutsummaryrefslogtreecommitdiffstats
path: root/main/features.c
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-02-17 18:29:48 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-02-17 18:29:48 +0000
commit6987914389571b2897d7554cfa8ead137364ddf7 (patch)
tree8c76c85089e297ed3166e349a257686220b36081 /main/features.c
parent49874404728c83cadc6f91f6ec1edc31a1ffd342 (diff)
addition of dynamic parkinglots feature
This feature allows for parkinglots to be created dynamically within the dialplan. Thanks to all who were involved with getting this patch written and tested! (closes issue #15135) Reported by: IgorG Patches: features.dynamic_park.v3.diff uploaded by IgorG (license 20) 2009090400_dynamicpark.diff.txt uploaded by mvanbaak (license 7) dynamic_parkinglot.diff uploaded by dvossel (license 671) Tested by: eliel, IgorG, acunningham, mvanbaak, zktech Review: https://reviewboard.asterisk.org/r/352/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@247248 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/features.c')
-rw-r--r--main/features.c99
1 files changed, 88 insertions, 11 deletions
diff --git a/main/features.c b/main/features.c
index 329dd17c5..9c0768fc3 100644
--- a/main/features.c
+++ b/main/features.c
@@ -212,6 +212,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
parking context, Park() will park the call on that extension, unless
it already exists. In that case, execution will continue at next priority.</para>
+ <para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
+ in that parkinglot.</para>
+ <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
+ will be used as template for the newly created dynamic lot.</para>
+ <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
+ parking lot will use this context.</para>
+ <para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
+ will use those parking postitions.</para>
</description>
<see-also>
<ref type="application">ParkAndAnnounce</ref>
@@ -356,6 +364,7 @@ char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park
static char courtesytone[256]; /*!< Courtesy tone */
static int parkedplay = 0; /*!< Who to play the courtesy tone to */
+static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
static char xfersound[256]; /*!< Call transfer sound */
static char xferfailsound[256]; /*!< Call transfer failure sound */
static char pickupsound[256]; /*!< Pickup sound */
@@ -426,7 +435,8 @@ static void parkinglot_unref(struct ast_parkinglot *parkinglot);
static void parkinglot_destroy(void *obj);
int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
struct ast_parkinglot *find_parkinglot(const char *name);
-
+static struct ast_parkinglot *create_parkinglot(const char *name);
+static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
const char *ast_parking_ext(void)
{
@@ -679,23 +689,67 @@ struct ast_park_call_args {
struct parkeduser *pu;
};
-static struct parkeduser *park_space_reserve(struct ast_channel *chan,
- struct ast_channel *peer, struct ast_park_call_args *args)
+static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
{
struct parkeduser *pu;
int i, parking_space = -1, parking_range;
const char *parkinglotname = NULL;
const char *parkingexten;
struct ast_parkinglot *parkinglot = NULL;
-
+
if (peer)
parkinglotname = findparkinglotname(peer);
if (parkinglotname) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
- parkinglot = find_parkinglot(parkinglotname);
+ ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglotname);
+ parkinglot = find_parkinglot(parkinglotname);
+
}
+
+ /* Dynamically create parkinglot */
+ if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
+ const char *dyn_context, *dyn_range;
+ const char *parkinglotname_copy = NULL;
+ struct ast_parkinglot *parkinglot_copy = NULL;
+ int dyn_start, dyn_end;
+
+ ast_channel_lock(chan);
+ parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
+ dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
+ dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
+ ast_channel_unlock(chan);
+
+ if (!ast_strlen_zero(parkinglotname_copy)) {
+ parkinglot_copy = find_parkinglot(parkinglotname_copy);
+ }
+ if (!parkinglot_copy) {
+ parkinglot_copy = parkinglot_addref(default_parkinglot);
+ ast_debug(1, "Using default parking lot for copy\n");
+ }
+ if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
+ ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
+ } else {
+ if (!ast_strlen_zero(dyn_context)) {
+ ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
+ }
+ if (!ast_strlen_zero(dyn_range)) {
+ if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
+ ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
+ } else {
+ parkinglot->parking_start = dyn_start;
+ parkinglot->parking_stop = dyn_end;
+ }
+ }
+ ao2_link(parkinglots, parkinglot);
+ }
+
+ if (parkinglot_copy) {
+ /* unref our tempory copy */
+ parkinglot_unref(parkinglot_copy);
+ parkinglot_copy = NULL;
+ }
+ }
+
if (!parkinglot) {
parkinglot = parkinglot_addref(default_parkinglot);
}
@@ -3508,6 +3562,27 @@ struct ast_parkinglot *find_parkinglot(const char *name)
return parkinglot;
}
+/*! \brief Copy parkinglot and store it with new name */
+struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot) {
+ struct ast_parkinglot *copylot;
+
+ if (ast_strlen_zero(name)) { /* No name specified */
+ return NULL;
+ }
+ if (find_parkinglot(name)) { /* Parkinglot with that name allready exists */
+ return NULL;
+ }
+
+ copylot = create_parkinglot(name);
+ ast_debug(1, "Building parking lot %s\n", name);
+
+ memcpy(copylot, parkinglot, sizeof(struct ast_parkinglot));
+ ast_copy_string(copylot->name, name, sizeof(copylot->name));
+ AST_LIST_HEAD_INIT(&copylot->parkings);
+
+ return copylot;
+}
+
AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
@@ -3792,7 +3867,7 @@ static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglo
}
/*! \brief Allocate parking lot structure */
-static struct ast_parkinglot *create_parkinglot(char *name)
+static struct ast_parkinglot *create_parkinglot(const char *name)
{
struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
@@ -3842,9 +3917,8 @@ static struct ast_parkinglot *build_parkinglot(char *name, struct ast_variable *
ao2_lock(parkinglot);
- if (option_debug)
- ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
-
+ ast_debug(1, "Building parking lot %s\n", name);
+
/* Do some config stuff */
while(confvar) {
if (!strcasecmp(confvar->name, "context")) {
@@ -4027,6 +4101,7 @@ static int load_config(void)
pickupfailsound[0] = '\0';
adsipark = 0;
comebacktoorigin = 1;
+ parkeddynamic = 0;
default_parkinglot->parkaddhints = 0;
default_parkinglot->parkedcalltransfers = 0;
@@ -4098,6 +4173,8 @@ static int load_config(void)
default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLER;
else if (!strcasecmp(var->value, "callee"))
default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLEE;
+ } else if (!strcasecmp(var->name, "parkeddynamic")) {
+ parkeddynamic = ast_true(var->value);
} else if (!strcasecmp(var->name, "adsipark")) {
adsipark = ast_true(var->value);
} else if (!strcasecmp(var->name, "transferdigittimeout")) {