dect
/
asterisk
Archived
13
0
Fork 0

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
This commit is contained in:
dvossel 2010-02-17 18:29:48 +00:00
parent 4987440472
commit 6987914389
3 changed files with 100 additions and 11 deletions

11
CHANGES
View File

@ -197,6 +197,15 @@ Dialplan Variables
* Added DYNAMIC_FEATURENAME which holds the last triggered dynamic feature.
* Added DYNAMIC_PEERNAME which holds the unique channel name on the other side
and is set when a dynamic feature is triggered.
* Added PARKINGLOT which can be used with parkeddynamic feature.conf option
to dynamically create a new parking lot matching the value this varible is
set to.
* Added PARKINGDYNAMIC which represents the template parkinglot defined in
features.conf that should be the base for dynamic parkinglots.
* Added PARKINGDYNCONTEXT which tells what context a newly created dynamic
parkinglot should have.
* Added PARKINGDYNPOS which holds what parking positions a dynamic parkinglot
should have.
Queue changes
-------------
@ -396,6 +405,8 @@ Miscellaneous
* jabber.conf supports a new option auth_policy that toggles auto user registration.
* A new lockconfdir option has been added to asterisk.conf to protect the
configuration directory (/etc/asterisk by default) during reloads.
* The parkeddynamic option has been added to features.conf to enable the creation
of dynamic parkinglots.
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2 -------------

View File

@ -27,6 +27,7 @@ context => parkedcalls ; Which context parked calls are in (default parking lot
; one of: callee, caller, both, no (default is no)
;parkedcallrecording = caller ; Enables or disables DTMF based one-touch recording when picking up a parked call.
; one of: callee, caller, both, no (default is no)
;parkeddynamic = yes ; Enables dynamically created parkinglots. (default is no)
;adsipark = yes ; if you want ADSI parking announcements
;findslot => next ; Continue to the 'next' free parking space.
; Defaults to 'first' available

View File

@ -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")) {