aboutsummaryrefslogtreecommitdiffstats
path: root/main/features.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-09 21:57:21 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-09 21:57:21 +0000
commit0e4fb319344275e50dd2e29ded05e8d5e0e20897 (patch)
tree36b50fe00ce72e314ce5e5ef44a3a1d3f9948b5b /main/features.c
parente8220c1f878156712741bd6427aad7b92c759dd5 (diff)
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/trunk@275424 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/features.c')
-rw-r--r--main/features.c83
1 files changed, 63 insertions, 20 deletions
diff --git a/main/features.c b/main/features.c
index 1f1da2967..798e86111 100644
--- a/main/features.c
+++ b/main/features.c
@@ -2165,7 +2165,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;
@@ -2174,8 +2174,9 @@ static struct feature_group* register_group(const char *fgname)
return NULL;
}
- if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128)))
+ if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128))) {
return NULL;
+ }
ast_string_field_set(fg, gname, fgname);
@@ -2195,7 +2196,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;
@@ -2209,17 +2210,18 @@ static void register_group_feature(struct feature_group *fg, const char *exten,
return;
}
- if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128)))
+ if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128))) {
return;
+ }
ast_string_field_set(fge, exten, S_OR(exten, feature->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)
@@ -2286,7 +2288,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) {
@@ -2478,20 +2481,23 @@ static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel
if (fg) {
AST_LIST_TRAVERSE(&fg->features, fge, entry) {
- if (strcasecmp(fge->exten, code))
- continue;
- if (operation) {
- 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;
+ if (!strcmp(fge->exten, code)) {
+ if (operation) {
+ 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);
@@ -2595,12 +2601,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);
}
@@ -4651,6 +4676,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);