diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-04-05 21:30:24 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-04-05 21:30:24 +0000 |
commit | 0aecb9fb67c965fb45d89612da922c13f25505f0 (patch) | |
tree | 6f45734ae9bed023989543c4d80b839a3170f7f5 /channels/chan_agent.c | |
parent | 3b18a3930dcb03e1beb8570bfcfc2cc770cb7391 (diff) |
optimize frame handling in agent_read()
ensure that the call is marked acknowledged when it goes to AST_STATE_UP even if AST_CONTROL_ANSWER is not received (if ackcall is disabled)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5413 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_agent.c')
-rwxr-xr-x | channels/chan_agent.c | 79 |
1 files changed, 43 insertions, 36 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 9043eaf8c..1ef0ec7c4 100755 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -379,7 +379,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast) } else f = &null_frame; if (!f) { - /* If there's a channel, hang it up (if it's on a callback) make it NULL */ + /* If there's a channel, hang it up (if it's on a callback) make it NULL */ if (p->chan) { p->chan->_bridge = NULL; /* Note that we don't hangup if it's not a callback because Asterisk will do it @@ -401,41 +401,48 @@ static struct ast_frame *agent_read(struct ast_channel *ast) p->chan = NULL; p->acknowledged = 0; } - } - if (p->chan && f && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { -/* TC */ - ast_log(LOG_DEBUG, "Got answer on %s\n", p->chan->name); - if (p->ackcall) { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name); - /* Don't pass answer along */ - ast_frfree(f); - f = &null_frame; - } else { - p->acknowledged = 1; - ast_frfree(f); - f = &answer_frame; - } - } - if (f && (f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { - if (!p->acknowledged) { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "%s acknowledged\n", p->chan->name); - p->acknowledged = 1; - ast_frfree(f); - f = &answer_frame; - } - } - if (f && (f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) { - /* * terminates call */ - ast_frfree(f); - f = NULL; - } - if (f && (f->frametype == AST_FRAME_VOICE) && !p->acknowledged) { - /* Don't pass along agent audio until call is acknowledged */ - ast_frfree(f); - f = &null_frame; - } + } else { + /* if acknowledgement is not required, and the channel is up, we may have missed + an AST_CONTROL_ANSWER (if there was one), so mark the call acknowledged anyway */ + if (!p->ackcall && !p->acknowledged && p->chan->_state == AST_STATE_UP) + p->acknowledged = 1; + switch (f->frametype) { + case AST_FRAME_CONTROL: + if (f->subclass == AST_CONTROL_ANSWER) { + if (p->ackcall) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name); + /* Don't pass answer along */ + ast_frfree(f); + f = &null_frame; + } else { + p->acknowledged = 1; + } + } + break; + case AST_FRAME_DTMF: + if (!p->acknowledged && (f->subclass == '#')) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "%s acknowledged\n", p->chan->name); + p->acknowledged = 1; + ast_frfree(f); + f = &answer_frame; + } else if (f->subclass == '*') { + /* terminates call */ + ast_frfree(f); + f = NULL; + } + break; + case AST_FRAME_VOICE: + /* don't pass voice until the call is acknowledged */ + if (!p->acknowledged) { + ast_frfree(f); + f = &null_frame; + } + break; + } + } + CLEANUP(ast,p); if (p->chan && !p->chan->_bridge) { if (strcasecmp(p->chan->type, "Local")) { |