2
0
Эх сурвалжийг харах

acc(k): exported acc API

- internal functions and structures were exported as API to be
  available for new acc engines out of acc module
Daniel-Constantin Mierla 15 жил өмнө
parent
commit
56fa156101

+ 50 - 2
modules_k/acc/acc.c

@@ -61,6 +61,7 @@
 #include "acc.h"
 #include "acc_extra.h"
 #include "acc_logic.h"
+#include "acc_api.h"
 
 #ifdef RAD_ACC
 #include "../../lib/kcore/radius.h"
@@ -118,8 +119,7 @@ static char type_arr[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
  * 		sip_code
  * 		sip_status
  * 		*/
-static inline int core2strar( struct sip_msg *req, str *c_vals,
-			      int *i_vals, char *t_vals)
+int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals)
 {
 	struct to_body *ft_body;
 	struct hdr_field *from;
@@ -828,3 +828,51 @@ error:
 
 #endif
 
+/**
+ * @brief execute all acc engines for a SIP request event
+ */
+int acc_run_engines(struct sip_msg *msg, int type, int *reset)
+{
+	acc_info_t inf;
+	acc_engine_t *e;
+
+	e = acc_api_get_engines();
+
+	if(e==NULL)
+		return 0;
+
+	memset(&inf, 0, sizeof(acc_info_t));
+	inf.env  = &acc_env;
+	inf.varr = val_arr;
+	inf.iarr = int_arr;
+	inf.tarr = type_arr;
+	inf.leg_info = leg_info;
+	while(e) {
+		if(e->flags & 1) {
+			if((type==0) && (msg->flags&(e->acc_flag))) {
+				LM_DBG("acc event for engine: %s\n", e->name);
+				e->acc_req(msg, &inf);
+				if(reset) *reset |= e->acc_flag;
+			}
+			if((type==1) && (msg->flags&(e->missed_flag))) {
+				LM_DBG("missed event for engine: %s\n", e->name);
+				e->acc_req(msg, &inf);
+				if(reset) *reset |= e->missed_flag;
+			}
+		}
+		e = e->next;
+	}
+	return 0;
+}
+
+/**
+ * @brief set hooks to acc_info_t attributes
+ */
+void acc_api_set_arrays(acc_info_t *inf)
+{
+	inf->varr = val_arr;
+	inf->iarr = int_arr;
+	inf->tarr = type_arr;
+	inf->leg_info = leg_info;
+}
+

+ 2 - 0
modules_k/acc/acc.h

@@ -84,6 +84,8 @@
 void acc_log_init(void);
 int  acc_log_request( struct sip_msg *req);
 
+int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals);
+
 #ifdef SQL_ACC
 int  acc_db_init(const str* db_url);
 int  acc_db_init_child(const str* db_url);

+ 157 - 0
modules_k/acc/acc_api.h

@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 FhG Fokus
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ * --------
+ */
+
+/*! \file
+ * \ingroup acc
+ * \brief Acc:: Core accounting
+ *
+ * - See \ref acc.c
+ * - Module: \ref acc
+ */
+
+#ifndef _ACC_API_H_
+#define _ACC_API_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../str.h"
+#include "../../dprint.h"
+#include "../../sr_module.h"
+#include "../../mem/mem.h"
+
+/* param trasnporter */
+typedef struct acc_param {
+	int code;
+	str code_s;
+	str reason;
+} acc_param_t;
+
+/* various acc variables */
+typedef struct acc_enviroment {
+	unsigned int code;
+	str code_s;
+	str reason;
+	struct hdr_field *to;
+	str text;
+	time_t ts;
+} acc_enviroment_t;
+
+/* acc extra parameter */
+typedef struct acc_extra {
+	str        name;       /*!< name (log comment/ column name) */
+	pv_spec_t  spec;       /*!< value's spec */
+	struct acc_extra *next;
+} acc_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,
+		int *int_arr, char *type_arr);
+typedef int (*legs2strar_f)( struct acc_extra *legs, struct sip_msg *rq, str *val_arr,
+		int *int_arr, char *type_arr, int start);
+typedef acc_extra_t* (*leg_info_f)(void);
+
+/* acc event data structures */
+typedef struct acc_info {
+	acc_enviroment_t *env;
+	str *varr;
+	int *iarr;
+	char *tarr;
+	acc_extra_t *leg_info;
+} acc_info_t;
+
+/* acc engine initialization data structures */
+typedef struct acc_init_info {
+	acc_extra_t   *leg_info;
+} acc_init_info_t;
+
+typedef int (*acc_init_f)(acc_init_info_t *inf);
+typedef int (*acc_req_f)(struct sip_msg *req, acc_info_t *data);
+
+/* acc engine structure */
+typedef struct acc_engine {
+	char name[16];
+	int flags;
+	int acc_flag;
+	int missed_flag;
+	acc_init_f acc_init;
+	acc_req_f  acc_req;
+	struct acc_engine *next;
+} acc_engine_t;
+
+#define MAX_ACC_EXTRA 64
+#define MAX_ACC_LEG   16
+#define ACC_CORE_LEN 6
+
+
+enum {TYPE_NULL = 0, TYPE_INT, TYPE_STR};
+
+
+typedef int (*register_engine_f)(acc_engine_t *eng);
+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);
+
+/* the acc API */
+typedef struct acc_api {
+	leg_info_f    get_leg_info;
+	core2strar_f  get_core_attrs;
+	extra2strar_f get_extra_attrs;
+	legs2strar_f  get_leg_attrs;
+	parse_extra_f parse_extra;
+	register_engine_f register_engine;
+	acc_api_exec_f    exec;
+} acc_api_t;
+
+typedef int (*bind_acc_f)(acc_api_t* api);
+
+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);
+
+
+/**
+ * @brief Load the SL API
+ */
+static inline int acc_load_api(acc_api_t *accb)
+{
+	bind_acc_f bindacc;
+
+	bindacc = (bind_acc_f)find_export("bind_acc", 0, 0);
+	if (bindacc == 0) {
+		LM_ERR("cannot find bind_acc\n");
+		return -1;
+	}
+	if (bindacc(accb)==-1)
+	{
+		LM_ERR("cannot bind acc api\n");
+		return -1;
+	}
+	return 0;
+}
+
+
+#endif

+ 1 - 0
modules_k/acc/acc_extra.c

@@ -49,6 +49,7 @@
 #include "../../usr_avp.h"
 #include "../../mem/mem.h"
 #include "../../lib/kcore/km_ut.h"
+#include "acc_api.h"
 #include "acc_extra.h"
 
 #define EQUAL '='

+ 0 - 13
modules_k/acc/acc_extra.h

@@ -47,19 +47,6 @@
 #include "../../pvar.h"
 #include "../../parser/msg_parser.h"
 
-struct acc_extra
-{
-	str        name;       /*!< name (log comment/ column name) */
-	pv_spec_t  spec;       /*!< value's spec */
-	struct acc_extra *next;
-};
-
-
-#define MAX_ACC_EXTRA 64
-#define MAX_ACC_LEG   16
-
-enum {TYPE_NULL = 0, TYPE_INT, TYPE_STR};
-
 void init_acc_extra(void);
 
 struct acc_extra *parse_acc_extra(char *extra);

+ 28 - 0
modules_k/acc/acc_logic.c

@@ -46,6 +46,7 @@
 #include "../../lib/kcore/km_ut.h"
 #include "../../flags.h"
 #include "acc.h"
+#include "acc_api.h"
 #include "acc_mod.h"
 #include "acc_logic.h"
 
@@ -219,6 +220,7 @@ int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo)
 #endif
 
 
+
 /* prepare message and transaction context for later accounting */
 void acc_onreq( struct cell* t, int type, struct tmcb_params *ps )
 {
@@ -335,6 +337,9 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
 	}
 #endif
 
+	/* run extra acc engines */
+	acc_run_engines(req, 1, &flags_to_reset);
+
 	/* Reset the accounting missed_flags
 	 * These can't be reset in the blocks above, because
 	 * it would skip accounting if the flags are identical
@@ -395,6 +400,9 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
 		acc_diam_request(req);
 #endif
 
+	/* run extra acc engines */
+	acc_run_engines(req, 0, NULL);
+
 	if (new_uri_bk.len>=0) {
 		req->new_uri = new_uri_bk;
 		req->parsed_uri_ok = 0;
@@ -434,10 +442,30 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
 		acc_diam_request(ack);
 	}
 #endif
+
+	/* run extra acc engines */
+	acc_run_engines(req, 0, NULL);
 	
 }
 
 
+/**
+ * @brief execute an acc event via a specific engine
+ */
+int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
+		acc_param_t* comment)
+{
+	acc_info_t inf;
+	if (acc_preparse_req(rq)<0)
+		return -1;
+	env_set_to(rq->to);
+	env_set_comment(comment);
+	memset(&inf, 0, sizeof(acc_info_t));
+	inf.env  = &acc_env;
+	acc_api_set_arrays(&inf);
+	return eng->acc_req(rq, &inf);
+}
+
 
 static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
 {

+ 3 - 18
modules_k/acc/acc_logic.h

@@ -39,24 +39,7 @@
 
 #include "../../str.h"
 #include "../../modules/tm/t_hooks.h"
-
-
-/* various acc variables */
-struct acc_enviroment {
-	unsigned int code;
-	str code_s;
-	str reason;
-	struct hdr_field *to;
-	str text;
-	time_t ts;
-};
-
-/* param trasnporter*/
-struct acc_param {
-	int code;
-	str code_s;
-	str reason;
-};
+#include "acc_api.h"
 
 
 void acc_onreq( struct cell* t, int type, struct tmcb_params *ps );
@@ -75,5 +58,7 @@ int w_acc_rad_request(struct sip_msg *rq, char *comment, char *foo);
 int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo);
 #endif
 
+int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
+		acc_param_t* comment);
 
 #endif

+ 118 - 0
modules_k/acc/acc_mod.c

@@ -69,6 +69,7 @@
 #include "../../modules/tm/tm_load.h"
 #include "../rr/api.h"
 #include "acc.h"
+#include "acc_api.h"
 #include "acc_mod.h"
 #include "acc_extra.h"
 #include "acc_logic.h"
@@ -176,6 +177,12 @@ str acc_time_col       = str_init("time");
 
 /*@}*/
 
+static int bind_acc(acc_api_t* api);
+static int acc_register_engine(acc_engine_t *eng);
+static int acc_init_engines(void);
+static acc_engine_t *_acc_engines=NULL;
+static int _acc_module_initialized = 0;
+
 /* ------------- fixup function --------------- */
 static int acc_fixup(void** param, int param_no);
 static int free_acc_fixup(void** param, int param_no);
@@ -200,6 +207,7 @@ static cmd_export_t cmds[] = {
 		acc_fixup, free_acc_fixup,
 		REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
 #endif
+	{"bind_acc",    (cmd_function)bind_acc, 0, 0, 0},
 	{0, 0, 0, 0, 0, 0}
 };
 
@@ -521,6 +529,13 @@ static int mod_init( void )
 	}
 
 #endif
+
+	_acc_module_initialized = 1;
+	if(acc_init_engines()<0) {
+		LM_ERR("failed to init extra engines\n");
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -586,3 +601,106 @@ static void destroy(void)
 #endif
 }
 
+
+/**
+ * @brief return leg_info structure
+ */
+acc_extra_t* get_leg_info(void)
+{
+	return leg_info;
+}
+
+/**
+ * @brief bind functions to ACC API structure
+ */
+static int bind_acc(acc_api_t* api)
+{
+	if (!api) {
+		ERR("Invalid parameter value\n");
+		return -1;
+	}
+
+	api->register_engine = acc_register_engine;
+	api->get_leg_info    = get_leg_info;
+	api->get_core_attrs  = core2strar;
+	api->get_extra_attrs = extra2strar;
+	api->get_leg_attrs   = legs2strar;
+	api->parse_extra     = parse_acc_extra;
+	api->exec            = acc_api_exec;
+	return 0;
+}
+
+/**
+ * @brief init an acc engine
+ */
+static int acc_init_engine(acc_engine_t *e)
+{
+	acc_init_info_t ai;
+
+	if(_acc_module_initialized==0)
+		return 0;
+
+	if(e->flags & 1)
+		return 0;
+
+	memset(&ai, 0, sizeof(acc_init_info_t));
+	ai.leg_info = leg_info;
+	if(e->acc_init(&ai)<0)
+	{
+		LM_ERR("failed to initialize extra acc engine\n");
+		return -1;
+	}
+	e->flags |= 1;
+	return 0;
+}
+
+/**
+ * @brief init registered acc engines
+ */
+static int acc_init_engines(void)
+{
+	acc_engine_t *e;
+	e = _acc_engines;
+	while(e) {
+		if(acc_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 acc_register_engine(acc_engine_t *eng)
+{
+	acc_engine_t *e;
+
+	if(eng==NULL)
+		return -1;
+	e = (acc_engine_t*)pkg_malloc(sizeof(acc_engine_t));
+	if(e ==NULL)
+	{
+		LM_ERR("no more pkg\n");
+		return -1;
+	}
+	memcpy(e, eng, sizeof(acc_engine_t));
+
+	if(acc_init_engine(e)<0)
+		return -1;
+
+	e->next = _acc_engines;
+	_acc_engines = e;
+	LM_DBG("new acc engine registered: %s\n", e->name);
+	return 0;
+}
+
+/**
+ *
+ */
+acc_engine_t *acc_api_get_engines(void)
+{
+	return _acc_engines;
+}
+