[asterisk-commits] rmudgett: branch rmudgett/parking r330994 - /team/rmudgett/parking/main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Aug 5 15:31:31 CDT 2011
Author: rmudgett
Date: Fri Aug 5 15:31:27 2011
New Revision: 330994
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=330994
Log:
* Extracted create_dynamic_parkinglot() from park_space_reserve() so
dynamic parking lots can be created again by DTMF transfer and the Park
application after adding the parking_lot_name option to the Park
application.
* Added PARKINGDYNEXTEN channel variable to allow dynamic parking lots to
specify the parking lot access extension.
Modified:
team/rmudgett/parking/main/features.c
Modified: team/rmudgett/parking/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/parking/main/features.c?view=diff&rev=330994&r1=330993&r2=330994
==============================================================================
--- team/rmudgett/parking/main/features.c (original)
+++ team/rmudgett/parking/main/features.c Fri Aug 5 15:31:27 2011
@@ -286,14 +286,20 @@
registered internally and does not need to be explicitly added
into the dialplan, although you should include the parking lot
context.</para>
- <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 the next priority.</para>
- <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from
- <literal>features.conf</literal> will be used as a template for the newly created dynamic lot.</para>
- <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
+ <para>If you set the <variable>PARKINGEXTEN</variable> variable to a
+ parking space extension in the parking lot, Park() will attempt to park the call
+ on that extension. If the extension is already is in use then execution
+ will continue at the next priority.</para>
+ <para>If the <literal>parkeddynamic</literal> option is enabled in features.conf
+ the following variables can be used to dynamically create new parking lots.</para>
+ <para>If you set the <variable>PARKINGDYNAMIC</variable> variable and this parking lot
+ exists then it will be used as a template for the newly created dynamic lot. Otherwise,
+ the default parking lot will be used.</para>
+ <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable then 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
+ <para>If you set the <variable>PARKINGDYNEXTEN</variable> variable then the newly created dynamic
+ parking lot will use this extension to access the parking lot.</para>
+ <para>If you set the <variable>PARKINGDYNPOS</variable> variable then the newly created dynamic parking lot
will use those parking postitions.</para>
</description>
<see-also>
@@ -1021,16 +1027,122 @@
/*!
* \internal
+ * \brief Create a dynamic parking lot.
+ *
+ * \param name Dynamic parking lot name to create.
+ * \param chan Channel to get dynamic parking lot parameters.
+ *
+ * \retval parkinglot on success.
+ * \retval NULL on error.
+ */
+static struct ast_parkinglot *create_dynamic_parkinglot(const char *name, struct ast_channel *chan)
+{
+ const char *dyn_context;
+ const char *dyn_exten;
+ const char *dyn_range;
+ const char *template_name;
+ struct ast_parkinglot *template_parkinglot = NULL;
+ struct ast_parkinglot *parkinglot;
+ int dyn_start;
+ int dyn_end;
+
+ ast_channel_lock(chan);
+ template_name = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
+ dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
+ dyn_exten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNEXTEN"), ""));
+ dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
+ ast_channel_unlock(chan);
+
+ if (!ast_strlen_zero(template_name)) {
+ template_parkinglot = find_parkinglot(template_name);
+ if (!template_parkinglot) {
+ ast_debug(1, "PARKINGDYNAMIC lot %s does not exist.\n",
+ template_name);
+ } else if (template_parkinglot->cfg.is_invalid) {
+ ast_debug(1, "PARKINGDYNAMIC lot %s has invalid config.\n",
+ template_name);
+ parkinglot_unref(template_parkinglot);
+ template_parkinglot = NULL;
+ }
+ }
+ if (!template_parkinglot) {
+ template_parkinglot = parkinglot_addref(default_parkinglot);
+ ast_debug(1, "Using default parking lot for template\n");
+ }
+
+ parkinglot = copy_parkinglot(name, template_parkinglot);
+ if (!parkinglot) {
+ ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
+ } else {
+ /* Configure the dynamic parking lot. */
+ if (!ast_strlen_zero(dyn_context)) {
+ ast_copy_string(parkinglot->cfg.parking_con, dyn_context,
+ sizeof(parkinglot->cfg.parking_con));
+ }
+ if (!ast_strlen_zero(dyn_exten)) {
+ ast_copy_string(parkinglot->cfg.parking_con, dyn_exten,
+ sizeof(parkinglot->cfg.parkext));
+ }
+ 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 if (dyn_end < dyn_start || dyn_start <= 0 || dyn_end <= 0) {
+ ast_log(LOG_WARNING,
+ "Format for parking positions is a-b, where a <= b\n");
+ } else {
+ parkinglot->cfg.parking_start = dyn_start;
+ parkinglot->cfg.parking_stop = dyn_end;
+ }
+ }
+
+ /*
+ * Sanity check for dynamic parking lot configuration.
+ *
+ * XXX It may be desirable to instead check if the dynamic
+ * parking lot overlaps any existing lots like what is done for
+ * a reload.
+ */
+ if (!strcmp(parkinglot->cfg.parking_con, template_parkinglot->cfg.parking_con)) {
+ if (!strcmp(parkinglot->cfg.parkext, template_parkinglot->cfg.parkext)) {
+ ast_log(LOG_WARNING,
+ "Parking lot '%s' conflicts with template parking lot '%s'!\n"
+ "Change either PARKINGDYNCONTEXT or PARKINGDYNEXTEN.\n",
+ parkinglot->name, template_parkinglot->name);
+ }
+ if ((template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_start
+ && parkinglot->cfg.parking_start <= template_parkinglot->cfg.parking_stop)
+ || (template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_stop
+ && parkinglot->cfg.parking_stop <= template_parkinglot->cfg.parking_stop)
+ || (parkinglot->cfg.parking_start < template_parkinglot->cfg.parking_start
+ && template_parkinglot->cfg.parking_stop < parkinglot->cfg.parking_stop)) {
+ ast_log(LOG_WARNING,
+ "Parking lot '%s' parking spaces overlap template parking lot '%s'!\n"
+ "Change PARKINGDYNPOS.\n",
+ parkinglot->name, template_parkinglot->name);
+ }
+ }
+
+ parkinglot_activate(parkinglot);
+ ao2_link(parkinglots, parkinglot);
+ }
+ parkinglot_unref(template_parkinglot);
+
+ return parkinglot;
+}
+
+/*!
+ * \internal
* \brief Reserve a parking space in a parking lot for a call being parked.
*
- * \param chan Channel being parked.
- * \param peer Channel parking the call.
+ * \param park_me Channel being parked.
+ * \param parker Channel parking the call.
* \param args Optional additional parking options when parking a call.
*
* \return Parked call descriptor or NULL if failed.
* \note The parking lot list is locked if successful.
*/
-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 *park_me, struct ast_channel *parker, struct ast_park_call_args *args)
{
struct parkeduser *pu;
int i;
@@ -1044,10 +1156,10 @@
parkinglot = parkinglot_addref(args->parkinglot);
parkinglotname = parkinglot->name;
} else {
- if (peer) {
- parkinglotname = findparkinglotname(peer);
- } else { /* peer was NULL, check chan (ParkAndAnnounce / res_agi) */
- parkinglotname = findparkinglotname(chan);
+ if (parker) {
+ parkinglotname = findparkinglotname(parker);
+ } else { /* parker was NULL, check park_me (ParkAndAnnounce / res_agi) */
+ parkinglotname = findparkinglotname(park_me);
}
if (!ast_strlen_zero(parkinglotname)) {
parkinglot = find_parkinglot(parkinglotname);
@@ -1060,70 +1172,11 @@
/* Dynamically create parkinglot */
if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
- const char *dyn_context;
- const char *dyn_range;
- const char *parkinglotname_copy;
- struct ast_parkinglot *parkinglot_copy = NULL;
- int dyn_start;
- int dyn_end;
-
- /* XXX Why are we getting dynamic parkinglot information from chan and not peer? */
- 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) {
- ast_debug(1, "PARKINGDYNAMIC lot %s does not exist.\n",
- parkinglotname_copy);
- } else if (parkinglot_copy->cfg.is_invalid) {
- ast_debug(1, "PARKINGDYNAMIC lot %s has invalid config.\n",
- parkinglotname_copy);
- parkinglot_unref(parkinglot_copy);
- parkinglot_copy = NULL;
- }
- }
- if (!parkinglot_copy) {
- parkinglot_copy = parkinglot_addref(default_parkinglot);
- ast_debug(1, "Using default parking lot for copy\n");
- }
- parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy);
-
-/* BUGBUG we should check that the dynamic parking lot does not use the same context and parkext as the template lot. */
-/* If this is the case it will make the template lot difficult to park new calls in using the standard access ramp. */
- /* unref our temporary copy */
- parkinglot_unref(parkinglot_copy);
- parkinglot_copy = NULL;
-
- if (!parkinglot) {
- ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
- } else {
- if (!ast_strlen_zero(dyn_context)) {
- ast_copy_string(parkinglot->cfg.parking_con, dyn_context,
- sizeof(parkinglot->cfg.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 if (dyn_end < dyn_start || dyn_start <= 0 || dyn_end <= 0) {
- ast_log(LOG_WARNING,
- "Format for parking positions is a-b, where a <= b\n");
- } else {
- parkinglot->cfg.parking_start = dyn_start;
- parkinglot->cfg.parking_stop = dyn_end;
- }
- }
- parkinglot_activate(parkinglot);
- ao2_link(parkinglots, parkinglot);
- }
+ parkinglot = create_dynamic_parkinglot(parkinglotname, park_me);
}
if (!parkinglot) {
- ast_log(LOG_WARNING, "Parking lot not available to park %s.\n", chan->name);
+ ast_log(LOG_WARNING, "Parking lot not available to park %s.\n", park_me->name);
return NULL;
}
@@ -1145,7 +1198,7 @@
AST_LIST_LOCK(&parkinglot->parkings);
/* Check for channel variable PARKINGEXTEN */
- parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
+ parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(park_me, "PARKINGEXTEN"), ""));
if (!ast_strlen_zero(parkingexten)) {
/*!
* \note The API forces us to specify a numeric parking slot, even
@@ -1443,8 +1496,8 @@
}
/*!
- * \param rchan is the transferee
- * \param peer is the transferer
+ * \param rchan the real channel to be parked
+ * \param peer the channel to have the parking read to.
*/
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)
{
@@ -1573,6 +1626,10 @@
args.parkinglot = parkinglot_addref(default_parkinglot);
} else {
args.parkinglot = find_parkinglot(pl_name);
+ if (!args.parkinglot && parkeddynamic) {
+ args.parkinglot = create_dynamic_parkinglot(pl_name, park_me);
+ }
+
}
if (args.parkinglot) {
res = masq_park_call_announce(park_me, parker, &args);
@@ -4660,6 +4717,9 @@
args.parkinglot = parkinglot_addref(default_parkinglot);
} else {
args.parkinglot = find_parkinglot(pl_name);
+ if (!args.parkinglot && parkeddynamic) {
+ args.parkinglot = create_dynamic_parkinglot(pl_name, chan);
+ }
}
if (args.parkinglot) {
res = masq_park_call_announce(chan, chan, &args);
More information about the asterisk-commits
mailing list