[asterisk-commits] mmichelson: branch mmichelson/features_config r390091 - in /team/mmichelson/f...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 29 16:08:15 CDT 2013
Author: mmichelson
Date: Wed May 29 16:08:11 2013
New Revision: 390091
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=390091
Log:
Large purge of unneeded content from features.c
For the most part, this commit removes operations and structures
that are no longer needed in features.c since there is a counterpart
in features_config.[ch] that is used now.
The other related change was to move the 'feature show' CLI command
into features_config.c
Modified:
team/mmichelson/features_config/include/asterisk/features.h
team/mmichelson/features_config/main/features.c
team/mmichelson/features_config/main/features_config.c
Modified: team/mmichelson/features_config/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/include/asterisk/features.h?view=diff&rev=390091&r1=390090&r2=390091
==============================================================================
--- team/mmichelson/features_config/include/asterisk/features.h (original)
+++ team/mmichelson/features_config/include/asterisk/features.h Wed May 29 16:08:11 2013
@@ -218,23 +218,6 @@
*/
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target);
-/*!
- * \brief register new feature into feature_set
- * \param feature an ast_call_feature object which contains a keysequence
- * and a callback function which is called when this keysequence is pressed
- * during a call.
-*/
-void ast_register_feature(struct ast_call_feature *feature);
-
-/*!
- * \brief unregister feature from feature_set
- * \param feature the ast_call_feature object which was registered before
-*/
-void ast_unregister_feature(struct ast_call_feature *feature);
-
-void ast_rdlock_call_features(void);
-void ast_unlock_call_features(void);
-
/*! \brief Reload call features from features.conf */
int ast_features_reload(void);
Modified: team/mmichelson/features_config/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/main/features.c?view=diff&rev=390091&r1=390090&r2=390091
==============================================================================
--- team/mmichelson/features_config/main/features.c (original)
+++ team/mmichelson/features_config/main/features.c Wed May 29 16:08:11 2013
@@ -405,24 +405,6 @@
/* TODO Scrape all of the parking stuff out of features.c */
-struct feature_group_exten {
- AST_LIST_ENTRY(feature_group_exten) entry;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(exten);
- );
- struct ast_call_feature *feature;
-};
-
-struct feature_group {
- AST_LIST_ENTRY(feature_group) entry;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(gname);
- );
- AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
-};
-
-static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
-
typedef enum {
FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
FEATURE_INTERPRET_DO, /* Used by feature_interpret */
@@ -2932,26 +2914,6 @@
/* add atxfer and automon as undefined so you can only use em if you configure them */
#define FEATURES_COUNT ARRAY_LEN(builtin_features)
-AST_RWLOCK_DEFINE_STATIC(features_lock);
-
-/*! \note This is protected by features_lock. */
-static AST_LIST_HEAD_NOLOCK_STATIC(feature_list, ast_call_feature);
-
-static void ast_wrlock_call_features(void)
-{
- ast_rwlock_wrlock(&features_lock);
-}
-
-void ast_rdlock_call_features(void)
-{
- ast_rwlock_rdlock(&features_lock);
-}
-
-void ast_unlock_call_features(void)
-{
- ast_rwlock_unlock(&features_lock);
-}
-
/*! \note This is protected by features_lock. */
static struct ast_call_feature builtin_features[] = {
{ AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
@@ -2961,70 +2923,6 @@
{ AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
{ AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
};
-
-/*! \brief register new feature into feature_list */
-void ast_register_feature(struct ast_call_feature *feature)
-{
- if (!feature) {
- ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
- return;
- }
-
- ast_wrlock_call_features();
- AST_LIST_INSERT_HEAD(&feature_list, feature, feature_entry);
- ast_unlock_call_features();
-
- ast_verb(2, "Registered Feature '%s'\n",feature->sname);
-}
-
-void ast_unregister_feature(struct ast_call_feature *feature)
-{
- if (!feature) {
- return;
- }
-
- ast_wrlock_call_features();
- AST_LIST_REMOVE(&feature_list, feature, feature_entry);
- ast_unlock_call_features();
-
- ast_free(feature);
-}
-
-/*!
- * \internal
- * \brief find a dynamic call feature by name
- * \pre Expects features_lock to be at least readlocked
- */
-static struct ast_call_feature *find_dynamic_feature(const char *name)
-{
- struct ast_call_feature *tmp;
-
- AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
- if (!strcasecmp(tmp->sname, name)) {
- break;
- }
- }
-
- return tmp;
-}
-
-/*!
- * \brief Find a group by name
- * \param name feature name
- * \retval feature group on success.
- * \retval NULL on failure.
- */
-static struct feature_group *find_group(const char *name)
-{
- struct feature_group *fg = NULL;
-
- AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
- if (!strcasecmp(fg->gname, name))
- break;
- }
-
- return fg;
-}
/*!
* \internal
@@ -3340,7 +3238,6 @@
/* BUGBUG there is code that checks AST_BRIDGE_REC_CHANNEL_1 but no code to set it. */
ast_clear_flag(config, AST_FLAGS_ALL);
- ast_rdlock_call_features();
for (x = 0; x < FEATURES_COUNT; x++) {
if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
continue;
@@ -3351,48 +3248,20 @@
if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
}
- ast_unlock_call_features();
if (!(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
- const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
-
- if (dynamic_features) {
- char *tmp = ast_strdupa(dynamic_features);
- char *tok;
- struct ast_call_feature *feature;
-
- /* while we have a feature */
- while ((tok = strsep(&tmp, "#"))) {
- struct feature_group *fg;
-
- AST_RWLIST_RDLOCK(&feature_groups);
- fg = find_group(tok);
- if (fg) {
- struct feature_group_exten *fge;
-
- AST_LIST_TRAVERSE(&fg->features, fge, entry) {
- if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLER)) {
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
- }
- if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLEE)) {
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
- }
- }
- }
- AST_RWLIST_UNLOCK(&feature_groups);
-
- ast_rdlock_call_features();
- if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
- if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
- }
- if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) {
- ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
- }
- }
- ast_unlock_call_features();
- }
- }
+ RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
+
+ ast_channel_lock(chan);
+ applicationmap = ast_get_chan_applicationmap(chan);
+ ast_channel_unlock(chan);
+
+ if (!applicationmap) {
+ return;
+ }
+
+ /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
+ ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
}
}
@@ -3447,10 +3316,12 @@
int ready = 0;
struct timeval started;
int x, len = 0;
- char *disconnect_code = NULL, *dialed_code = NULL;
+ char disconnect_code[FEATURE_MAX_LEN];
+ char *dialed_code = NULL;
struct ast_format_cap *tmp_cap;
struct ast_format best_audio_fmt;
struct ast_frame *f;
+ int disconnect_res;
AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
tmp_cap = ast_format_cap_alloc_nolock();
@@ -3506,18 +3377,17 @@
}
/* support dialing of the featuremap disconnect code while performing an attended tranfer */
- ast_rdlock_call_features();
- for (x = 0; x < FEATURES_COUNT; x++) {
- if (strcasecmp(builtin_features[x].sname, "disconnect"))
- continue;
-
- disconnect_code = builtin_features[x].exten;
+ ast_channel_lock(chan);
+ disconnect_res = ast_get_builtin_feature(chan, "disconnect",
+ disconnect_code, sizeof(disconnect_code));
+ ast_channel_unlock(chan);
+
+ if (!disconnect_res) {
len = strlen(disconnect_code) + 1;
dialed_code = ast_alloca(len);
memset(dialed_code, 0, len);
- break;
- }
- ast_unlock_call_features();
+ }
+
x = 0;
started = ast_tvnow();
to = timeout;
@@ -3677,7 +3547,7 @@
} else if (caller == active_channel) {
f = ast_read(caller);
if (f) {
- if (f->frametype == AST_FRAME_DTMF) {
+ if (f->frametype == AST_FRAME_DTMF && dialed_code) {
dialed_code[x++] = f->subclass.integer;
dialed_code[x] = '\0';
if (strlen(dialed_code) == len) {
@@ -4942,80 +4812,6 @@
return disabled ? -1 : 0;
}
-/*!
- * \brief CLI command to list configured features
- * \param e
- * \param cmd
- * \param a
- *
- * \retval CLI_SUCCESS on success.
- * \retval NULL when tab completion is used.
- */
-static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
- int i;
- struct ast_call_feature *feature;
- RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, ast_get_chan_features_pickup_config(NULL), ao2_cleanup);
-#define HFS_FORMAT "%-25s %-7s %-7s\n"
-
- switch (cmd) {
-
- case CLI_INIT:
- e->command = "features show";
- e->usage =
- "Usage: features show\n"
- " Lists configured features\n";
- return NULL;
- case CLI_GENERATE:
- return NULL;
- }
-
- ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
- ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
-
- ast_cli(a->fd, HFS_FORMAT, "Pickup", "*8", pickup_cfg->pickupexten); /* default hardcoded above, so we'll hardcode it here */
-
- ast_rdlock_call_features();
- for (i = 0; i < FEATURES_COUNT; i++)
- ast_cli(a->fd, HFS_FORMAT, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
- ast_unlock_call_features();
-
- ast_cli(a->fd, "\n");
- ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
- ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
- ast_rdlock_call_features();
- if (AST_LIST_EMPTY(&feature_list)) {
- ast_cli(a->fd, "(none)\n");
- } else {
- AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
- ast_cli(a->fd, HFS_FORMAT, feature->sname, "no def", feature->exten);
- }
- }
- ast_unlock_call_features();
-
- ast_cli(a->fd, "\nFeature Groups:\n");
- ast_cli(a->fd, "---------------\n");
- AST_RWLIST_RDLOCK(&feature_groups);
- if (AST_RWLIST_EMPTY(&feature_groups)) {
- ast_cli(a->fd, "(none)\n");
- } else {
- struct feature_group *fg;
- struct feature_group_exten *fge;
-
- AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
- ast_cli(a->fd, "===> Group: %s\n", fg->gname);
- AST_LIST_TRAVERSE(&fg->features, fge, entry) {
- ast_cli(a->fd, "===> --> %s (%s)\n", fge->feature->sname, fge->exten);
- }
- }
- }
- AST_RWLIST_UNLOCK(&feature_groups);
-
- ast_cli(a->fd, "\n");
-
- return CLI_SUCCESS;
-}
-
int ast_features_reload(void)
{
struct ast_context *con;
@@ -5277,7 +5073,6 @@
}
static struct ast_cli_entry cli_features[] = {
- AST_CLI_DEFINE(handle_feature_show, "Lists configured features"),
AST_CLI_DEFINE(handle_features_reload, "Reloads configured features"),
};
Modified: team/mmichelson/features_config/main/features_config.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/main/features_config.c?view=diff&rev=390091&r1=390090&r2=390091
==============================================================================
--- team/mmichelson/features_config/main/features_config.c (original)
+++ team/mmichelson/features_config/main/features_config.c Wed May 29 16:08:11 2013
@@ -24,6 +24,7 @@
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
+#include "asterisk/cli.h"
#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 /*!< ms */
#define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000 /*!< ms */
@@ -786,14 +787,7 @@
}
/* Dang, must be in the application map */
- if (chan) {
- applicationmap = ast_get_chan_applicationmap(chan);
- } else {
- RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
-
- ao2_ref(cfg->applicationmap, +1);
- applicationmap = cfg->applicationmap;
- }
+ applicationmap = ast_get_chan_applicationmap(chan);
if (!applicationmap) {
return -1;
@@ -857,8 +851,15 @@
char *group_names;
char *name;
- if (!chan || !cfg) {
- return NULL;
+ if (!cfg) {
+ return NULL;
+ }
+
+ if (!chan) {
+ if (!cfg->applicationmap || ao2_container_count(cfg->applicationmap) == 0) {
+ return NULL;
+ }
+ return cfg->applicationmap;
}
group_names = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"), ""));
@@ -1246,11 +1247,108 @@
return 0;
}
+static int print_featuregroup(void *obj, void *arg, int flags)
+{
+ struct featuregroup_item *item = obj;
+ struct ast_cli_args *a = arg;
+
+ ast_cli(a->fd, "===> --> %s (%s)\n", item->appmap_item_name,
+ S_OR(item->dtmf_override, item->appmap_item->dtmf));
+
+ return 0;
+}
+
+static int print_featuregroups(void *obj, void *arg, int flags)
+{
+ struct featuregroup *group = obj;
+ struct ast_cli_args *a = arg;
+
+ ast_cli(a->fd, "===> Group: %s\n", group->name);
+
+ ao2_callback(group->items, 0, print_featuregroup, a);
+ return 0;
+}
+
+#define HFS_FORMAT "%-25s %-7s %-7s\n"
+
+static int print_applicationmap(void *obj, void *arg, int flags)
+{
+ struct ast_applicationmap_item *item = obj;
+ struct ast_cli_args *a = arg;
+
+ ast_cli(a->fd, HFS_FORMAT, item->name, "no def", item->dtmf);
+ return 0;
+}
+
+/*!
+ * \brief CLI command to list configured features
+ * \param e
+ * \param cmd
+ * \param a
+ *
+ * \retval CLI_SUCCESS on success.
+ * \retval NULL when tab completion is used.
+ */
+static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
+
+ switch (cmd) {
+
+ case CLI_INIT:
+ e->command = "features show";
+ e->usage =
+ "Usage: features show\n"
+ " Lists configured features\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ cfg = ao2_global_obj_ref(globals);
+
+ ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
+ ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
+
+ ast_cli(a->fd, HFS_FORMAT, "Pickup", "*8", cfg->global->pickup->pickupexten); /* default hardcoded above, so we'll hardcode it here */
+ ast_cli(a->fd, HFS_FORMAT, "Blind Transfer", "#", cfg->featuremap->blindxfer);
+ ast_cli(a->fd, HFS_FORMAT, "Attended Transfer", "", cfg->featuremap->atxfer);
+ ast_cli(a->fd, HFS_FORMAT, "One Touch Monitor", "", cfg->featuremap->automon);
+ ast_cli(a->fd, HFS_FORMAT, "Disconnect Call", "*", cfg->featuremap->disconnect);
+ ast_cli(a->fd, HFS_FORMAT, "Park Call", "", cfg->featuremap->parkcall);
+ ast_cli(a->fd, HFS_FORMAT, "One Touch MixMonitor", "", cfg->featuremap->automixmon);
+
+ ast_cli(a->fd, "\n");
+ ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
+ ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
+ if (!cfg->applicationmap || ao2_container_count(cfg->applicationmap) == 0) {
+ ast_cli(a->fd, "(none)\n");
+ } else {
+ ao2_callback(cfg->applicationmap, 0, print_applicationmap, a);
+ }
+
+ ast_cli(a->fd, "\nFeature Groups:\n");
+ ast_cli(a->fd, "---------------\n");
+ if (!cfg->featuregroups || ao2_container_count(cfg->featuregroups) == 0) {
+ ast_cli(a->fd, "(none)\n");
+ } else {
+ ao2_callback(cfg->featuregroups, 0, print_featuregroups, a);
+ }
+
+ ast_cli(a->fd, "\n");
+
+ return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry cli_features_config[] = {
+ AST_CLI_DEFINE(handle_feature_show, "Lists configured features"),
+};
void ast_features_config_shutdown(void)
{
ast_custom_function_unregister(&featuremap_function);
ast_custom_function_unregister(&feature_function);
+ ast_cli_unregister_multiple(cli_features_config, ARRAY_LEN(cli_features_config));
aco_info_destroy(&cfg_info);
ao2_global_obj_release(globals);
}
@@ -1271,6 +1369,7 @@
res |= __ast_custom_function_register(&feature_function, NULL);
res |= __ast_custom_function_register(&featuremap_function, NULL);
+ res |= ast_cli_register_multiple(cli_features_config, ARRAY_LEN(cli_features_config));
return res;
}
More information about the asterisk-commits
mailing list