]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
This commit prevents cdr records with AST_CDR_FLAG_ANSLOCKED and AST_CDR_FLAG_LOCKED...
authorMatthew Nicholson <mnicholson@digium.com>
Thu, 21 May 2009 15:25:50 +0000 (15:25 +0000)
committerMatthew Nicholson <mnicholson@digium.com>
Thu, 21 May 2009 15:25:50 +0000 (15:25 +0000)
This is accomplished by adding two functions to update the answer time and disposition of calls that checks for the proper lock flags.  These functions are used in the ast_bridge_call() function so that ForkCDR(A) calls are respected.

This patch also modifies the way ast_bridge_call() chooses the cdr record to base the bridged_cdr on.  Previously the first unlocked cdr record would be chosen, now instead the first cdr record is chosen and forked cdr records are moved to the bridge_cdr.  This allows the original cdr record and any forked cdr records to be properly updated with answer and end times.

(closes issue #13797)
Reported by: sh0t
Tested by: sh0t

(closes issue #14744)
Reported by: deepesh

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

include/asterisk/cdr.h
main/cdr.c
res/res_features.c

index 74f6a0ab1a4ab7e15ff8e011279bddbe4fd2ea0a..e6742dee05b468e5a57218a4f671ca37b1743e3f 100644 (file)
@@ -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
index 39045c9edddec7309fa657af4857608cf2251a16..853fed949e634ecdb3e13ffe5dde83e871cdb84a 100644 (file)
@@ -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)
 {
index cf2b8669dc0f6da4c73c14f07bbe0ab3c6e8e7cb..1e98615f5618561ebbc1abd1672dc4113ac12095 100644 (file)
@@ -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);