diff --git a/src/modules/acc/acc_api.h b/src/modules/acc/acc_api.h index d01f075aedf..93f8acc1001 100644 --- a/src/modules/acc/acc_api.h +++ b/src/modules/acc/acc_api.h @@ -38,6 +38,7 @@ #include "../../core/dprint.h" #include "../../core/sr_module.h" #include "../../core/mem/mem.h" +#include "../dialog/dlg_load.h" /* param trasnporter */ typedef struct acc_param { @@ -65,6 +66,10 @@ typedef struct acc_extra { struct acc_extra *next; } acc_extra_t; +typedef acc_param_t cdr_param_t; +typedef acc_enviroment_t cdr_enviroment_t; +typedef acc_extra_t cdr_extra_t; + typedef int (*core2strar_f)( struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals); typedef int (*extra2strar_f)(struct acc_extra *extra, struct sip_msg *rq, str *val_arr, @@ -73,6 +78,12 @@ typedef int (*legs2strar_f)( struct acc_extra *legs, struct sip_msg *rq, str *va int *int_arr, char *type_arr, int start); typedef acc_extra_t* (*leg_info_f)(void); +/* cdr related fuctions */ +typedef int (*cdr_core2strar_f)( struct dlg_cell* dlg, + str* values, int* unused, char* types); +typedef int (*extra2strar_dlg_only_f)(struct acc_extra *extra, struct dlg_cell* dlg, str *val_arr, + int *int_arr, char *type_arr, const struct dlg_binds* p_dlgb); + /* acc event data structures */ typedef struct acc_info { acc_enviroment_t *env; @@ -82,6 +93,13 @@ typedef struct acc_info { acc_extra_t *leg_info; } acc_info_t; +/* cdr event data structures */ +typedef struct cdr_info { + str *varr; + int *iarr; + char *tarr; +} cdr_info_t; + /* acc engine initialization data structures */ typedef struct acc_init_info { acc_extra_t *leg_info; @@ -90,6 +108,8 @@ typedef struct acc_init_info { typedef int (*acc_init_f)(acc_init_info_t *inf); typedef int (*acc_req_f)(struct sip_msg *req, acc_info_t *data); +typedef int (*cdr_init_f)(void); +typedef int (*cdr_write_f)(struct dlg_cell *dlg, struct sip_msg *req, cdr_info_t *data); /* acc engine structure */ typedef struct acc_engine { char name[16]; @@ -101,6 +121,14 @@ typedef struct acc_engine { struct acc_engine *next; } acc_engine_t; +/* cdr engine structure */ +typedef struct cdr_engine { + char name[16]; + cdr_init_f cdr_init; + cdr_write_f cdr_write; + struct cdr_engine *next; +} cdr_engine_t; + #define MAX_ACC_EXTRA 64 #define MAX_ACC_LEG 16 #define ACC_CORE_LEN 6 @@ -114,6 +142,9 @@ typedef int (*acc_api_exec_f)(struct sip_msg *rq, acc_engine_t *eng, acc_param_t* comment); typedef acc_extra_t* (*parse_extra_f)(char *extra_str); +typedef int (*register_cdr_engine_f)(cdr_engine_t *eng); +typedef int (*cdr_api_exec_f)(struct dlg_cell *dlg, struct sip_msg *rq, cdr_engine_t *eng, acc_param_t* comment); + /* the acc API */ typedef struct acc_api { leg_info_f get_leg_info; @@ -123,6 +154,10 @@ typedef struct acc_api { parse_extra_f parse_extra; register_engine_f register_engine; acc_api_exec_f exec; + cdr_core2strar_f get_core_cdr_attrs; + extra2strar_dlg_only_f get_extra_dlg_attrs; + register_cdr_engine_f register_cdr_engine; + cdr_api_exec_f exec_cdr; } acc_api_t; typedef int (*bind_acc_f)(acc_api_t* api); @@ -131,6 +166,9 @@ int acc_run_engines(struct sip_msg *msg, int type, int *reset); acc_engine_t *acc_api_get_engines(void); void acc_api_set_arrays(acc_info_t *inf); +int cdr_run_engines(struct dlg_cell *dlg, struct sip_msg *msg); +cdr_engine_t *cdr_api_get_engines(void); +void cdr_api_set_arrays(cdr_info_t *inf); /** * @brief Load the SL API diff --git a/src/modules/acc/acc_cdr.c b/src/modules/acc/acc_cdr.c index 8a0cdfa2a45..7b052440e63 100644 --- a/src/modules/acc/acc_cdr.c +++ b/src/modules/acc/acc_cdr.c @@ -39,7 +39,6 @@ #include "../../core/str.h" #include "../dialog/dlg_load.h" -#include "acc_api.h" #include "acc_cdr.h" #include "acc_mod.h" #include "acc_extra.h" @@ -92,7 +91,7 @@ extern int _acc_cdr_on_failed; static int string2time( str* time_str, struct timeval* time_value); /* write all basic information to buffers(e.g. start-time ...) */ -static int cdr_core2strar( struct dlg_cell* dlg, +int cdr_core2strar( struct dlg_cell* dlg, str* values, int* unused, char* types) @@ -383,6 +382,10 @@ static int write_cdr( struct dlg_cell* dialog, LM_ERR( "dialog is empty!"); return -1; } + + /* engines decide if they have cdr_expired_dlg_enable set or not */ + cdr_run_engines(dialog, message); + /* message can be null when logging expired dialogs */ if ( !cdr_expired_dlg_enable && !message ){ LM_ERR( "message is empty!"); @@ -950,3 +953,37 @@ void destroy_cdr_generation( void) destroy_extras( cdr_extra); } + +/** + * @brief execute all acc engines for a SIP request event + */ +int cdr_run_engines(struct dlg_cell *dlg, struct sip_msg *msg) +{ + cdr_info_t inf; + cdr_engine_t *e; + + e = cdr_api_get_engines(); + + if(e==NULL) + return 0; + + memset(&inf, 0, sizeof(cdr_info_t)); + inf.varr = cdr_value_array; + inf.iarr = cdr_int_array; + inf.tarr = cdr_type_array; + while(e) { + e->cdr_write(dlg, msg, &inf); + e = e->next; + } + return 0; +} + +/** + * @brief set hooks to acc_info_t attributes + */ +void cdr_api_set_arrays(cdr_info_t *inf) +{ + inf->varr = cdr_value_array; + inf->iarr = cdr_int_array; + inf->tarr = cdr_type_array; +} diff --git a/src/modules/acc/acc_cdr.h b/src/modules/acc/acc_cdr.h index ac28eb88ce2..0043dfba74e 100644 --- a/src/modules/acc/acc_cdr.h +++ b/src/modules/acc/acc_cdr.h @@ -35,6 +35,9 @@ * version). * */ +#ifndef _ACC_CDR_H_ +#define _ACC_CDR_H_ + #define MAX_CDR_CORE 3 #define MAX_CDR_EXTRA 64 @@ -44,6 +47,7 @@ int set_cdr_extra( char* cdr_extra_value); int set_cdr_facility( char* cdr_facility); int init_cdr_generation( void); void destroy_cdr_generation( void); +int cdr_core2strar( struct dlg_cell* dlg, str* values, int* unused, char* types); - +#endif diff --git a/src/modules/acc/acc_logic.c b/src/modules/acc/acc_logic.c index cc66bc67dfc..3cceaf3a3ce 100644 --- a/src/modules/acc/acc_logic.c +++ b/src/modules/acc/acc_logic.c @@ -675,6 +675,16 @@ int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng, return eng->acc_req(rq, &inf); } +/** + * @brief execute an acc event via a specific engine + */ +int cdr_api_exec(struct dlg_cell *dlg, struct sip_msg *rq, cdr_engine_t *eng, acc_param_t* comment) +{ + cdr_info_t inf; + memset(&inf, 0, sizeof(cdr_info_t)); + cdr_api_set_arrays(&inf); + return eng->cdr_write(dlg, rq, &inf); +} static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps ) { diff --git a/src/modules/acc/acc_logic.h b/src/modules/acc/acc_logic.h index ab85c673c86..b2639b6266a 100644 --- a/src/modules/acc/acc_logic.h +++ b/src/modules/acc/acc_logic.h @@ -50,5 +50,7 @@ int ki_acc_request(sip_msg_t *rq, str *comment, str *dbtable); int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng, acc_param_t* comment); +int cdr_api_exec(struct dlg_cell *dlg, struct sip_msg *rq, cdr_engine_t *eng, + acc_param_t* comment); #endif diff --git a/src/modules/acc/acc_mod.c b/src/modules/acc/acc_mod.c index ba18a8f8f64..0b04f3e82c6 100644 --- a/src/modules/acc/acc_mod.c +++ b/src/modules/acc/acc_mod.c @@ -161,6 +161,11 @@ static int acc_init_engines(void); static acc_engine_t *_acc_engines=NULL; static int _acc_module_initialized = 0; +static int cdr_register_engine(cdr_engine_t *eng); +static int cdr_init_engines(void); +static cdr_engine_t *_cdr_engines=NULL; +static int cdr_module_initialized = 0; + /* ------------- fixup function --------------- */ static int acc_fixup(void** param, int param_no); static int free_acc_fixup(void** param, int param_no); @@ -560,6 +565,12 @@ static int mod_init( void ) return -1; } + cdr_module_initialized = 1; + if(cdr_init_engines()<0) { + LM_ERR("failed to init extra engines\n"); + return -1; + } + return 0; } @@ -613,6 +624,19 @@ static int bind_acc(acc_api_t* api) api->get_leg_attrs = legs2strar; api->parse_extra = parse_acc_extra; api->exec = acc_api_exec; + + if (cdr_enable) { + api->register_cdr_engine = cdr_register_engine; + api->get_core_cdr_attrs = cdr_core2strar; + api->get_extra_dlg_attrs = extra2strar_dlg_only; + api->exec_cdr = cdr_api_exec; + } + else { + api->register_cdr_engine = NULL; + api->get_core_cdr_attrs = NULL; + api->get_extra_dlg_attrs = NULL; + api->exec_cdr = NULL; + } return 0; } @@ -685,6 +709,67 @@ static int acc_register_engine(acc_engine_t *eng) return 0; } +/** + * @brief init an acc engine + */ +static int cdr_init_engine(cdr_engine_t *e) +{ + if(cdr_module_initialized==0) + return 0; + + if(e->cdr_init()<0) + { + LM_ERR("failed to initialize extra cdr engine\n"); + return -1; + } + return 0; +} + +/** + * @brief init registered acc engines + */ +static int cdr_init_engines(void) +{ + cdr_engine_t *e; + e = _cdr_engines; + while(e) { + if(cdr_init_engine(e)<0) + return -1; + e = e->next; + } + return 0; +} + +/** + * @brief register an accounting engine + * @return 0 on success, <0 on failure + */ +static int cdr_register_engine(cdr_engine_t *eng) +{ + cdr_engine_t *e; + + if(eng==NULL) + return -1; + e = (cdr_engine_t*)pkg_malloc(sizeof(cdr_engine_t)); + if(e ==NULL) + { + PKG_MEM_ERROR; + return -1; + } + memcpy(e, eng, sizeof(cdr_engine_t)); + + if(cdr_init_engine(e)<0) + { + pkg_free(e); + return -1; + } + + e->next = _cdr_engines; + _cdr_engines = e; + LM_DBG("new acc engine registered: %s\n", e->name); + return 0; +} + /** * */ @@ -693,6 +778,14 @@ acc_engine_t *acc_api_get_engines(void) return _acc_engines; } +/** + * + */ +cdr_engine_t *cdr_api_get_engines(void) +{ + return _cdr_engines; +} + /** * */