Explorar el Código

acc: adding CDR engine functionality

- the engine allows the extension of the acc module
  for anyone wanting to add another format (e.g. JSON)
  or another backend for CDRs
Lucian Balaceanu hace 5 años
padre
commit
e3fe8e7f88

+ 38 - 0
src/modules/acc/acc_api.h

@@ -38,6 +38,7 @@
 #include "../../core/dprint.h"
 #include "../../core/dprint.h"
 #include "../../core/sr_module.h"
 #include "../../core/sr_module.h"
 #include "../../core/mem/mem.h"
 #include "../../core/mem/mem.h"
+#include "../dialog/dlg_load.h"
 
 
 /* param trasnporter */
 /* param trasnporter */
 typedef struct acc_param {
 typedef struct acc_param {
@@ -65,6 +66,10 @@ typedef struct acc_extra {
 	struct acc_extra *next;
 	struct acc_extra *next;
 } acc_extra_t;
 } 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,
 typedef int (*core2strar_f)( struct sip_msg *req, str *c_vals,
 		int *i_vals, char *t_vals);
 		int *i_vals, char *t_vals);
 typedef int (*extra2strar_f)(struct acc_extra *extra, struct sip_msg *rq, str *val_arr,
 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);
 		int *int_arr, char *type_arr, int start);
 typedef acc_extra_t* (*leg_info_f)(void);
 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 */
 /* acc event data structures */
 typedef struct acc_info {
 typedef struct acc_info {
 	acc_enviroment_t *env;
 	acc_enviroment_t *env;
@@ -82,6 +93,13 @@ typedef struct acc_info {
 	acc_extra_t *leg_info;
 	acc_extra_t *leg_info;
 } acc_info_t;
 } 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 */
 /* acc engine initialization data structures */
 typedef struct acc_init_info {
 typedef struct acc_init_info {
 	acc_extra_t   *leg_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_init_f)(acc_init_info_t *inf);
 typedef int (*acc_req_f)(struct sip_msg *req, acc_info_t *data);
 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 */
 /* acc engine structure */
 typedef struct acc_engine {
 typedef struct acc_engine {
 	char name[16];
 	char name[16];
@@ -101,6 +121,14 @@ typedef struct acc_engine {
 	struct acc_engine *next;
 	struct acc_engine *next;
 } acc_engine_t;
 } 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_EXTRA 64
 #define MAX_ACC_LEG   16
 #define MAX_ACC_LEG   16
 #define ACC_CORE_LEN  6
 #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);
 		acc_param_t* comment);
 typedef acc_extra_t* (*parse_extra_f)(char *extra_str);
 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 */
 /* the acc API */
 typedef struct acc_api {
 typedef struct acc_api {
 	leg_info_f    get_leg_info;
 	leg_info_f    get_leg_info;
@@ -123,6 +154,10 @@ typedef struct acc_api {
 	parse_extra_f parse_extra;
 	parse_extra_f parse_extra;
 	register_engine_f register_engine;
 	register_engine_f register_engine;
 	acc_api_exec_f    exec;
 	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;
 } acc_api_t;
 
 
 typedef int (*bind_acc_f)(acc_api_t* api);
 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);
 acc_engine_t *acc_api_get_engines(void);
 void acc_api_set_arrays(acc_info_t *inf);
 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
  * @brief Load the SL API

+ 39 - 2
src/modules/acc/acc_cdr.c

@@ -39,7 +39,6 @@
 #include "../../core/str.h"
 #include "../../core/str.h"
 #include "../dialog/dlg_load.h"
 #include "../dialog/dlg_load.h"
 
 
-#include "acc_api.h"
 #include "acc_cdr.h"
 #include "acc_cdr.h"
 #include "acc_mod.h"
 #include "acc_mod.h"
 #include "acc_extra.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);
 static int string2time( str* time_str, struct timeval* time_value);
 
 
 /* write all basic information to buffers(e.g. start-time ...) */
 /* 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,
 		str* values,
 		int* unused,
 		int* unused,
 		char* types)
 		char* types)
@@ -383,6 +382,10 @@ static int write_cdr( struct dlg_cell* dialog,
 		LM_ERR( "dialog is empty!");
 		LM_ERR( "dialog is empty!");
 		return -1;
 		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  */
 	/* message can be null when logging expired dialogs  */
 	if ( !cdr_expired_dlg_enable && !message ){
 	if ( !cdr_expired_dlg_enable && !message ){
 		LM_ERR( "message is empty!");
 		LM_ERR( "message is empty!");
@@ -950,3 +953,37 @@ void destroy_cdr_generation( void)
 
 
 	destroy_extras( cdr_extra);
 	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;
+}

+ 5 - 1
src/modules/acc/acc_cdr.h

@@ -35,6 +35,9 @@
  *  version).
  *  version).
  *
  *
  */
  */
+#ifndef _ACC_CDR_H_
+#define _ACC_CDR_H_
+
 
 
 #define MAX_CDR_CORE 3
 #define MAX_CDR_CORE 3
 #define MAX_CDR_EXTRA 64
 #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 set_cdr_facility( char* cdr_facility);
 int init_cdr_generation( void);
 int init_cdr_generation( void);
 void destroy_cdr_generation( void);
 void destroy_cdr_generation( void);
+int cdr_core2strar( struct dlg_cell* dlg, str* values, int* unused, char* types);
 
 
 
 
-
+#endif

+ 10 - 0
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);
 	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 )
 static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
 {
 {

+ 2 - 0
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,
 int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
 		acc_param_t* comment);
 		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
 #endif

+ 93 - 0
src/modules/acc/acc_mod.c

@@ -161,6 +161,11 @@ static int acc_init_engines(void);
 static acc_engine_t *_acc_engines=NULL;
 static acc_engine_t *_acc_engines=NULL;
 static int _acc_module_initialized = 0;
 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 --------------- */
 /* ------------- fixup function --------------- */
 static int acc_fixup(void** param, int param_no);
 static int acc_fixup(void** param, int param_no);
 static int free_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;
 		return -1;
 	}
 	}
 
 
+	cdr_module_initialized = 1;
+	if(cdr_init_engines()<0) {
+		LM_ERR("failed to init extra engines\n");
+		return -1;
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -613,6 +624,19 @@ static int bind_acc(acc_api_t* api)
 	api->get_leg_attrs   = legs2strar;
 	api->get_leg_attrs   = legs2strar;
 	api->parse_extra     = parse_acc_extra;
 	api->parse_extra     = parse_acc_extra;
 	api->exec            = acc_api_exec;
 	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;
 	return 0;
 }
 }
 
 
@@ -685,6 +709,67 @@ static int acc_register_engine(acc_engine_t *eng)
 	return 0;
 	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;
 	return _acc_engines;
 }
 }
 
 
+/**
+ *
+ */
+cdr_engine_t *cdr_api_get_engines(void)
+{
+	return _cdr_engines;
+}
+
 /**
 /**
  *
  *
  */
  */