[asterisk-commits] mmichelson: branch mmichelson/features_config r389538 - /team/mmichelson/feat...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 22 17:58:06 CDT 2013
Author: mmichelson
Date: Wed May 22 17:58:02 2013
New Revision: 389538
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389538
Log:
Add applicationmap handling.
Modified:
team/mmichelson/features_config/main/features_config.c
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=389538&r1=389537&r2=389538
==============================================================================
--- team/mmichelson/features_config/main/features_config.c (original)
+++ team/mmichelson/features_config/main/features_config.c Wed May 22 17:58:02 2013
@@ -23,6 +23,7 @@
#include "asterisk/datastore.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
+#include "asterisk/app.h"
#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 /*!< ms */
#define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000 /*!< ms */
@@ -37,14 +38,68 @@
struct ast_features_pickup_config *pickup;
};
-struct features_applicationmap {
- /* XXX STUB */
+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;
+
+ ast_string_field_free_memory(item);
+}
+
+static int applicationmap_hash(const void *obj, int flags)
+{
+ const struct applicationmap_item *item;
+ const char *key;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_KEY:
+ key = obj;
+ return ast_str_case_hash(key);
+ case OBJ_PARTIAL_KEY:
+ ast_assert(0);
+ return 0;
+ case OBJ_POINTER:
+ default:
+ item = obj;
+ return ast_str_case_hash(item->name);
+ }
+}
+
+static int applicationmap_cmp(void *obj, void *arg, int flags)
+{
+ struct applicationmap_item *item1 = obj;
+ struct applicationmap_item *item2;
+ const char *key2;
+
+ switch(flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_KEY:
+ key2 = arg;
+ return strcasecmp(item1->name, key2) ? 0 : CMP_MATCH;
+ case OBJ_PARTIAL_KEY:
+ key2 = arg;
+ return strncasecmp(item1->name, key2, strlen(key2)) ? 0 : CMP_MATCH;
+ case OBJ_POINTER:
+ item2 = arg;
+ return strcasecmp(item1->name, item2->name) ? 0 : CMP_MATCH;
+ default:
+ return CMP_STOP;
+ }
+}
struct features_config {
struct features_global_config *global;
struct ast_featuremap_config *featuremap;
- struct features_applicationmap *applicationmap;
+ struct ao2_container *applicationmap;
};
static struct aco_type global_option = {
@@ -98,11 +153,6 @@
ast_string_field_free_memory(cfg);
}
-static void applicationmap_config_destructor (void *obj)
-{
- /* XXX STUB */
-}
-
static void global_config_destructor(void *obj)
{
struct features_global_config *cfg = obj;
@@ -154,7 +204,7 @@
return cfg;
}
-static void *features_config_alloc(void)
+static struct features_config *__features_config_alloc(int allocate_applicationmap)
{
RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
@@ -173,14 +223,22 @@
return NULL;
}
- cfg->applicationmap = ao2_alloc(sizeof(*cfg->applicationmap),
- applicationmap_config_destructor);
- if (!cfg->applicationmap) {
- return NULL;
+ if (allocate_applicationmap) {
+ cfg->applicationmap = ao2_container_alloc(11, applicationmap_hash,
+ applicationmap_cmp);
+ if (!cfg->applicationmap) {
+ return NULL;
+ }
}
ao2_ref(cfg, +1);
return cfg;
+
+}
+
+static void *features_config_alloc(void)
+{
+ return __features_config_alloc(1);
}
static void general_copy(struct ast_features_general_config *dest, const struct ast_features_general_config *src)
@@ -215,23 +273,21 @@
ast_string_fields_copy(dest, src);
}
-static void applicationmap_copy(struct features_applicationmap *dest, const struct features_applicationmap *src)
-{
- /* XXX STUB */
-}
-
static void features_copy(struct features_config *dest, const struct features_config *src)
{
global_copy(dest->global, src->global);
featuremap_copy(dest->featuremap, src->featuremap);
- applicationmap_copy(dest->applicationmap, src->applicationmap);
+
+ /* No deep copy is needed because applicationmap cannot change */
+ ao2_ref(src->applicationmap, +1);
+ dest->applicationmap = src->applicationmap;
}
static struct features_config *features_config_dup(const struct features_config *orig)
{
struct features_config *dup;
- dup = features_config_alloc();
+ dup = __features_config_alloc(0);
if (!dup) {
return NULL;
}
@@ -612,7 +668,76 @@
static int applicationmap_handler(const struct aco_option *opt,
struct ast_variable *var, void *obj)
{
- /* XXX STUB */
+ RAII_VAR(struct applicationmap_item *, item, NULL, ao2_cleanup);
+ struct ao2_container *applicationmap = obj;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(dtmf);
+ AST_APP_ARG(activate_on);
+ AST_APP_ARG(app);
+ AST_APP_ARG(app_data);
+ AST_APP_ARG(moh_class);
+ );
+ char *parse = ast_strdupa(var->value);
+ char *slash;
+ char *paren;
+ unsigned int activate_on_self;
+
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ /* features.conf used to have an "activated_by" portion
+ * in addition to activate_on. Get rid of whatever may be
+ * there
+ */
+ slash = strchr(args.activate_on, '/');
+ if (slash) {
+ *slash = '\0';
+ }
+
+ /* Two syntaxes allowed for applicationmap:
+ * Old: foo = *1,self,NoOp,Boo!,default
+ * New: foo = *1,self,NoOp(Boo!),default
+ *
+ * We need to handle both
+ */
+ paren = strchr(args.app, '(');
+ if (paren) {
+ /* New syntax */
+ args.moh_class = args.app_data;
+ args.app_data = ast_strip_quoted(paren, "(", ")");
+ }
+
+ if (ast_strlen_zero(args.dtmf) ||
+ ast_strlen_zero(args.activate_on) ||
+ ast_strlen_zero(args.app)) {
+ ast_log(LOG_WARNING, "Invalid applicationmap syntax for '%s'. Missing required argument\n", var->name);
+ return -1;
+ }
+
+ if (!strcasecmp(args.activate_on, "self")) {
+ activate_on_self = 1;
+ } else if (!strcasecmp(args.activate_on, "peer")) {
+ activate_on_self = 0;
+ } else {
+ ast_log(LOG_WARNING, "Invalid 'activate_on' value %s for applicationmap item %s\n",
+ args.activate_on, var->name);
+ return -1;
+ }
+
+ item = ao2_alloc(sizeof(*item), applicationmap_item_destructor);
+
+ if (!item || ast_string_field_init(item, 64)) {
+ 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);
+
return 0;
}
More information about the asterisk-commits
mailing list