diff options
author | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-11-03 21:21:09 +0000 |
---|---|---|
committer | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-11-03 21:21:09 +0000 |
commit | 899c3fed766d6e8337e4c85ccc54c1de1599c695 (patch) | |
tree | a0f4b7160c78f146373e2ad325b1915676955edf /main | |
parent | 930620c029c038931bd88ec390f525b49e1f74ae (diff) |
This patch adds a sequence field to CDRs that can be combined with the linkedid or uniqueid field to uniquely identify a CDR.
(closes issue #15180)
Reported by: Nick_Lewis
Patches:
cdr-sequence10.diff uploaded by mnicholson (license 96)
Tested by: mnicholson
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@227435 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r-- | main/cdr.c | 37 | ||||
-rw-r--r-- | main/features.c | 2 |
2 files changed, 36 insertions, 3 deletions
diff --git a/main/cdr.c b/main/cdr.c index 69d4a8fe1..9168978a4 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -74,6 +74,11 @@ static struct ast_cdr_batch { struct ast_cdr_batch_item *tail; } *batch = NULL; + +static int cdr_sequence = 0; + +static int cdr_seq_inc(struct ast_cdr *cdr); + static struct sched_context *sched; static int cdr_sched = -1; static pthread_t cdr_thread = AST_PTHREADT_NULL; @@ -165,6 +170,26 @@ int ast_cdr_isset_unanswered(void) return unanswered; } +struct ast_cdr *ast_cdr_dup_unique(struct ast_cdr *cdr) +{ + struct ast_cdr *newcdr = ast_cdr_dup(cdr); + if (!newcdr) + return NULL; + + cdr_seq_inc(newcdr); + return newcdr; +} + +struct ast_cdr *ast_cdr_dup_unique_swap(struct ast_cdr *cdr) +{ + struct ast_cdr *newcdr = ast_cdr_dup(cdr); + if (!newcdr) + return NULL; + + cdr_seq_inc(cdr); + return newcdr; +} + /*! Duplicate a CDR record \returns Pointer to new CDR record */ @@ -279,6 +304,8 @@ void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *wor ast_copy_string(workspace, cdr->linkedid, workspacelen); else if (!strcasecmp(name, "userfield")) ast_copy_string(workspace, cdr->userfield, workspacelen); + else if (!strcasecmp(name, "sequence")) + snprintf(workspace, workspacelen, "%d", cdr->sequence); else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur))) ast_copy_string(workspace, varbuf, workspacelen); else @@ -292,7 +319,7 @@ void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *wor static const char * const cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel", "lastapp", "lastdata", "start", "answer", "end", "duration", "billsec", "disposition", "amaflags", "accountcode", "uniqueid", "linkedid", - "userfield", NULL }; + "userfield", "sequence", NULL }; /*! Set a CDR channel variable \note You can't set the CDR variables that belong to the actual CDR record, like "billsec". */ @@ -847,6 +874,11 @@ int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *c) return 0; } +static int cdr_seq_inc(struct ast_cdr *cdr) +{ + return (cdr->sequence = ast_atomic_fetchadd_int(&cdr_sequence, +1)); +} + int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c) { char *chan; @@ -856,6 +888,7 @@ int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c) chan = S_OR(cdr->channel, "<unknown>"); ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel)); set_one_cid(cdr, c); + cdr_seq_inc(cdr); cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NOANSWER; cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags; @@ -1116,7 +1149,7 @@ void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *_flags) if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) { ast_cdr_end(cdr); - if ((duplicate = ast_cdr_dup(cdr))) { + if ((duplicate = ast_cdr_dup_unique_swap(cdr))) { ast_cdr_detach(duplicate); } ast_set_flag(cdr, AST_CDR_FLAG_POSTED); diff --git a/main/features.c b/main/features.c index 132281c5b..cfce3f1d7 100644 --- a/main/features.c +++ b/main/features.c @@ -2804,7 +2804,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast if (chan_cdr) { ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN); ast_cdr_update(chan); - bridge_cdr = ast_cdr_dup(chan_cdr); + bridge_cdr = ast_cdr_dup_unique_swap(chan_cdr); 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 { |