diff options
author | Joshua Colp <jcolp@digium.com> | 2015-10-21 13:11:44 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2015-10-21 13:11:44 -0500 |
commit | 27e0430f04a099a0f6b9757a15ab022b6fda5f76 (patch) | |
tree | 5e94898a0f955ea426acb48ac80ceeb857f43d3b /main/cdr.c | |
parent | b9bd249a85b7dcb3890fca1df8cf12558f7d82f5 (diff) | |
parent | 77780790e0fa646c15260f4ae4e958e33913bfed (diff) |
Merge "main/cdr: Allow modules to modify CDR fields before dispatching them"
Diffstat (limited to 'main/cdr.c')
-rw-r--r-- | main/cdr.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/main/cdr.c b/main/cdr.c index 8d7f53f17..5e2407502 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -297,6 +297,9 @@ struct cdr_beitem { /*! \brief List of registered backends */ static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem); +/*! \brief List of registered modifiers */ +static AST_RWLIST_HEAD_STATIC(mo_list, cdr_beitem); + /*! \brief Queued CDR waiting to be batched */ struct cdr_batch_item { struct ast_cdr *cdr; @@ -2678,7 +2681,7 @@ int ast_cdr_backend_unsuspend(const char *name) return success; } -int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be) +static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be) { struct cdr_beitem *i = NULL; @@ -2690,11 +2693,11 @@ int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be) return -1; } - AST_RWLIST_WRLOCK(&be_list); - AST_RWLIST_TRAVERSE(&be_list, i, list) { + AST_RWLIST_WRLOCK(generic_list); + AST_RWLIST_TRAVERSE(generic_list, i, list) { if (!strcasecmp(name, i->name)) { ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name); - AST_RWLIST_UNLOCK(&be_list); + AST_RWLIST_UNLOCK(generic_list); return -1; } } @@ -2706,40 +2709,50 @@ int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be) ast_copy_string(i->name, name, sizeof(i->name)); ast_copy_string(i->desc, desc, sizeof(i->desc)); - AST_RWLIST_INSERT_HEAD(&be_list, i, list); - AST_RWLIST_UNLOCK(&be_list); + AST_RWLIST_INSERT_HEAD(generic_list, i, list); + AST_RWLIST_UNLOCK(generic_list); return 0; } -int ast_cdr_unregister(const char *name) +int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be) +{ + return cdr_generic_register(&be_list, name, desc, be); +} + +int ast_cdr_modifier_register(const char *name, const char *desc, ast_cdrbe be) +{ + return cdr_generic_register((struct be_list *)&mo_list, name, desc, be); +} + +static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name) { struct cdr_beitem *match = NULL; int active_count; - AST_RWLIST_WRLOCK(&be_list); - AST_RWLIST_TRAVERSE(&be_list, match, list) { + AST_RWLIST_WRLOCK(generic_list); + AST_RWLIST_TRAVERSE(generic_list, match, list) { if (!strcasecmp(name, match->name)) { break; } } if (!match) { - AST_RWLIST_UNLOCK(&be_list); + AST_RWLIST_UNLOCK(generic_list); return 0; } active_count = ao2_container_count(active_cdrs_by_channel); if (!match->suspended && active_count != 0) { - AST_RWLIST_UNLOCK(&be_list); + AST_RWLIST_UNLOCK(generic_list); ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n", name, active_count); return -1; } - AST_RWLIST_REMOVE(&be_list, match, list); - AST_RWLIST_UNLOCK(&be_list); + AST_RWLIST_REMOVE(generic_list, match, list); + AST_RWLIST_UNLOCK(generic_list); ast_verb(2, "Unregistered '%s' CDR backend\n", name); ast_free(match); @@ -2747,6 +2760,16 @@ int ast_cdr_unregister(const char *name) return 0; } +int ast_cdr_unregister(const char *name) +{ + return ast_cdr_generic_unregister(&be_list, name); +} + +int ast_cdr_modifier_unregister(const char *name) +{ + return ast_cdr_generic_unregister((struct be_list *)&mo_list, name); +} + struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr) { struct ast_cdr *newcdr; @@ -3262,6 +3285,13 @@ static void post_cdr(struct ast_cdr *cdr) continue; } + /* Modify CDR's */ + AST_RWLIST_RDLOCK(&mo_list); + AST_RWLIST_TRAVERSE(&mo_list, i, list) { + i->be(cdr); + } + AST_RWLIST_UNLOCK(&mo_list); + if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) { continue; } |