[asterisk-commits] rmudgett: branch rmudgett/parking r329894 - /team/rmudgett/parking/main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 27 19:25:01 CDT 2011
Author: rmudgett
Date: Wed Jul 27 19:24:58 2011
New Revision: 329894
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=329894
Log:
Work in progress.
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=329894&r1=329893&r2=329894
==============================================================================
--- team/rmudgett/parking/main/features.c (original)
+++ team/rmudgett/parking/main/features.c Wed Jul 27 19:24:58 2011
@@ -466,7 +466,6 @@
/*! Add parking hints automatically */
unsigned int parkaddhints:1;
-/* BUGBUG need to make use is_invalid to prevent use of parking lot. */
/*! TRUE if configuration is invalid and the parking lot should not be used. */
unsigned int is_invalid:1;
};
@@ -480,7 +479,6 @@
/*! That which bears the_mark shall be deleted if parking lot empty! (Used during reloads.) */
unsigned int the_mark:1;
-/* BUGBUG need to make use disabled flag to prevent new calls going into the parking lot. */
/*! TRUE if the parking lot is disabled. */
unsigned int disabled:1;
@@ -494,13 +492,16 @@
/*!
* \brief Default parking lot.
* \note Holds a parkinglot reference.
- * \note Will not be NULL while running. (BUGBUG can I guarantee this? The code already expects it.)
+ * \note Will not be NULL while running.
*/
static struct ast_parkinglot *default_parkinglot;
-static char courtesytone[256]; /*!< Courtesy tone */
+/*! Force a config reload to reload regardless of config file timestamp. */
+static int force_reload_load;
+
static int parkedplay = 0; /*!< Who to play the courtesy tone to */
static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
+static char courtesytone[256]; /*!< Courtesy tone */
static char xfersound[256]; /*!< Call transfer sound */
static char xferfailsound[256]; /*!< Call transfer failure sound */
static char pickupsound[256]; /*!< Pickup sound */
@@ -646,6 +647,7 @@
static 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);
+static int parkinglot_activate(struct ast_parkinglot *parkinglot);
int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
{
@@ -951,6 +953,10 @@
}
if (!ast_strlen_zero(parkinglotname)) {
parkinglot = find_parkinglot(parkinglotname);
+ } else {
+ /* Parking lot is not specified. Fallback to default lot. */
+ ast_debug(4, "This could be an indication channel driver needs updating, using default lot.\n");
+ parkinglot = parkinglot_addref(default_parkinglot);
}
}
@@ -972,8 +978,12 @@
if (!ast_strlen_zero(parkinglotname_copy)) {
parkinglot_copy = find_parkinglot(parkinglotname_copy);
- if (parkinglot_copy && parkinglot_copy->cfg.is_invalid) {
- ast_debug(1, "Requested parking lot has invalid config.\n");
+ 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;
}
@@ -1007,17 +1017,23 @@
parkinglot->cfg.parking_stop = dyn_end;
}
}
-/* BUGBUG need to create the dynamic parking lot context and park extension if they do not already exist! */
+ parkinglot_activate(parkinglot);
ao2_link(parkinglots, parkinglot);
}
}
if (!parkinglot) {
- /* We'll just have to use the default parking lot. */
- parkinglot = parkinglot_addref(default_parkinglot);
- }
-
- ast_debug(1, "Parkinglot: %s\n", parkinglot->name);
+ ast_log(LOG_WARNING, "Parking lot not available to park %s.\n", chan->name);
+ return NULL;
+ }
+
+ ast_debug(1, "Parking lot: %s\n", parkinglot->name);
+ if (parkinglot->disabled || parkinglot->cfg.is_invalid) {
+ ast_log(LOG_WARNING, "Parking lot %s is not in a useable state.\n",
+ parkinglot->name);
+ parkinglot_unref(parkinglot);
+ return NULL;
+ }
/* Allocate memory for parking data */
if (!(pu = ast_calloc(1, sizeof(*pu)))) {
@@ -1039,8 +1055,7 @@
* arbitrary non-numeric extensions.
*/
if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space <= 0) {
- ast_log(LOG_WARNING,
- "PARKINGEXTEN does not indicate a valid parking space: '%s'.\n",
+ ast_log(LOG_WARNING, "PARKINGEXTEN='%s' is not a valid parking space.\n",
parkingexten);
AST_LIST_UNLOCK(&parkinglot->parkings);
parkinglot_unref(parkinglot);
@@ -1055,8 +1070,7 @@
* outside of lot. (Things like dialplan hints don't exist for
* outside lot space.)
*/
- ast_log(LOG_WARNING,
- "PARKINGEXTEN requested parking space %d is not in %s (%d-%d).\n",
+ ast_log(LOG_WARNING, "PARKINGEXTEN=%d is not in %s (%d-%d).\n",
parking_space, parkinglot->name, parkinglot->cfg.parking_start,
parkinglot->cfg.parking_stop);
AST_LIST_UNLOCK(&parkinglot->parkings);
@@ -1068,8 +1082,7 @@
/* Check if requested parking space is in use. */
AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
if (cur->parkingnum == parking_space) {
- ast_log(LOG_WARNING,
- "PARKINGEXTEN requested parking space %d is in use in %s\n",
+ ast_log(LOG_WARNING, "PARKINGEXTEN=%d is already in use in %s\n",
parking_space, parkinglot->name);
AST_LIST_UNLOCK(&parkinglot->parkings);
parkinglot_unref(parkinglot);
@@ -4264,6 +4277,8 @@
}
}
+/* BUGBUG need to check collision of recall call and parking pickup scenario. */
+/* BUGBUG need to protect cfg.parking_con_dial context from the config reload routine. */
con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->cfg.parking_con_dial, registrar);
if (!con) {
ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->cfg.parking_con_dial);
@@ -4480,7 +4495,7 @@
parkinglot = ao2_find(parkinglots, (void *) name, 0);
if (parkinglot) {
- ast_debug(1, "Found Parkinglot: %s\n", parkinglot->name);
+ ast_debug(1, "Found Parking lot: %s\n", parkinglot->name);
}
return parkinglot;
@@ -4857,12 +4872,12 @@
}
/*!
- * \brief Add parking hints for all defined parking lots
- * \param context
- * \param start starting parkinglot number
- * \param stop ending parkinglot number
+ * \brief Add parking hints for all defined parking spaces.
+ * \param context Dialplan context to add the hints.
+ * \param start Starting space in parkinglot.
+ * \param stop Ending space in parkinglot.
*/
-static void park_add_hints(char *context, int start, int stop)
+static void park_add_hints(const char *context, int start, int stop)
{
int numext;
char device[AST_MAX_EXTENSION];
@@ -4895,37 +4910,58 @@
/*!
* \internal
+ * \brief Set parking lot feature flag configuration value.
+ *
+ * \param pl_name Parking lot name for diagnostic messages.
+ * \param param Parameter value to set.
+ * \param var Current configuration variable item.
+ *
+ * \return Nothing
+ */
+static void parkinglot_feature_flag_cfg(const char *pl_name, int *param, struct ast_variable *var)
+{
+ ast_debug(1, "Setting parking lot %s %s to %s\n", pl_name, var->name, var->value);
+ if (!strcasecmp(var->value, "both")) {
+ *param = AST_FEATURE_FLAG_BYBOTH;
+ } else if (!strcasecmp(var->value, "caller")) {
+ *param = AST_FEATURE_FLAG_BYCALLER;
+ } else if (!strcasecmp(var->value, "callee")) {
+ *param = AST_FEATURE_FLAG_BYCALLEE;
+ }
+}
+
+/*!
+ * \internal
* \brief Read parking lot configuration.
*
- * \param parkinglot Parking lot to read user config into.
- * \param cfg_defaults Parking lot default values to start with.
+ * \param pl_name Parking lot name for diagnostic messages.
+ * \param cfg Parking lot config to update that is already initialized with defaults.
* \param var Config variable list.
*
* \retval 0 on success.
- * \retval 1 on error.
+ * \retval -1 on error.
*/
-static int parkinglot_config_read(struct ast_parkinglot *parkinglot, const struct parkinglot_cfg *cfg_defaults, struct ast_variable *var)
+static int parkinglot_config_read(const char *pl_name, struct parkinglot_cfg *cfg, struct ast_variable *var)
{
int error = 0;
- parkinglot->cfg = *cfg_defaults;
while (var) {
if (!strcasecmp(var->name, "context")) {
- ast_copy_string(parkinglot->cfg.parking_con, var->value, sizeof(parkinglot->cfg.parking_con));
+ ast_copy_string(cfg->parking_con, var->value, sizeof(cfg->parking_con));
} else if (!strcasecmp(var->name, "parkext")) {
- ast_copy_string(parkinglot->cfg.parkext, var->value, sizeof(parkinglot->cfg.parkext));
+ ast_copy_string(cfg->parkext, var->value, sizeof(cfg->parkext));
} else if (!strcasecmp(var->name, "parkinghints")) {
- parkinglot->cfg.parkaddhints = ast_true(var->value);
+ cfg->parkaddhints = ast_true(var->value);
} else if (!strcasecmp(var->name, "parkedmusicclass")) {
- ast_copy_string(parkinglot->cfg.mohclass, var->value, sizeof(parkinglot->cfg.mohclass));
+ ast_copy_string(cfg->mohclass, var->value, sizeof(cfg->mohclass));
} else if (!strcasecmp(var->name, "parkingtime")) {
int parkingtime = 0;
if ((sscanf(var->value, "%30d", &parkingtime) != 1) || parkingtime < 1) {
ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
- error = 1;
+ error = -1;
} else {
- parkinglot->cfg.parkingtime = parkingtime * 1000;
+ cfg->parkingtime = parkingtime * 1000;
}
} else if (!strcasecmp(var->name, "parkpos")) {
int start = 0;
@@ -4935,152 +4971,161 @@
ast_log(LOG_WARNING,
"Format for parking positions is a-b, where a and b are numbers at line %d of %s\n",
var->lineno, var->file);
- error = 1;
+ error = -1;
} else if (end < start || start <= 0 || end <= 0) {
ast_log(LOG_WARNING, "Parking range is invalid. Must be a <= b, at line %d of %s\n",
var->lineno, var->file);
- error = 1;
+ error = -1;
} else {
- parkinglot->cfg.parking_start = start;
- parkinglot->cfg.parking_stop = end;
+ cfg->parking_start = start;
+ cfg->parking_stop = end;
}
} else if (!strcasecmp(var->name, "parkedcalltransfers")) {
- ast_debug(1, "Setting parking lot %s %s to %s\n",
- parkinglot->name, var->name, var->value);
- if (!strcasecmp(var->value, "both")) {
- parkinglot->cfg.parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
- } else if (!strcasecmp(var->value, "caller")) {
- parkinglot->cfg.parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
- } else if (!strcasecmp(var->value, "callee")) {
- parkinglot->cfg.parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
- }
+ parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcalltransfers, var);
} else if (!strcasecmp(var->name, "parkedcallreparking")) {
- ast_debug(1, "Setting parking lot %s %s to %s\n",
- parkinglot->name, var->name, var->value);
- if (!strcasecmp(var->value, "both")) {
- parkinglot->cfg.parkedcallreparking = AST_FEATURE_FLAG_BYBOTH;
- } else if (!strcasecmp(var->value, "caller")) {
- parkinglot->cfg.parkedcallreparking = AST_FEATURE_FLAG_BYCALLER;
- } else if (!strcasecmp(var->value, "callee")) {
- parkinglot->cfg.parkedcallreparking = AST_FEATURE_FLAG_BYCALLEE;
- }
+ parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallreparking, var);
} else if (!strcasecmp(var->name, "parkedcallhangup")) {
- ast_debug(1, "Setting parking lot %s %s to %s\n",
- parkinglot->name, var->name, var->value);
- if (!strcasecmp(var->value, "both")) {
- parkinglot->cfg.parkedcallhangup = AST_FEATURE_FLAG_BYBOTH;
- } else if (!strcasecmp(var->value, "caller")) {
- parkinglot->cfg.parkedcallhangup = AST_FEATURE_FLAG_BYCALLER;
- } else if (!strcasecmp(var->value, "callee")) {
- parkinglot->cfg.parkedcallhangup = AST_FEATURE_FLAG_BYCALLEE;
- }
+ parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallhangup, var);
} else if (!strcasecmp(var->name, "parkedcallrecording")) {
- ast_debug(1, "Setting parking lot %s %s to %s\n",
- parkinglot->name, var->name, var->value);
- if (!strcasecmp(var->value, "both")) {
- parkinglot->cfg.parkedcallrecording = AST_FEATURE_FLAG_BYBOTH;
- } else if (!strcasecmp(var->value, "caller")) {
- parkinglot->cfg.parkedcallrecording = AST_FEATURE_FLAG_BYCALLER;
- } else if (!strcasecmp(var->value, "callee")) {
- parkinglot->cfg.parkedcallrecording = AST_FEATURE_FLAG_BYCALLEE;
- }
+ parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallrecording, var);
}
var = var->next;
}
/* Check for configuration errors */
- if (ast_strlen_zero(parkinglot->cfg.parking_con)) {
- ast_log(LOG_WARNING, "Parking lot %s needs context\n", parkinglot->name);
- error = 1;
- }
- if (ast_strlen_zero(parkinglot->cfg.parkext)) {
- ast_log(LOG_WARNING, "Parking lot %s needs parkext\n", parkinglot->name);
- error = 1;
- }
- if (!parkinglot->cfg.parking_start) {
- ast_log(LOG_WARNING, "Parking lot %s needs parkpos\n", parkinglot->name);
- error = 1;
+ if (ast_strlen_zero(cfg->parking_con)) {
+ ast_log(LOG_WARNING, "Parking lot %s needs context\n", pl_name);
+ error = -1;
+ }
+ if (ast_strlen_zero(cfg->parkext)) {
+ ast_log(LOG_WARNING, "Parking lot %s needs parkext\n", pl_name);
+ error = -1;
+ }
+ if (!cfg->parking_start) {
+ ast_log(LOG_WARNING, "Parking lot %s needs parkpos\n", pl_name);
+ error = -1;
}
if (error) {
- parkinglot->cfg.is_invalid = 1;
+ cfg->is_invalid = 1;
}
return error;
}
+/*!
+ * \internal
+ * \brief Activate the given parkinglot.
+ *
+ * \param parkinglot Parking lot to activate.
+ *
+ * \details
+ * Insert into the dialplan the context, parking lot access
+ * extension, and optional dialplan hints.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int parkinglot_activate(struct ast_parkinglot *parkinglot)
+{
+ int disabled = 0;
+ struct ast_context *con;
+
+ /* Create context */
+ con = ast_context_find_or_create(NULL, NULL, parkinglot->cfg.parking_con, registrar);
+ if (!con) {
+ ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n",
+ parkinglot->cfg.parking_con);
+ disabled = 1;
+
+ /* Add a parking extension into the context */
+ } else if (ast_add_extension2(con, 1, parkinglot->cfg.parkext, 1, NULL, NULL,
+ parkcall, ast_strdup(""), ast_free_ptr, registrar)) {
+ ast_log(LOG_ERROR, "Could not create parking lot %s access exten %s@%s\n",
+ parkinglot->name, parkinglot->cfg.parkext, parkinglot->cfg.parking_con);
+ disabled = 1;
+ } else {
+ /* Add parking hints */
+ if (parkinglot->cfg.parkaddhints) {
+ park_add_hints(parkinglot->cfg.parking_con, parkinglot->cfg.parking_start,
+ parkinglot->cfg.parking_stop);
+ }
+
+ /*
+ * XXX Not sure why we should need to notify the metermaids for
+ * this exten. It was originally done for the default parking
+ * lot entry exten only.
+ */
+ /* Notify metermaids about parking lot entry exten state. */
+ notify_metermaids(parkinglot->cfg.parkext, parkinglot->cfg.parking_con,
+ AST_DEVICE_INUSE);
+ }
+
+ parkinglot->disabled = disabled;
+ return disabled ? -1 : 0;
+}
+
/*! \brief Build parkinglot from configuration and chain it in if it doesn't already exist */
-static struct ast_parkinglot *build_parkinglot(const char *name, struct ast_variable *var)
+static struct ast_parkinglot *build_parkinglot(const char *pl_name, struct ast_variable *var)
{
struct ast_parkinglot *parkinglot;
- struct ast_context *con = NULL;
- struct parkinglot_cfg orig_cfg;
const struct parkinglot_cfg *cfg_defaults;
- int error;
+ struct parkinglot_cfg new_cfg;
+ int cfg_error;
int oldparkinglot = 0;
- parkinglot = find_parkinglot(name);
+ parkinglot = find_parkinglot(pl_name);
if (parkinglot) {
oldparkinglot = 1;
} else {
- parkinglot = create_parkinglot(name);
+ parkinglot = create_parkinglot(pl_name);
if (!parkinglot) {
return NULL;
}
}
- if (!strcmp(name, DEFAULT_PARKINGLOT)) {
+ if (!strcmp(parkinglot->name, DEFAULT_PARKINGLOT)) {
cfg_defaults = &parkinglot_cfg_default_default;
} else {
cfg_defaults = &parkinglot_cfg_default;
}
+ new_cfg = *cfg_defaults;
+
+ ast_debug(1, "Building parking lot %s\n", parkinglot->name);
+
+ ao2_lock(parkinglot);
+
+ /* Do some config stuff */
+ cfg_error = parkinglot_config_read(parkinglot->name, &new_cfg, var);
if (oldparkinglot) {
- orig_cfg = parkinglot->cfg;
- } else {
- orig_cfg = *cfg_defaults;
- }
-
- ao2_lock(parkinglot);
-
- ast_debug(1, "Building parking lot %s\n", name);
-
- /* Do some config stuff */
- error = parkinglot_config_read(parkinglot, cfg_defaults, var);
- if (oldparkinglot) {
- if (error) {
- /* Bad configuration read so restoring original config. */
- parkinglot->cfg = orig_cfg;
- error = 0;
+ if (cfg_error) {
+ /* Bad configuration read. Keep using the original config. */
+ ast_debug(1, "Changes to parking lot %s are discarded.\n", parkinglot->name);
+ cfg_error = 0;
} else if (!AST_LIST_EMPTY(&parkinglot->parkings)
- && !memcmp(&parkinglot->cfg, &orig_cfg, sizeof(orig_cfg))) {
+ && memcmp(&new_cfg, &parkinglot->cfg, sizeof(parkinglot->cfg))) {
/* Try reloading later when parking lot is empty. */
ast_log(LOG_WARNING,
- "Parking lot %s has parked calls. Parking lot changes ignored.\n",
+ "Parking lot %s has parked calls. Parking lot changes discarded.\n",
parkinglot->name);
- parkinglot->cfg = orig_cfg;
- }
+ force_reload_load = 1;
+ } else {
+ /* Accept the new config */
+ parkinglot->cfg = new_cfg;
+ }
+ } else {
+ /* Load the initial parking lot config. */
+ parkinglot->cfg = new_cfg;
}
parkinglot->the_mark = 0;
- /* Create context */
- if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->cfg.parking_con, registrar))) {
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->cfg.parking_con);
- error = 1;
- }
-
- /* Add a parking extension into the context */
- if (!error && !oldparkinglot) {
- if (ast_add_extension2(con, 1, parkinglot->cfg.parkext, 1, NULL, NULL, parkcall, ast_strdup(""), ast_free_ptr, registrar) == -1) {
- error = 1;
- }
- }
-
- /* Add parking hints */
- if (parkinglot->cfg.parkaddhints) {
- park_add_hints(parkinglot->cfg.parking_con, parkinglot->cfg.parking_start, parkinglot->cfg.parking_stop);
- }
-
- if (error) {
- ast_log(LOG_WARNING, "Parking lot %s not open for business.\n", name);
- parkinglot->disabled = 1;
+ if (cfg_error || parkinglot_activate(parkinglot)) {
+ ast_log(LOG_WARNING, "Parking lot %s not open for business.\n", parkinglot->name);
+ if (oldparkinglot) {
+ /*
+ * The old parking lot failed to activate most likely because of
+ * changes. Allow reloading later to see if that fixes it.
+ */
+ force_reload_load = 1;
+ }
ao2_unlock(parkinglot);
parkinglot_unref(parkinglot);
return NULL;
@@ -5088,7 +5133,7 @@
ao2_unlock(parkinglot);
ast_debug(1, "Parking lot %s now open for business. (parkpos %d-%d)\n",
- name, parkinglot->cfg.parking_start, parkinglot->cfg.parking_stop);
+ parkinglot->name, parkinglot->cfg.parking_start, parkinglot->cfg.parking_stop);
/* Move it into the list, if it wasn't already there */
if (!oldparkinglot) {
@@ -5115,20 +5160,6 @@
"applicationmap"
};
-#if 0 //BUGBUG
-/* BUGBUG this defeats the mark and sweep of a reload. (Done for ASTERISK-17397 because the dialplan contexts were not cleaned up.) */
- /* Clear the existing parkinglots in the parkinglots container. */
- {
- struct ast_parkinglot *p;
- struct ao2_iterator iter = ao2_iterator_init(parkinglots, 0);
- while ((p = ao2_iterator_next(&iter))) {
- ao2_unlink(parkinglots, p);
- ao2_ref(p,-1);
- }
- ao2_iterator_destroy(&iter);
- }
-#endif
-
/* Reset to defaults */
strcpy(pickup_ext, "*8");
courtesytone[0] = '\0';
@@ -5372,20 +5403,6 @@
AST_RWLIST_UNLOCK(&feature_groups);
-#if 0 //BUGBUG should no longer need this code after redesign.
- if (!(con = ast_context_find_or_create(NULL, NULL, default_parkinglot->cfg.parking_con, registrar))) {
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", default_parkinglot->cfg.parking_con);
- return -1;
- }
- res = ast_add_extension2(con, 1, default_parkinglot->cfg.parkext, 1, NULL, NULL, parkcall, ast_strdup(""), ast_free_ptr, registrar);
- if (default_parkinglot->cfg.parkaddhints)
- park_add_hints(default_parkinglot->cfg.parking_con, default_parkinglot->cfg.parking_start, default_parkinglot->cfg.parking_stop);
- if (!res)
-#endif
-
-/* BUGBUG why is this code needed? If it is needed then the other parkinglot->cfg.parkext need to be notified as inuse. */
- notify_metermaids(default_parkinglot->cfg.parkext, default_parkinglot->cfg.parking_con, AST_DEVICE_INUSE);
-
return 0;
}
@@ -5409,6 +5426,8 @@
ast_log(LOG_WARNING,
"Parking lot %s has parked calls. Could not remove.\n",
parkinglot->name);
+ parkinglot->disabled = 1;
+ force_reload_load = 1;
}
return 0;
@@ -5417,20 +5436,24 @@
static int load_config(int reload)
{
#ifdef BUGBUG
- struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+ struct ast_flags config_flags = {
+ reload && !force_reload_load ? CONFIG_FLAG_FILEUNCHANGED : 0 };
#else
struct ast_flags config_flags = { 0 };
#endif
struct ast_config *cfg;
+ /* We are reloading now and have already determined if we will force the reload. */
+ force_reload_load = 0;
+
if (!default_parkinglot) {
- /* Must create the default parking lot */
+ /* Must create the default default parking lot */
default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
if (!default_parkinglot) {
- ast_log(LOG_ERROR, "Configuration of default parkinglot failed.\n");
+ ast_log(LOG_ERROR, "Configuration of default default parking lot failed.\n");
return -1;
}
- ast_debug(1, "Configuration of default default parkinglot done.\n");
+ ast_debug(1, "Configuration of default default parking lot done.\n");
parkinglot_addref(default_parkinglot);
}
@@ -5449,11 +5472,11 @@
/* BUGBUG build old contexts and extens usage list. */
ao2_t_callback(parkinglots, OBJ_NODATA, parkinglot_markall_cb, NULL,
- "callback to mark all parkinglots");
+ "callback to mark all parking lots");
process_config(cfg);
ast_config_destroy(cfg);
ao2_t_callback(parkinglots, OBJ_NODATA | OBJ_UNLINK, parkinglot_is_marked_cb, NULL,
- "callback to remove marked parkinglots");
+ "callback to remove marked parking lots");
/* BUGBUG build new contexts and extens usage list. */
/* BUGBUG Remove dead contexts and extens */
@@ -5554,6 +5577,8 @@
int ast_features_reload(void)
{
+/* BUGBUG Should always destroy cfg.parking_con_dial context and protect it from the manage_parkinglot() thread. */
+/* Destroying it removes buildup of recalled extensions in the context. */
return load_config(1);
}
More information about the asterisk-commits
mailing list