dect
/
asterisk
Archived
13
0
Fork 0

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
This commit is contained in:
murf 2008-08-05 23:45:32 +00:00
parent 008db88c65
commit e44c06e6c5
5 changed files with 52 additions and 13 deletions

View File

@ -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 |

View File

@ -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);

View File

@ -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
*/

View File

@ -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);

View File

@ -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;
}