diff options
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; } |