[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