diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/features.c | 99 |
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(©lot->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")) { |