]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 275424 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Fri, 9 Jul 2010 22:01:01 +0000 (22:01 +0000)
committerRussell Bryant <russell@russellbryant.com>
Fri, 9 Jul 2010 22:01:01 +0000 (22:01 +0000)
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: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@275425 65c4cc65-6c06-0410-ace0-fbb531ad65f3

configs/features.conf.sample
main/features.c

index 9d6fa43d6465ba82ac33f815f0b8550210cbf191..f70185035805bde174d4abea3d327ac0f6628086 100644 (file)
@@ -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   -> 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].
index 72111193b04a63b03afc3fa583bdf69a126b5f5f..a054b9e904ff230c99e2444bb17aadae9d19fbb2 100644 (file)
@@ -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_groupregister_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);