diff options
author | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-05 23:45:32 +0000 |
---|---|---|
committer | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-05 23:45:32 +0000 |
commit | e44c06e6c5fd14be3f78dbcceb45eb61cc5379e1 (patch) | |
tree | 5cc17919fb6c8c46a38008cb1b2beafc9b98ccfe | |
parent | 008db88c6569e1c8049ac0d53edc06e4089bcd47 (diff) |
Merged revisions 135799 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@135821 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | apps/app_dial.c | 4 | ||||
-rw-r--r-- | include/asterisk/cdr.h | 4 | ||||
-rw-r--r-- | main/cdr.c | 5 | ||||
-rw-r--r-- | main/channel.c | 7 | ||||
-rw-r--r-- | main/features.c | 45 |
5 files changed, 52 insertions, 13 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index 07cbf51ee..a03dfc0ab 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -672,6 +672,10 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, if (!peer) { ast_verb(3, "%s answered %s\n", c->name, in->name); peer = c; + if (peer->cdr) { + peer->cdr->answer = ast_tvnow(); + peer->cdr->disposition = AST_CDR_ANSWERED; + } ast_copy_flags64(peerflags, o, OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP | diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h index dc14f326e..7ece62379 100644 --- a/include/asterisk/cdr.h +++ b/include/asterisk/cdr.h @@ -37,7 +37,8 @@ #define AST_CDR_FLAG_ENABLE (1 << 7) #define AST_CDR_FLAG_ANSLOCKED (1 << 8) #define AST_CDR_FLAG_DONT_TOUCH (1 << 9) -#define AST_CDR_FLAG_POST_ENABLE (1 << 5) +#define AST_CDR_FLAG_POST_ENABLE (1 << 10) +#define AST_CDR_FLAG_DIALED (1 << 11) /*@} */ /*! \name CDR Flags - Disposition */ @@ -111,6 +112,7 @@ struct ast_cdr { struct ast_cdr *next; }; +int ast_cdr_isset_unanswered(void); void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw); int ast_cdr_setvar(struct ast_cdr *cdr, const char *name, const char *value, int recur); int ast_cdr_serialize_variables(struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur); diff --git a/main/cdr.c b/main/cdr.c index f8fc2c634..9402ae674 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -157,6 +157,11 @@ void ast_cdr_unregister(const char *name) AST_RWLIST_UNLOCK(&be_list); } +int ast_cdr_isset_unanswered(void) +{ + return unanswered; +} + /*! Duplicate a CDR record \returns Pointer to new CDR record */ diff --git a/main/channel.c b/main/channel.c index 98a89f0dc..33bcc0552 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1633,7 +1633,10 @@ int ast_hangup(struct ast_channel *chan) ast_cause2str(chan->hangupcause) ); - if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && chan->cdr->disposition != AST_CDR_NULL) { + if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && + !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && + (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { + ast_cdr_end(chan->cdr); ast_cdr_detach(chan->cdr); } @@ -3439,6 +3442,8 @@ int ast_call(struct ast_channel *chan, char *addr, int timeout) /* Stop if we're a zombie or need a soft hangup */ ast_channel_lock(chan); if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { + if (chan->cdr) + ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); if (chan->tech->call) res = chan->tech->call(chan, addr, timeout); ast_set_flag(chan, AST_FLAG_OUTGOING); diff --git a/main/features.c b/main/features.c index f540c455b..69bfbe59e 100644 --- a/main/features.c +++ b/main/features.c @@ -2140,11 +2140,23 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_cdr_start(bridge_cdr); } } - ast_cdr_answer(bridge_cdr); - ast_cdr_answer(chan->cdr); /* for the sake of cli status checks */ - ast_set_flag(chan->cdr, AST_CDR_FLAG_BRIDGED); + ast_log(LOG_NOTICE,"bridge answer set, chan answer set\n"); + /* peer->cdr->answer will be set when a macro runs on the peer; + in that case, the bridge answer will be delayed while the + macro plays on the peer channel. The peer answered the call + before the macro started playing. To the phone system, + this is billable time for the call, even tho the caller + hears nothing but ringing while the macro does its thing. */ + if (peer->cdr && !ast_tvzero(peer->cdr->answer)) { + bridge_cdr->answer = peer->cdr->answer; + chan->cdr->answer = peer->cdr->answer; + } else { + ast_cdr_answer(bridge_cdr); + ast_cdr_answer(chan->cdr); /* for the sake of cli status checks */ + } + ast_set_flag(chan->cdr, AST_CDR_FLAG_BRIDGED); if (peer->cdr) { - ast_set_flag(peer->cdr, AST_CDR_FLAG_BRIDGED); + ast_set_flag(peer->cdr, AST_CDR_FLAG_BRIDGED); } } for (;;) { @@ -2212,7 +2224,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast if (res < 0) { if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer)) ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name); - return -1; + goto before_you_go; } if (!f || (f->frametype == AST_FRAME_CONTROL && @@ -2308,6 +2320,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_frfree(f); } + before_you_go: /* obey the NoCDR() wishes. */ if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) { @@ -2320,14 +2333,24 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_cdr_specialized_reset(chan->cdr,0); } if (peer->cdr) { - if (orig_peer_cdr && peer->cdr != orig_peer_cdr) { - /* this can only happen if there was a transfer, methinks */ - ast_cdr_specialized_reset(orig_peer_cdr,0); - } else { - ast_cdr_specialized_reset(peer->cdr,0); + /* before resetting the peer cdr, throw a copy of it to the + backend, just in case the cdr.conf file is calling for + unanswered CDR's. */ + + /* When peer->cdr isn't the same addr as orig_peer_cdr, + this can only happen if there was a transfer, methinks; + at any rate, only pay attention to the original*/ + if (ast_cdr_isset_unanswered()) { + struct ast_cdr *dupd = ast_cdr_dup(orig_peer_cdr); + if (dupd) { + if (ast_tvzero(dupd->end) && ast_cdr_isset_unanswered()) + ast_cdr_end(dupd); + ast_cdr_detach(dupd); + } } + ast_cdr_specialized_reset(orig_peer_cdr,0); } - } + } return res; } |