Browse code

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 authored on 29/07/2010 12:45:23
Showing 8 changed files
... ...
@@ -61,6 +61,7 @@
61 61
 #include "acc.h"
62 62
 #include "acc_extra.h"
63 63
 #include "acc_logic.h"
64
+#include "acc_api.h"
64 65
 
65 66
 #ifdef RAD_ACC
66 67
 #include "../../lib/kcore/radius.h"
... ...
@@ -118,8 +119,7 @@ static char type_arr[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
118 119
  * 		sip_code
119 120
  * 		sip_status
120 121
  * 		*/
121
-static inline int core2strar( struct sip_msg *req, str *c_vals,
122
-			      int *i_vals, char *t_vals)
122
+int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals)
123 123
 {
124 124
 	struct to_body *ft_body;
125 125
 	struct hdr_field *from;
... ...
@@ -828,3 +828,51 @@ error:
828 828
 
829 829
 #endif
830 830
 
831
+/**
832
+ * @brief execute all acc engines for a SIP request event
833
+ */
834
+int acc_run_engines(struct sip_msg *msg, int type, int *reset)
835
+{
836
+	acc_info_t inf;
837
+	acc_engine_t *e;
838
+
839
+	e = acc_api_get_engines();
840
+
841
+	if(e==NULL)
842
+		return 0;
843
+
844
+	memset(&inf, 0, sizeof(acc_info_t));
845
+	inf.env  = &acc_env;
846
+	inf.varr = val_arr;
847
+	inf.iarr = int_arr;
848
+	inf.tarr = type_arr;
849
+	inf.leg_info = leg_info;
850
+	while(e) {
851
+		if(e->flags & 1) {
852
+			if((type==0) && (msg->flags&(e->acc_flag))) {
853
+				LM_DBG("acc event for engine: %s\n", e->name);
854
+				e->acc_req(msg, &inf);
855
+				if(reset) *reset |= e->acc_flag;
856
+			}
857
+			if((type==1) && (msg->flags&(e->missed_flag))) {
858
+				LM_DBG("missed event for engine: %s\n", e->name);
859
+				e->acc_req(msg, &inf);
860
+				if(reset) *reset |= e->missed_flag;
861
+			}
862
+		}
863
+		e = e->next;
864
+	}
865
+	return 0;
866
+}
867
+
868
+/**
869
+ * @brief set hooks to acc_info_t attributes
870
+ */
871
+void acc_api_set_arrays(acc_info_t *inf)
872
+{
873
+	inf->varr = val_arr;
874
+	inf->iarr = int_arr;
875
+	inf->tarr = type_arr;
876
+	inf->leg_info = leg_info;
877
+}
878
+
... ...
@@ -84,6 +84,8 @@
84 84
 void acc_log_init(void);
85 85
 int  acc_log_request( struct sip_msg *req);
86 86
 
87
+int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals);
88
+
87 89
 #ifdef SQL_ACC
88 90
 int  acc_db_init(const str* db_url);
89 91
 int  acc_db_init_child(const str* db_url);
90 92
new file mode 100644
... ...
@@ -0,0 +1,157 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 FhG Fokus
5
+ *
6
+ * This file is part of Kamailio, a free SIP server.
7
+ *
8
+ * Kamailio is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * Kamailio is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License 
19
+ * along with this program; if not, write to the Free Software 
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
+ *
22
+ * History:
23
+ * --------
24
+ */
25
+
26
+/*! \file
27
+ * \ingroup acc
28
+ * \brief Acc:: Core accounting
29
+ *
30
+ * - See \ref acc.c
31
+ * - Module: \ref acc
32
+ */
33
+
34
+#ifndef _ACC_API_H_
35
+#define _ACC_API_H_
36
+
37
+#include <stdio.h>
38
+#include <string.h>
39
+
40
+#include "../../str.h"
41
+#include "../../dprint.h"
42
+#include "../../sr_module.h"
43
+#include "../../mem/mem.h"
44
+
45
+/* param trasnporter */
46
+typedef struct acc_param {
47
+	int code;
48
+	str code_s;
49
+	str reason;
50
+} acc_param_t;
51
+
52
+/* various acc variables */
53
+typedef struct acc_enviroment {
54
+	unsigned int code;
55
+	str code_s;
56
+	str reason;
57
+	struct hdr_field *to;
58
+	str text;
59
+	time_t ts;
60
+} acc_enviroment_t;
61
+
62
+/* acc extra parameter */
63
+typedef struct acc_extra {
64
+	str        name;       /*!< name (log comment/ column name) */
65
+	pv_spec_t  spec;       /*!< value's spec */
66
+	struct acc_extra *next;
67
+} acc_extra_t;
68
+
69
+typedef int (*core2strar_f)( struct sip_msg *req, str *c_vals,
70
+			      int *i_vals, char *t_vals);
71
+typedef int (*extra2strar_f)(struct acc_extra *extra, struct sip_msg *rq, str *val_arr,
72
+		int *int_arr, char *type_arr);
73
+typedef int (*legs2strar_f)( struct acc_extra *legs, struct sip_msg *rq, str *val_arr,
74
+		int *int_arr, char *type_arr, int start);
75
+typedef acc_extra_t* (*leg_info_f)(void);
76
+
77
+/* acc event data structures */
78
+typedef struct acc_info {
79
+	acc_enviroment_t *env;
80
+	str *varr;
81
+	int *iarr;
82
+	char *tarr;
83
+	acc_extra_t *leg_info;
84
+} acc_info_t;
85
+
86
+/* acc engine initialization data structures */
87
+typedef struct acc_init_info {
88
+	acc_extra_t   *leg_info;
89
+} acc_init_info_t;
90
+
91
+typedef int (*acc_init_f)(acc_init_info_t *inf);
92
+typedef int (*acc_req_f)(struct sip_msg *req, acc_info_t *data);
93
+
94
+/* acc engine structure */
95
+typedef struct acc_engine {
96
+	char name[16];
97
+	int flags;
98
+	int acc_flag;
99
+	int missed_flag;
100
+	acc_init_f acc_init;
101
+	acc_req_f  acc_req;
102
+	struct acc_engine *next;
103
+} acc_engine_t;
104
+
105
+#define MAX_ACC_EXTRA 64
106
+#define MAX_ACC_LEG   16
107
+#define ACC_CORE_LEN 6
108
+
109
+
110
+enum {TYPE_NULL = 0, TYPE_INT, TYPE_STR};
111
+
112
+
113
+typedef int (*register_engine_f)(acc_engine_t *eng);
114
+typedef int (*acc_api_exec_f)(struct sip_msg *rq, acc_engine_t *eng,
115
+		acc_param_t* comment);
116
+typedef acc_extra_t* (*parse_extra_f)(char *extra_str);
117
+
118
+/* the acc API */
119
+typedef struct acc_api {
120
+	leg_info_f    get_leg_info;
121
+	core2strar_f  get_core_attrs;
122
+	extra2strar_f get_extra_attrs;
123
+	legs2strar_f  get_leg_attrs;
124
+	parse_extra_f parse_extra;
125
+	register_engine_f register_engine;
126
+	acc_api_exec_f    exec;
127
+} acc_api_t;
128
+
129
+typedef int (*bind_acc_f)(acc_api_t* api);
130
+
131
+int acc_run_engines(struct sip_msg *msg, int type, int *reset);
132
+acc_engine_t *acc_api_get_engines(void);
133
+void acc_api_set_arrays(acc_info_t *inf);
134
+
135
+
136
+/**
137
+ * @brief Load the SL API
138
+ */
139
+static inline int acc_load_api(acc_api_t *accb)
140
+{
141
+	bind_acc_f bindacc;
142
+
143
+	bindacc = (bind_acc_f)find_export("bind_acc", 0, 0);
144
+	if (bindacc == 0) {
145
+		LM_ERR("cannot find bind_acc\n");
146
+		return -1;
147
+	}
148
+	if (bindacc(accb)==-1)
149
+	{
150
+		LM_ERR("cannot bind acc api\n");
151
+		return -1;
152
+	}
153
+	return 0;
154
+}
155
+
156
+
157
+#endif
... ...
@@ -49,6 +49,7 @@
49 49
 #include "../../usr_avp.h"
50 50
 #include "../../mem/mem.h"
51 51
 #include "../../lib/kcore/km_ut.h"
52
+#include "acc_api.h"
52 53
 #include "acc_extra.h"
53 54
 
54 55
 #define EQUAL '='
... ...
@@ -47,19 +47,6 @@
47 47
 #include "../../pvar.h"
48 48
 #include "../../parser/msg_parser.h"
49 49
 
50
-struct acc_extra
51
-{
52
-	str        name;       /*!< name (log comment/ column name) */
53
-	pv_spec_t  spec;       /*!< value's spec */
54
-	struct acc_extra *next;
55
-};
56
-
57
-
58
-#define MAX_ACC_EXTRA 64
59
-#define MAX_ACC_LEG   16
60
-
61
-enum {TYPE_NULL = 0, TYPE_INT, TYPE_STR};
62
-
63 50
 void init_acc_extra(void);
64 51
 
65 52
 struct acc_extra *parse_acc_extra(char *extra);
... ...
@@ -46,6 +46,7 @@
46 46
 #include "../../lib/kcore/km_ut.h"
47 47
 #include "../../flags.h"
48 48
 #include "acc.h"
49
+#include "acc_api.h"
49 50
 #include "acc_mod.h"
50 51
 #include "acc_logic.h"
51 52
 
... ...
@@ -219,6 +220,7 @@ int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo)
219 220
 #endif
220 221
 
221 222
 
223
+
222 224
 /* prepare message and transaction context for later accounting */
223 225
 void acc_onreq( struct cell* t, int type, struct tmcb_params *ps )
224 226
 {
... ...
@@ -335,6 +337,9 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
335 337
 	}
336 338
 #endif
337 339
 
340
+	/* run extra acc engines */
341
+	acc_run_engines(req, 1, &flags_to_reset);
342
+
338 343
 	/* Reset the accounting missed_flags
339 344
 	 * These can't be reset in the blocks above, because
340 345
 	 * 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,
395 400
 		acc_diam_request(req);
396 401
 #endif
397 402
 
403
+	/* run extra acc engines */
404
+	acc_run_engines(req, 0, NULL);
405
+
398 406
 	if (new_uri_bk.len>=0) {
399 407
 		req->new_uri = new_uri_bk;
400 408
 		req->parsed_uri_ok = 0;
... ...
@@ -434,10 +442,30 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
434 442
 		acc_diam_request(ack);
435 443
 	}
436 444
 #endif
445
+
446
+	/* run extra acc engines */
447
+	acc_run_engines(req, 0, NULL);
437 448
 	
438 449
 }
439 450
 
440 451
 
452
+/**
453
+ * @brief execute an acc event via a specific engine
454
+ */
455
+int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
456
+		acc_param_t* comment)
457
+{
458
+	acc_info_t inf;
459
+	if (acc_preparse_req(rq)<0)
460
+		return -1;
461
+	env_set_to(rq->to);
462
+	env_set_comment(comment);
463
+	memset(&inf, 0, sizeof(acc_info_t));
464
+	inf.env  = &acc_env;
465
+	acc_api_set_arrays(&inf);
466
+	return eng->acc_req(rq, &inf);
467
+}
468
+
441 469
 
442 470
 static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
443 471
 {
... ...
@@ -39,24 +39,7 @@
39 39
 
40 40
 #include "../../str.h"
41 41
 #include "../../modules/tm/t_hooks.h"
42
-
43
-
44
-/* various acc variables */
45
-struct acc_enviroment {
46
-	unsigned int code;
47
-	str code_s;
48
-	str reason;
49
-	struct hdr_field *to;
50
-	str text;
51
-	time_t ts;
52
-};
53
-
54
-/* param trasnporter*/
55
-struct acc_param {
56
-	int code;
57
-	str code_s;
58
-	str reason;
59
-};
42
+#include "acc_api.h"
60 43
 
61 44
 
62 45
 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);
75 58
 int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo);
76 59
 #endif
77 60
 
61
+int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
62
+		acc_param_t* comment);
78 63
 
79 64
 #endif
... ...
@@ -69,6 +69,7 @@
69 69
 #include "../../modules/tm/tm_load.h"
70 70
 #include "../rr/api.h"
71 71
 #include "acc.h"
72
+#include "acc_api.h"
72 73
 #include "acc_mod.h"
73 74
 #include "acc_extra.h"
74 75
 #include "acc_logic.h"
... ...
@@ -176,6 +177,12 @@ str acc_time_col       = str_init("time");
176 177
 
177 178
 /*@}*/
178 179
 
180
+static int bind_acc(acc_api_t* api);
181
+static int acc_register_engine(acc_engine_t *eng);
182
+static int acc_init_engines(void);
183
+static acc_engine_t *_acc_engines=NULL;
184
+static int _acc_module_initialized = 0;
185
+
179 186
 /* ------------- fixup function --------------- */
180 187
 static int acc_fixup(void** param, int param_no);
181 188
 static int free_acc_fixup(void** param, int param_no);
... ...
@@ -200,6 +207,7 @@ static cmd_export_t cmds[] = {
200 207
 		acc_fixup, free_acc_fixup,
201 208
 		REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
202 209
 #endif
210
+	{"bind_acc",    (cmd_function)bind_acc, 0, 0, 0},
203 211
 	{0, 0, 0, 0, 0, 0}
204 212
 };
205 213
 
... ...
@@ -521,6 +529,13 @@ static int mod_init( void )
521 529
 	}
522 530
 
523 531
 #endif
532
+
533
+	_acc_module_initialized = 1;
534
+	if(acc_init_engines()<0) {
535
+		LM_ERR("failed to init extra engines\n");
536
+		return -1;
537
+	}
538
+
524 539
 	return 0;
525 540
 }
526 541
 
... ...
@@ -586,3 +601,106 @@ static void destroy(void)
586 601
 #endif
587 602
 }
588 603
 
604
+
605
+/**
606
+ * @brief return leg_info structure
607
+ */
608
+acc_extra_t* get_leg_info(void)
609
+{
610
+	return leg_info;
611
+}
612
+
613
+/**
614
+ * @brief bind functions to ACC API structure
615
+ */
616
+static int bind_acc(acc_api_t* api)
617
+{
618
+	if (!api) {
619
+		ERR("Invalid parameter value\n");
620
+		return -1;
621
+	}
622
+
623
+	api->register_engine = acc_register_engine;
624
+	api->get_leg_info    = get_leg_info;
625
+	api->get_core_attrs  = core2strar;
626
+	api->get_extra_attrs = extra2strar;
627
+	api->get_leg_attrs   = legs2strar;
628
+	api->parse_extra     = parse_acc_extra;
629
+	api->exec            = acc_api_exec;
630
+	return 0;
631
+}
632
+
633
+/**
634
+ * @brief init an acc engine
635
+ */
636
+static int acc_init_engine(acc_engine_t *e)
637
+{
638
+	acc_init_info_t ai;
639
+
640
+	if(_acc_module_initialized==0)
641
+		return 0;
642
+
643
+	if(e->flags & 1)
644
+		return 0;
645
+
646
+	memset(&ai, 0, sizeof(acc_init_info_t));
647
+	ai.leg_info = leg_info;
648
+	if(e->acc_init(&ai)<0)
649
+	{
650
+		LM_ERR("failed to initialize extra acc engine\n");
651
+		return -1;
652
+	}
653
+	e->flags |= 1;
654
+	return 0;
655
+}
656
+
657
+/**
658
+ * @brief init registered acc engines
659
+ */
660
+static int acc_init_engines(void)
661
+{
662
+	acc_engine_t *e;
663
+	e = _acc_engines;
664
+	while(e) {
665
+		if(acc_init_engine(e)<0)
666
+			return -1;
667
+		e = e->next;
668
+	}
669
+	return 0;
670
+}
671
+
672
+/**
673
+ * @brief register an accounting engine
674
+ * @return 0 on success, <0 on failure
675
+ */
676
+static int acc_register_engine(acc_engine_t *eng)
677
+{
678
+	acc_engine_t *e;
679
+
680
+	if(eng==NULL)
681
+		return -1;
682
+	e = (acc_engine_t*)pkg_malloc(sizeof(acc_engine_t));
683
+	if(e ==NULL)
684
+	{
685
+		LM_ERR("no more pkg\n");
686
+		return -1;
687
+	}
688
+	memcpy(e, eng, sizeof(acc_engine_t));
689
+
690
+	if(acc_init_engine(e)<0)
691
+		return -1;
692
+
693
+	e->next = _acc_engines;
694
+	_acc_engines = e;
695
+	LM_DBG("new acc engine registered: %s\n", e->name);
696
+	return 0;
697
+}
698
+
699
+/**
700
+ *
701
+ */
702
+acc_engine_t *acc_api_get_engines(void)
703
+{
704
+	return _acc_engines;
705
+}
706
+