@ -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 ;
}