add one remaining bit of functionality to the features.conf applicationmap (from...
authorKevin P. Fleming <kpfleming@digium.com>
Tue, 29 Aug 2006 21:20:43 +0000 (21:20 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Tue, 29 Aug 2006 21:20:43 +0000 (21:20 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@41281 65c4cc65-6c06-0410-ace0-fbb531ad65f3

configs/features.conf.sample
include/asterisk/features.h
res/res_features.c

index 7867223..7e25782 100644 (file)
@@ -48,7 +48,7 @@ context => parkedcalls                ; Which context parked calls are in
 ;
 ; The syntax for declaring a dynaic feature is the following:
 ;
-;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>]
+;<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.
@@ -64,6 +64,9 @@ context => parkedcalls                ; Which context parked calls are in
 ;                   the "callee" is the channel called by the Dial application.
 ;  Application   -> This is the application to execute.
 ;  AppArguments  -> These are the arguments to be passed into the application.
+;  MOH_Class     -> This is the music on hold class to play while the idle
+;                   channel waits for the feature to complete. If left blank,
+;                   no music will be played.
 ;
 ;
 ; IMPORTANT NOTE: The applicationmap is not intended to be used for all Asterisk
index 2fb9e7a..db25e7d 100644 (file)
@@ -29,6 +29,7 @@
 #define FEATURE_APP_ARGS_LEN   256
 #define FEATURE_SNAME_LEN      32
 #define FEATURE_EXTEN_LEN      32
+#define FEATURE_MOH_LEN                80  /* same as MAX_MUSICCLASS from channel.h */
 
 /*! \brief main call feature structure */
 struct ast_call_feature {
@@ -41,6 +42,7 @@ struct ast_call_feature {
        unsigned int flags;
        char app[FEATURE_APP_LEN];              
        char app_args[FEATURE_APP_ARGS_LEN];
+       char moh_class[FEATURE_MOH_LEN];
        AST_LIST_ENTRY(ast_call_feature) feature_entry;
 };
 
index 0a7883c..10faf00 100644 (file)
@@ -871,11 +871,11 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
 
 struct ast_call_feature builtin_features[] = 
  {
-       { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF },
-       { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF },
-       { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF },
-       { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF },
-       { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF },
+       { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
+       { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
+       { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
+       { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
+       { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
 };
 
 
@@ -940,7 +940,7 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
 {
        struct ast_app *app;
        struct ast_call_feature *feature;
-       struct ast_channel *work;
+       struct ast_channel *work, *idle;
        int res;
 
        AST_LIST_LOCK(&feature_list);
@@ -958,11 +958,23 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
        if (sense == FEATURE_SENSE_CHAN) {
                if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
                        return FEATURE_RETURN_PASSDIGITS;
-               work = ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) ? chan : peer;
+               if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
+                       work = chan;
+                       idle = peer;
+               } else {
+                       work = peer;
+                       idle = chan;
+               }
        } else {
                if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
                        return FEATURE_RETURN_PASSDIGITS;
-               work = ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) ? peer : chan;
+               if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
+                       work = peer;
+                       idle = chan;
+               } else {
+                       work = chan;
+                       idle = peer;
+               }
        }
 
        if (!(app = pbx_findapp(feature->app))) {
@@ -970,9 +982,18 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
                return -2;
        }
 
-       /* XXX Should we service the other channel while this runs? */
+       ast_autoservice_start(idle);
+       
+       if (!ast_strlen_zero(feature->moh_class))
+               ast_moh_start(idle, feature->moh_class, NULL);
+
        res = pbx_exec(work, app, feature->app_args);
 
+       if (!ast_strlen_zero(feature->moh_class))
+               ast_moh_stop(idle);
+
+       ast_autoservice_stop(idle);
+
        if (res == AST_PBX_KEEPALIVE)
                return FEATURE_RETURN_PBX_KEEPALIVE;
        else if (res == AST_PBX_NO_HANGUP_PEER)
@@ -2164,7 +2185,7 @@ static int load_config(void)
                ast_unregister_features();
                for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
                        char *tmp_val = ast_strdupa(var->value);
-                       char *exten, *activateon, *activatedby, *app, *app_args; 
+                       char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
                        struct ast_call_feature *feature;
 
                        /* strsep() sets the argument to NULL if match not found, and it
@@ -2175,6 +2196,7 @@ static int load_config(void)
                        activatedby = strsep(&tmp_val,",");
                        app = strsep(&tmp_val,",");
                        app_args = strsep(&tmp_val,",");
+                       moh_class = strsep(&tmp_val,",");
 
                        activateon = strsep(&activatedby, "/"); 
 
@@ -2199,6 +2221,9 @@ static int load_config(void)
                        
                        if (app_args) 
                                ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
+
+                       if (moh_class)
+                               ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
                                
                        ast_copy_string(feature->exten, exten, sizeof(feature->exten));
                        feature->operation = feature_exec_app;