[asterisk-commits] mmichelson: branch mmichelson/features_config r389761 - in /team/mmichelson/f...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 24 17:01:47 CDT 2013


Author: mmichelson
Date: Fri May 24 17:01:44 2013
New Revision: 389761

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389761
Log:
Create public function for getting a channel's applicationmap.

This function examines the DYNAMIC_FEATURES variable on a channel in
order to determine what features are available for the channel and
returns an ao2_container with each of the enabled features.

There is currently the possibility for duplicate entries to be
placed in the returned container, but that will be addressed later.


Modified:
    team/mmichelson/features_config/include/asterisk/features_config.h
    team/mmichelson/features_config/main/features_config.c

Modified: team/mmichelson/features_config/include/asterisk/features_config.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/include/asterisk/features_config.h?view=diff&rev=389761&r1=389760&r2=389761
==============================================================================
--- team/mmichelson/features_config/include/asterisk/features_config.h (original)
+++ team/mmichelson/features_config/include/asterisk/features_config.h Fri May 24 17:01:44 2013
@@ -159,6 +159,41 @@
  */
 int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len);
 
+#define FEATURE_MAX_LEN 11
+
+/*!
+ * \brief An applicationmap configuration item
+ */
+struct ast_applicationmap_item {
+	AST_DECLARE_STRING_FIELDS (
+		/* Name of the item */
+		AST_STRING_FIELD(name);
+		/* Name Dialplan application that is invoked by the feature */
+		AST_STRING_FIELD(app);
+		/* Data to pass to the application */
+		AST_STRING_FIELD(app_data);
+		/* Music-on-hold class to play to party on which feature is not activated */
+		AST_STRING_FIELD(moh_class);
+	);
+	/* DTMF key sequence used to activate the feature */
+	char dtmf[FEATURE_MAX_LEN];
+	/* If true, activate on party that input the sequence, otherwise activate on the other party */
+	unsigned int activate_on_self;
+};
+
+/*!
+ * \brief Get the applicationmap for a given channel.
+ *
+ * This uses the value of the DYNAMIC_FEATURES channel variable to build a
+ * custom applicationmap for this channel. The returned container has
+ * applicationmap_items inside.
+ *
+ * \param chan The channel for which applicationmap is being retrieved.
+ * \retval NULL An error occurred or the channel has no dynamic features.
+ * \retval non-NULL A container of applicationmap_items pertaining to the channel.
+ */
+struct ao2_container *ast_get_chan_applicationmap(struct ast_channel *chan);
+
 void ast_features_config_shutdown(void);
 
 int ast_features_config_reload(void);

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=389761&r1=389760&r2=389761
==============================================================================
--- team/mmichelson/features_config/main/features_config.c (original)
+++ team/mmichelson/features_config/main/features_config.c Fri May 24 17:01:44 2013
@@ -38,27 +38,16 @@
 	struct ast_features_pickup_config *pickup;
 };
 
-struct applicationmap_item {
-	AST_DECLARE_STRING_FIELDS (
-		AST_STRING_FIELD(name);
-		AST_STRING_FIELD(dtmf);
-		AST_STRING_FIELD(app);
-		AST_STRING_FIELD(app_data);
-		AST_STRING_FIELD(moh_class);
-	);
-	unsigned int activate_on_self;
-};
-
-static void applicationmap_item_destructor(void *obj)
-{
-	struct applicationmap_item *item = obj;
+static void ast_applicationmap_item_destructor(void *obj)
+{
+	struct ast_applicationmap_item *item = obj;
 
 	ast_string_field_free_memory(item);
 }
 
 static int applicationmap_hash(const void *obj, int flags)
 {
-	const struct applicationmap_item *item;
+	const struct ast_applicationmap_item *item;
 	const char *key;
 
 	switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
@@ -77,8 +66,8 @@
 
 static int applicationmap_cmp(void *obj, void *arg, int flags)
 {
-	struct applicationmap_item *item1 = obj;
-	struct applicationmap_item *item2;
+	struct ast_applicationmap_item *item1 = obj;
+	struct ast_applicationmap_item *item2;
 	const char *key2;
 
 	switch(flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
@@ -101,7 +90,7 @@
 		AST_STRING_FIELD(appmap_item_name);
 		AST_STRING_FIELD(dtmf_override);
 	);
-	struct applicationmap_item *appmap_item;
+	struct ast_applicationmap_item *appmap_item;
 };
 
 static void featuregroup_item_destructor(void *obj)
@@ -814,10 +803,92 @@
 	return featuremap_get(cfg->featuremap, feature, buf, len);
 }
 
+static struct ast_applicationmap_item *applicationmap_item_alloc(const char *name,
+		const char *app, const char *app_data, const char *moh_class, const char *dtmf,
+		unsigned int activate_on_self)
+{
+	struct ast_applicationmap_item *item;
+
+	item = ao2_alloc(sizeof(*item), ast_applicationmap_item_destructor);
+
+	if (!item || ast_string_field_init(item, 64)) {
+		return NULL;
+	}
+
+	ast_string_field_set(item, name, name);
+	ast_string_field_set(item, app, app);
+	ast_string_field_set(item, app_data, app_data);
+	ast_string_field_set(item, moh_class, moh_class);
+	ast_copy_string(item->dtmf, dtmf, sizeof(item->dtmf));
+	item->activate_on_self = activate_on_self;
+
+	return item;
+}
+
+static int add_item(void *obj, void *arg, int flags)
+{
+	struct featuregroup_item *fg_item = obj;
+	struct ao2_container *applicationmap = arg;
+	struct ast_applicationmap_item *appmap_item;
+
+	appmap_item = applicationmap_item_alloc(fg_item->appmap_item_name,
+			fg_item->appmap_item->app, fg_item->appmap_item->app_data,
+			fg_item->appmap_item->moh_class,
+			S_OR(fg_item->dtmf_override, fg_item->appmap_item->dtmf),
+			fg_item->appmap_item->activate_on_self);
+
+	if (!appmap_item) {
+		return 0;
+	}
+
+	ao2_link(applicationmap, appmap_item);
+	return 0;
+}
+
+struct ao2_container *ast_get_chan_applicationmap(struct ast_channel *chan)
+{
+	RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
+	struct ao2_container *applicationmap;
+	char *group_names;
+	char *name;
+
+	if (!chan || !cfg) {
+		return NULL;
+	}
+
+	ast_channel_lock(chan);
+	group_names = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"), ""));
+	ast_channel_unlock(chan);
+	if (ast_strlen_zero(group_names)) {
+		return NULL;
+	}
+
+	applicationmap = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 11,
+			applicationmap_hash, applicationmap_cmp);
+	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) {
+			continue;
+		}
+		ao2_callback(group->items, 0, add_item, applicationmap);
+	}
+
+	if (ao2_container_count(applicationmap) == 0) {
+		ao2_cleanup(applicationmap);
+		return NULL;
+	}
+
+	return applicationmap;
+}
+
 static int applicationmap_handler(const struct aco_option *opt,
 		struct ast_variable *var, void *obj)
 {
-	RAII_VAR(struct applicationmap_item *, item, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_applicationmap_item *, item, NULL, ao2_cleanup);
 	struct ao2_container *applicationmap = obj;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(dtmf);
@@ -872,18 +943,12 @@
 		return -1;
 	}
 
-	item = ao2_alloc(sizeof(*item), applicationmap_item_destructor);
-
-	if (!item || ast_string_field_init(item, 64)) {
+	item = applicationmap_item_alloc(var->name, args.app, args.app_data,
+			args.moh_class, args.dtmf, activate_on_self);
+
+	if (!item) {
 		return -1;
 	}
-
-	ast_string_field_set(item, name, var->name);
-	ast_string_field_set(item, dtmf, args.dtmf);
-	ast_string_field_set(item, app, args.app);
-	ast_string_field_set(item, app_data, args.app_data);
-	ast_string_field_set(item, moh_class, args.moh_class);
-	item->activate_on_self = activate_on_self;
 
 	ao2_link(applicationmap, item);
 
@@ -948,7 +1013,7 @@
 
 static int check_featuregroup_item(void *obj, void *arg, void *data, int flags)
 {
-	RAII_VAR(struct applicationmap_item *, appmap_item, NULL, ao2_cleanup);
+	struct ast_applicationmap_item *appmap_item;
 	struct featuregroup_item *fg_item = obj;
 	int *err = arg;
 	struct ao2_container *applicationmap = data;
@@ -958,6 +1023,8 @@
 		*err = 1;
 		return CMP_STOP;
 	}
+
+	fg_item->appmap_item = appmap_item;
 
 	return 0;
 }




More information about the asterisk-commits mailing list