aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-09 22:01:01 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-09 22:01:01 +0000
commit8e1fa41e24b87d7a48d057ef92287aab44058399 (patch)
tree9e65bb813e51de8f2b4563e6394f0f46c6791dde /main
parent776d1c1c6f6f96ab194275c331d5695035ce5e73 (diff)
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
Diffstat (limited to 'main')
-rw-r--r--main/features.c81
1 files changed, 62 insertions, 19 deletions
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);