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 )
  Reported by: lmadsen
  Patches:
        issue_17589.rev4.txt uploaded by russell (license 2)
  Tested by: russell, lmadsen
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@275425 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.2
Russell Bryant 15 years ago
parent 40c8586ec3
commit 4fb30be81b

@ -92,6 +92,7 @@ context => parkedcalls ; Which context parked calls are in (default parking lot
;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>[,MOH_Class]] ;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>[,MOH_Class]]
;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,"<AppArguments>"[,MOH_Class]] ;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,"<AppArguments>"[,MOH_Class]]
;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>([<AppArguments>])[,MOH_Class] ;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>([<AppArguments>])[,MOH_Class]
; ;
; FeatureName -> This is the name of the feature used in when setting the ; FeatureName -> This is the name of the feature used in when setting the
; DYNAMIC_FEATURES variable to enable usage of this feature. ; 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 ;unpauseMonitor => #3,self/callee,UnPauseMonitor ;Allow the callee to unpause monitoring
; ;on their channel ; ;on their channel
; GROUPS ; Dynamic Feature Groups:
; Groups are groupings of features defined in [applicationmap] ; Dynamic feature groups are groupings of features defined in [applicationmap]
; that can have their own key mappings. ; 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: ; example:
; [myGroupName] ; defines the group named myGroupName ; [myGroupName] ; defines the group named myGroupName
; testfeature => #9 ; associates testfeature with the group and the keycode #9 ; testfeature => #9 ; associates testfeature with the group and the keycode '#9'.
; pauseMonitor ; associates pauseMonitor with the group and the keycode ; pauseMonitor => ; associates pauseMonitor with the group and uses the keycode specified
; ; in the [applicationmap].

@ -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. * 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. * \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; struct feature_group *fg;
@ -1746,8 +1746,9 @@ static struct feature_group* register_group(const char *fgname)
return NULL; return NULL;
} }
if (!(fg = ast_calloc(1, sizeof(*fg)))) if (!(fg = ast_calloc(1, sizeof(*fg)))) {
return NULL; return NULL;
}
if (ast_string_field_init(fg, 128)) { if (ast_string_field_init(fg, 128)) {
ast_free(fg); ast_free(fg);
@ -1786,8 +1787,9 @@ static void register_group_feature(struct feature_group *fg, const char *exten,
return; return;
} }
if (!(fge = ast_calloc(1, sizeof(*fge)))) if (!(fge = ast_calloc(1, sizeof(*fge)))) {
return; return;
}
if (ast_string_field_init(fge, 128)) { if (ast_string_field_init(fge, 128)) {
ast_free(fge); ast_free(fge);
@ -1801,7 +1803,7 @@ static void register_group_feature(struct feature_group *fg, const char *exten,
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", 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) 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 feature group on success.
* \retval NULL on failure. * \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; struct feature_group *fg = NULL;
AST_LIST_TRAVERSE(&feature_groups, fg, entry) { 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; int x;
struct ast_flags features; struct ast_flags features;
struct ast_call_feature *feature; struct ast_call_feature *feature = NULL;
struct feature_group *fg = NULL; struct feature_group *fg = NULL;
struct feature_group_exten *fge; struct feature_group_exten *fge;
const char *peer_dynamic_features, *chan_dynamic_features; 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) { if (fg) {
AST_LIST_TRAVERSE(&fg->features, fge, entry) { AST_LIST_TRAVERSE(&fg->features, fge, entry) {
if (strcasecmp(fge->exten, code)) if (!strcmp(fge->exten, code)) {
continue; res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
memcpy(feature, fge->feature, sizeof(feature));
res = fge->feature->operation(chan, peer, config, code, sense, fge->feature); if (res != AST_FEATURE_RETURN_KEEPTRYING) {
if (res != AST_FEATURE_RETURN_KEEPTRYING) { AST_RWLIST_UNLOCK(&feature_groups);
AST_RWLIST_UNLOCK(&feature_groups); break;
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; break;
}
} }
AST_RWLIST_UNLOCK(&feature_groups); 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 we have a feature */
while ((tok = strsep(&tmp, "#"))) { 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); AST_RWLIST_RDLOCK(&feature_list);
if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) { 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); 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_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
}
} }
AST_RWLIST_UNLOCK(&feature_list); 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_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); iter = ao2_iterator_init(parkinglots, 0);
while ((curlot = ao2_iterator_next(&iter))) { while ((curlot = ao2_iterator_next(&iter))) {
ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name); ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name);

Loading…
Cancel
Save