}
group->items = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
- AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, group_item_sort, NULL);
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, group_item_sort, NULL);
if (!group->items) {
ao2_cleanup(group);
return NULL;
return cfg;
}
-static struct ao2_container *applicationmap_alloc(void)
+static struct ao2_container *applicationmap_alloc(int replace_duplicates)
{
return ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
- AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, applicationmap_sort, NULL);
+ replace_duplicates ? AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE : AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW,
+ applicationmap_sort, NULL);
}
/*!
}
if (allocate_applicationmap) {
- cfg->applicationmap = applicationmap_alloc();
+ cfg->applicationmap = applicationmap_alloc(1);
if (!cfg->applicationmap) {
return NULL;
}
{
RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
RAII_VAR(struct ast_applicationmap_item *, item, NULL, ao2_cleanup);
+
if (!ast_get_builtin_feature(chan, feature, buf, len)) {
return 0;
}
/* Dang, must be in the application map */
applicationmap = ast_get_chan_applicationmap(chan);
-
if (!applicationmap) {
return -1;
}
return 0;
}
- if (!ao2_link(applicationmap, appmap_item)) {
- ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate\n",
- fg_item->appmap_item_name);
- }
+ ao2_link(applicationmap, appmap_item);
return 0;
}
return NULL;
}
- applicationmap = applicationmap_alloc();
+ applicationmap = applicationmap_alloc(0);
if (!applicationmap) {
return NULL;
}
while ((name = strsep(&group_names, "#"))) {
RAII_VAR(struct featuregroup *, group, ao2_find(cfg->featuregroups, name, OBJ_KEY), ao2_cleanup);
+
if (!group) {
RAII_VAR(struct ast_applicationmap_item *, item, ao2_find(cfg->applicationmap, name, OBJ_KEY), ao2_cleanup);
- if (item && !ao2_link(applicationmap, item)) {
- ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate.\n", item->name);
+
+ if (item) {
+ ao2_link(applicationmap, item);
+ } else {
+ ast_log(LOG_WARNING, "Unknown DYNAMIC_FEATURES item '%s' on channel %s.\n",
+ name, ast_channel_name(chan));
}
} else {
ao2_callback(group->items, 0, add_item, applicationmap);
}
if (!ao2_link(applicationmap, item)) {
- ast_log(LOG_WARNING, "Unable to add applicationmap item %s. Possible duplicate\n", item->name);
+ return -1;
}
return 0;
ast_string_field_set(item, dtmf_override, var->value);
if (!ao2_link(group->items, item)) {
- ast_log(LOG_WARNING, "Unable to add featuregroup item %s. Possible duplicate\n", item->appmap_item_name);
+ return -1;
}
/* We wait to look up the application map item in the preapply callback */
return pickup_set(pickup, var->name, var->value);
}
+static int unsupported_handler(const struct aco_option *opt,
+ struct ast_variable *var, void *obj)
+{
+ ast_log(LOG_WARNING, "The option '%s' is no longer configurable in features.conf.\n", var->name);
+ return 0;
+}
+
static int featuremap_handler(const struct aco_option *opt,
struct ast_variable *var, void *obj)
{
aco_option_register_custom(&cfg_info, "pickupfailsound", ACO_EXACT, global_options,
DEFAULT_PICKUPFAILSOUND, pickup_handler, 0);
+ aco_option_register_custom(&cfg_info, "context", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkext", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkext_exclusive", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkinghints", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedmusicclass", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkingtime", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkpos", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "findslot", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcalltransfers", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallreparking", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallhangup", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallrecording", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebackcontext", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebacktoorigin", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebackdialtime", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkeddynamic", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "adsipark", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+
aco_option_register_custom(&cfg_info, "blindxfer", ACO_EXACT, featuremap_options,
DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,