diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h index 74f6a0ab1a..e6742dee05 100644 --- a/include/asterisk/cdr.h +++ b/include/asterisk/cdr.h @@ -266,6 +266,24 @@ void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan); */ void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data); +/*! Set the answer time for a call */ +/*! + * \param cdr the cdr you wish to associate with the call + * \param t the answer time + * Starts all CDR stuff necessary for doing CDR when answering a call + * NULL argument is just fine. + */ +void ast_cdr_setanswer(struct ast_cdr *cdr, struct timeval t); + +/*! Set the disposition for a call */ +/*! + * \param cdr the cdr you wish to associate with the call + * \param disposition the new disposition + * Set the disposition on a call. + * NULL argument is just fine. + */ +void ast_cdr_setdisposition(struct ast_cdr *cdr, long int disposition); + /*! Convert a string to a detail record AMA flag */ /*! * \param flag string form of flag diff --git a/main/cdr.c b/main/cdr.c index 39045c9edd..853fed949e 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -799,6 +799,30 @@ void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data) } } +void ast_cdr_setanswer(struct ast_cdr *cdr, struct timeval t) +{ + + for (; cdr; cdr = cdr->next) { + if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) + continue; + if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) + continue; + check_post(cdr); + cdr->answer = t; + } +} + +void ast_cdr_setdisposition(struct ast_cdr *cdr, long int disposition) +{ + + for (; cdr; cdr = cdr->next) { + if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) + continue; + check_post(cdr); + cdr->disposition = disposition; + } +} + /* set cid info for one record */ static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c) { diff --git a/res/res_features.c b/res/res_features.c index cf2b8669dc..1e98615f56 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -1668,8 +1668,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast struct ast_bridge_config backup_config; struct ast_cdr *bridge_cdr = NULL; struct ast_cdr *orig_peer_cdr = NULL; - struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */ - struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */ + struct ast_cdr *chan_cdr = chan->cdr; /* the proper chan cdr, if there are forked cdrs */ + struct ast_cdr *peer_cdr = peer->cdr; /* the proper chan cdr, if there are forked cdrs */ struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */ struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */ @@ -1728,6 +1728,10 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN); ast_cdr_update(chan); bridge_cdr = ast_cdr_dup(chan_cdr); + /* rip any forked CDR's off of the chan_cdr and attach + * them to the bridge_cdr instead */ + bridge_cdr->next = chan_cdr->next; + chan_cdr->next = NULL; ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp)); ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata)); } else { @@ -1759,11 +1763,11 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast 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; - bridge_cdr->disposition = peer_cdr->disposition; + ast_cdr_setanswer(bridge_cdr, peer_cdr->answer); + ast_cdr_setdisposition(bridge_cdr, peer_cdr->disposition); if (chan_cdr) { - chan_cdr->answer = peer_cdr->answer; - chan_cdr->disposition = peer_cdr->disposition; + ast_cdr_setanswer(chan_cdr, peer_cdr->answer); + ast_cdr_setdisposition(chan_cdr, peer_cdr->disposition); } } else { ast_cdr_answer(bridge_cdr);