[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