From 8e1fa41e24b87d7a48d057ef92287aab44058399 Mon Sep 17 00:00:00 2001 From: russell Date: Fri, 9 Jul 2010 22:01:01 +0000 Subject: Merged revisions 275424 via svnmerge from https://origsvn.digium.com/svn/asterisk/trunk ........ r275424 | russell | 2010-07-09 16:57:21 -0500 (Fri, 09 Jul 2010) | 27 lines Fix some issues related to dynamic feature groups in features.conf. The bridge handling code did not properly consider feature groups when setting parameters that would affect whether or not a native bridge would be attempted. If DYNAMIC_FEATURES only include a feature group, a native bridge would occur that may prevent features from working. Fix a bug in verbose output that would show the key mapping as empty if it was using the default mapping and not a custom mapping in the feature group. Add feature groups to the output of "features show". Adjust the feature execution logic to match that of the logic when executing a feature that was not configured through a feature group. Update features.conf.sample to show that an '=' is still required if using the default key mapping from [applicationmap]. Finally, clean up a little bit of formatting to better coform to coding guidelines while in the area. (closes issue #17589) Reported by: lmadsen Patches: issue_17589.rev4.txt uploaded by russell (license 2) Tested by: russell, lmadsen ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@275425 f38db490-d61c-443f-a65b-d21fe96a405b --- configs/features.conf.sample | 13 ++++--- main/features.c | 81 +++++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/configs/features.conf.sample b/configs/features.conf.sample index 9d6fa43d6..f70185035 100644 --- a/configs/features.conf.sample +++ b/configs/features.conf.sample @@ -92,6 +92,7 @@ context => parkedcalls ; Which context parked calls are in (default parking lot ; => ,[/],[,[,MOH_Class]] ; => ,[/],[,""[,MOH_Class]] ; => ,[/],([])[,MOH_Class] + ; ; FeatureName -> This is the name of the feature used in when setting the ; DYNAMIC_FEATURES variable to enable usage of this feature. @@ -139,11 +140,13 @@ context => parkedcalls ; Which context parked calls are in (default parking lot ;unpauseMonitor => #3,self/callee,UnPauseMonitor ;Allow the callee to unpause monitoring ; ;on their channel -; GROUPS -; Groups are groupings of features defined in [applicationmap] -; that can have their own key mappings. +; Dynamic Feature Groups: +; Dynamic feature groups are groupings of features defined in [applicationmap] +; that can have their own custom key mappings. To give a channel access to a dynamic +; feature group, add the group name to the value of the DYNAMIC_FEATURES variable. ; ; example: ; [myGroupName] ; defines the group named myGroupName -; testfeature => #9 ; associates testfeature with the group and the keycode #9 -; pauseMonitor ; associates pauseMonitor with the group and the keycode +; testfeature => #9 ; associates testfeature with the group and the keycode '#9'. +; pauseMonitor => ; associates pauseMonitor with the group and uses the keycode specified +; ; in the [applicationmap]. diff --git a/main/features.c b/main/features.c index 72111193b..a054b9e90 100644 --- a/main/features.c +++ b/main/features.c @@ -1737,7 +1737,7 @@ void ast_register_feature(struct ast_call_feature *feature) * Add new feature group to the feature group list insert at head of list. * \note This function MUST be called while feature_groups is locked. */ -static struct feature_group* register_group(const char *fgname) +static struct feature_group *register_group(const char *fgname) { struct feature_group *fg; @@ -1746,8 +1746,9 @@ static struct feature_group* register_group(const char *fgname) return NULL; } - if (!(fg = ast_calloc(1, sizeof(*fg)))) + if (!(fg = ast_calloc(1, sizeof(*fg)))) { return NULL; + } if (ast_string_field_init(fg, 128)) { ast_free(fg); @@ -1772,7 +1773,7 @@ static struct feature_group* register_group(const char *fgname) * Check fg and feature specified, add feature to list * \note This function MUST be called while feature_groups is locked. */ -static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature) +static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature) { struct feature_group_exten *fge; @@ -1786,8 +1787,9 @@ static void register_group_feature(struct feature_group *fg, const char *exten, return; } - if (!(fge = ast_calloc(1, sizeof(*fge)))) + if (!(fge = ast_calloc(1, sizeof(*fge)))) { return; + } if (ast_string_field_init(fge, 128)) { ast_free(fge); @@ -1798,10 +1800,10 @@ static void register_group_feature(struct feature_group *fg, const char *exten, fge->feature = feature; - AST_LIST_INSERT_HEAD(&fg->features, fge, entry); + AST_LIST_INSERT_HEAD(&fg->features, fge, entry); ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n", - feature->sname, fg->gname, exten); + feature->sname, fg->gname, fge->exten); } void ast_unregister_feature(struct ast_call_feature *feature) @@ -1868,7 +1870,8 @@ static void ast_unregister_groups(void) * \retval feature group on success. * \retval NULL on failure. */ -static struct feature_group *find_group(const char *name) { +static struct feature_group *find_group(const char *name) +{ struct feature_group *fg = NULL; AST_LIST_TRAVERSE(&feature_groups, fg, entry) { @@ -2005,7 +2008,7 @@ static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, { int x; struct ast_flags features; - struct ast_call_feature *feature; + struct ast_call_feature *feature = NULL; struct feature_group *fg = NULL; struct feature_group_exten *fge; const char *peer_dynamic_features, *chan_dynamic_features; @@ -2063,18 +2066,21 @@ static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, if (fg) { AST_LIST_TRAVERSE(&fg->features, fge, entry) { - if (strcasecmp(fge->exten, code)) - continue; - - res = fge->feature->operation(chan, peer, config, code, sense, fge->feature); - if (res != AST_FEATURE_RETURN_KEEPTRYING) { - AST_RWLIST_UNLOCK(&feature_groups); - break; + if (!strcmp(fge->exten, code)) { + res = fge->feature->operation(chan, peer, config, code, sense, fge->feature); + memcpy(feature, fge->feature, sizeof(feature)); + if (res != AST_FEATURE_RETURN_KEEPTRYING) { + AST_RWLIST_UNLOCK(&feature_groups); + break; + } + res = AST_FEATURE_RETURN_PASSDIGITS; + } else if (!strncmp(fge->exten, code, strlen(code))) { + res = AST_FEATURE_RETURN_STOREDIGITS; } - res = AST_FEATURE_RETURN_PASSDIGITS; } - if (fge) + if (fge) { break; + } } AST_RWLIST_UNLOCK(&feature_groups); @@ -2133,12 +2139,31 @@ static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, /* while we have a feature */ while ((tok = strsep(&tmp, "#"))) { + struct feature_group *fg; + + AST_RWLIST_RDLOCK(&feature_groups); + AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) { + 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_RWLIST_RDLOCK(&feature_list); if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) { - if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) + 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)) + } + if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) { ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1); + } } AST_RWLIST_UNLOCK(&feature_list); } @@ -4085,6 +4110,24 @@ static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cl AST_RWLIST_UNLOCK(&feature_list); } + ast_cli(a->fd, "\nFeature Groups:\n"); + ast_cli(a->fd, "---------------\n"); + if (AST_RWLIST_EMPTY(&feature_groups)) { + ast_cli(a->fd, "(none)\n"); + } else { + struct feature_group *fg; + struct feature_group_exten *fge; + + AST_RWLIST_RDLOCK(&feature_groups); + 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); + } + iter = ao2_iterator_init(parkinglots, 0); while ((curlot = ao2_iterator_next(&iter))) { ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name); -- cgit v1.2.3