summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-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")) {