The ackcall and endcall options in agents.conf now have supplemental options
authorMark Michelson <mmichelson@digium.com>
Wed, 2 Jul 2008 20:43:55 +0000 (20:43 +0000)
committerMark Michelson <mmichelson@digium.com>
Wed, 2 Jul 2008 20:43:55 +0000 (20:43 +0000)
acceptdtmf and enddtmf. These allow for the DTMF pressed to be configurable
instead of being hardcoded to '#' and '*'.

(AST-86)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@127558 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
channels/chan_agent.c
configs/agents.conf.sample

diff --git a/CHANGES b/CHANGES
index 875aae5..a672441 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -379,6 +379,13 @@ Local channel changes
      that is behind it when queried. This is useful for transfer scenarios as the
      actual channel will be transferred, not the Local channel.
 
      that is behind it when queried. This is useful for transfer scenarios as the
      actual channel will be transferred, not the Local channel.
 
+Agent channel changes
+----------------------
+  * The ackcall and endcall options are now supplemented with options acceptdtmf
+    and enddtmf. These allow for the DTMF keypress to be configurable. The options
+       default to their old hard-coded values ('#' and '*' respectively) so this should
+       not break any existing agent installations.
+
 Zaptel channel driver (chan_zap) Changes
 ----------------------------------------
   * SS7 support in chan_zap (via libss7 library)
 Zaptel channel driver (chan_zap) Changes
 ----------------------------------------
   * SS7 support in chan_zap (via libss7 library)
index f96fac5..7ad929c 100644 (file)
@@ -124,6 +124,9 @@ static const char pa_family[] = "Agents";          /*!< Persistent Agents astdb
 static int persistent_agents = 0;                   /*!< queues.conf [general] option */
 static void dump_agents(void);
 
 static int persistent_agents = 0;                   /*!< queues.conf [general] option */
 static void dump_agents(void);
 
+#define DEFAULT_ACCEPTDTMF '#'
+#define DEFAULT_ENDDTMF '*'
+
 static ast_group_t group;
 static int autologoff;
 static int wrapuptime;
 static ast_group_t group;
 static int autologoff;
 static int wrapuptime;
@@ -131,6 +134,8 @@ static int ackcall;
 static int endcall;
 static int multiplelogin = 1;
 static int autologoffunavail = 0;
 static int endcall;
 static int multiplelogin = 1;
 static int autologoffunavail = 0;
+static char acceptdtmf = DEFAULT_ACCEPTDTMF;
+static char enddtmf = DEFAULT_ENDDTMF;
 
 static int maxlogintries = 3;
 static char agentgoodbye[AST_MAX_FILENAME_LEN] = "vm-goodbye";
 
 static int maxlogintries = 3;
 static char agentgoodbye[AST_MAX_FILENAME_LEN] = "vm-goodbye";
@@ -154,6 +159,8 @@ struct agent_pvt {
        int autologoff;                /*!< Auto timeout time */
        int ackcall;                   /*!< ackcall */
        int deferlogoff;               /*!< Defer logoff to hangup */
        int autologoff;                /*!< Auto timeout time */
        int ackcall;                   /*!< ackcall */
        int deferlogoff;               /*!< Defer logoff to hangup */
+       char acceptdtmf;
+       char enddtmf;
        time_t loginstart;             /*!< When agent first logged in (0 when logged off) */
        time_t start;                  /*!< When call started */
        struct timeval lastdisc;       /*!< When last disconnected */
        time_t loginstart;             /*!< When agent first logged in (0 when logged off) */
        time_t start;                  /*!< When call started */
        struct timeval lastdisc;       /*!< When last disconnected */
@@ -324,6 +331,8 @@ static struct agent_pvt *add_agent(const char *agent, int pending)
        ast_copy_string(p->moh, moh, sizeof(p->moh));
        p->ackcall = ackcall;
        p->autologoff = autologoff;
        ast_copy_string(p->moh, moh, sizeof(p->moh));
        p->ackcall = ackcall;
        p->autologoff = autologoff;
+       p->acceptdtmf = acceptdtmf;
+       p->enddtmf = enddtmf;
 
        /* If someone reduces the wrapuptime and reloads, we want it
         * to change the wrapuptime immediately on all calls */
 
        /* If someone reduces the wrapuptime and reloads, we want it
         * to change the wrapuptime immediately on all calls */
@@ -468,7 +477,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
                case AST_FRAME_CONTROL:
                        if (f->subclass == AST_CONTROL_ANSWER) {
                                if (p->ackcall) {
                case AST_FRAME_CONTROL:
                        if (f->subclass == AST_CONTROL_ANSWER) {
                                if (p->ackcall) {
-                                       ast_verb(3, "%s answered, waiting for '#' to acknowledge\n", p->chan->name);
+                                       ast_verb(3, "%s answered, waiting for '%c' to acknowledge\n", p->chan->name, p->acceptdtmf);
                                        /* Don't pass answer along */
                                        ast_frfree(f);
                                        f = &ast_null_frame;
                                        /* Don't pass answer along */
                                        ast_frfree(f);
                                        f = &ast_null_frame;
@@ -483,18 +492,18 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
                        break;
                case AST_FRAME_DTMF_BEGIN:
                        /*ignore DTMF begin's as it can cause issues with queue announce files*/
                        break;
                case AST_FRAME_DTMF_BEGIN:
                        /*ignore DTMF begin's as it can cause issues with queue announce files*/
-                       if((!p->acknowledged && f->subclass == '#') || (f->subclass == '*' && endcall)){
+                       if((!p->acknowledged && f->subclass == p->acceptdtmf) || (f->subclass == p->enddtmf && endcall)){
                                ast_frfree(f);
                                f = &ast_null_frame;
                        }
                        break;
                case AST_FRAME_DTMF_END:
                                ast_frfree(f);
                                f = &ast_null_frame;
                        }
                        break;
                case AST_FRAME_DTMF_END:
-                       if (!p->acknowledged && (f->subclass == '#')) {
+                       if (!p->acknowledged && (f->subclass == p->acceptdtmf)) {
                                ast_verb(3, "%s acknowledged\n", p->chan->name);
                                p->acknowledged = 1;
                                ast_frfree(f);
                                f = &answer_frame;
                                ast_verb(3, "%s acknowledged\n", p->chan->name);
                                p->acknowledged = 1;
                                ast_frfree(f);
                                f = &answer_frame;
-                       } else if (f->subclass == '*' && endcall) {
+                       } else if (f->subclass == p->enddtmf && endcall) {
                                /* terminates call */
                                ast_frfree(f);
                                f = NULL;
                                /* terminates call */
                                ast_frfree(f);
                                f = NULL;
@@ -907,7 +916,7 @@ static int agent_ack_sleep(void *data)
                if (!p->app_sleep_cond) {
                        ast_mutex_unlock(&p->lock);
                        return 0;
                if (!p->app_sleep_cond) {
                        ast_mutex_unlock(&p->lock);
                        return 0;
-               } else if (res == '#') {
+               } else if (res == p->acceptdtmf) {
                        ast_mutex_unlock(&p->lock);
                        return 1;
                }
                        ast_mutex_unlock(&p->lock);
                        return 1;
                }
@@ -1091,6 +1100,11 @@ static int read_agent_config(int reload)
                                ackcall = 0;
                } else if (!strcasecmp(v->name, "endcall")) {
                        endcall = ast_true(v->value);
                                ackcall = 0;
                } else if (!strcasecmp(v->name, "endcall")) {
                        endcall = ast_true(v->value);
+               } else if (!strcasecmp(v->name, "acceptdtmf")) {
+                       acceptdtmf = *(v->value);
+                       ast_log(LOG_NOTICE, "Set acceptdtmf to %c\n", acceptdtmf);
+               } else if (!strcasecmp(v->name, "enddtmf")) {
+                       enddtmf = *(v->value);
                } else if (!strcasecmp(v->name, "wrapuptime")) {
                        wrapuptime = atoi(v->value);
                        if (wrapuptime < 0)
                } else if (!strcasecmp(v->name, "wrapuptime")) {
                        wrapuptime = atoi(v->value);
                        if (wrapuptime < 0)
@@ -1924,21 +1938,31 @@ static int login_exec(struct ast_channel *chan, void *data)
                                        else
                                                p->ackcall = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
                                        else
                                                p->ackcall = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
-                                       ast_verb(3, "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n",tmpoptions,p->ackcall,p->agent);
+                                       ast_verb(3, "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n", tmpoptions, p->ackcall, p->agent);
                                }
                                if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"))) {
                                        p->autologoff = atoi(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"));
                                        if (p->autologoff < 0)
                                                p->autologoff = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF");
                                }
                                if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"))) {
                                        p->autologoff = atoi(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"));
                                        if (p->autologoff < 0)
                                                p->autologoff = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF");
-                                       ast_verb(3, "Saw variable AGENTAUTOLOGOFF=%s, setting autologff to: %d for Agent '%s'.\n",tmpoptions,p->autologoff,p->agent);
+                                       ast_verb(3, "Saw variable AGENTAUTOLOGOFF=%s, setting autologff to: %d for Agent '%s'.\n", tmpoptions, p->autologoff, p->agent);
                                }
                                if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"))) {
                                        p->wrapuptime = atoi(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"));
                                        if (p->wrapuptime < 0)
                                                p->wrapuptime = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME");
                                }
                                if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"))) {
                                        p->wrapuptime = atoi(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"));
                                        if (p->wrapuptime < 0)
                                                p->wrapuptime = 0;
                                        tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME");
-                                       ast_verb(3, "Saw variable AGENTWRAPUPTIME=%s, setting wrapuptime to: %d for Agent '%s'.\n",tmpoptions,p->wrapuptime,p->agent);
+                                       ast_verb(3, "Saw variable AGENTWRAPUPTIME=%s, setting wrapuptime to: %d for Agent '%s'.\n", tmpoptions, p->wrapuptime, p->agent);
+                               }
+                               tmpoptions = pbx_builtin_getvar_helper(chan, "AGENTACCEPTDMTF");
+                               if (!ast_strlen_zero(tmpoptions)) {
+                                       p->acceptdtmf = *tmpoptions;
+                                       ast_verb(3, "Saw variable AGENTACCEPTDTMF=%s, setting acceptdtmf to: %c for Agent '%s'.\n", tmpoptions, p->acceptdtmf, p->agent);
+                               }
+                               tmpoptions = pbx_builtin_getvar_helper(chan, "AGENTENDDTMF");
+                               if (!ast_strlen_zero(tmpoptions)) {
+                                       p->enddtmf = *tmpoptions;
+                                       ast_verb(3, "Saw variable AGENTENDDTMF=%s, setting enddtmf to: %c for Agent '%s'.\n", tmpoptions, p->enddtmf, p->agent);
                                }
                                /* End Channel Specific Agent Overrides */
                                if (!p->chan) {
                                }
                                /* End Channel Specific Agent Overrides */
                                if (!p->chan) {
index e07a420..bab4d1b 100644 (file)
@@ -36,17 +36,23 @@ persistentagents=yes
 ;
 ;autologoffunavail=yes
 ;
 ;
 ;autologoffunavail=yes
 ;
-; Define ackcall to require an acknowledgement by '#' when
+; Define ackcall to require a DTMF acknowledgement when
 ; an agent logs in using agentcallbacklogin.  Default is "no".
 ; Can also be set to "always", which will also require AgentLogin
 ; an agent logs in using agentcallbacklogin.  Default is "no".
 ; Can also be set to "always", which will also require AgentLogin
-; agents to acknowledge calls by pressing '#'.
+; agents to acknowledge calls. Use the acceptdtmf option to 
+; configure what DTMF key press should be used to acknowledge the
+; call. The default is '#'.
 ;
 ;ackcall=no
 ;
 ;ackcall=no
+;acceptdtmf=#
 ;
 ;
-; Define endcall to allow an agent to hangup a call by '*'.
-; Default is "yes". Set this to "no" to ignore '*'. 
+; Define endcall to allow an agent to hangup a call with a
+; DTMF keypress. Default is "yes". Use the enddtmf option to
+; configure which DTMF key will end a call. The default is
+; '*'.
 ;
 ;endcall=yes
 ;
 ;endcall=yes
+;enddtmf=*
 ;
 ; Define wrapuptime.  This is the minimum amount of time when
 ; after disconnecting before the caller can receive a new call
 ;
 ; Define wrapuptime.  This is the minimum amount of time when
 ; after disconnecting before the caller can receive a new call