Browse code

Merge commit 'origin/andrei/module_interface'

* commit 'origin/andrei/module_interface':
tm makefile: declare SER_MOD_INTERFACE
kamailio LM_* compatibility macros
dual module interface support: ser and kamailio
kamailio compatibility header files
added .gitignore
module interface: minor changes from kamailio

Andrei Pelinescu-Onciul authored on 24/11/2008 13:15:50
Showing 12 changed files
... ...
@@ -716,8 +716,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
716 716
 				}
717 717
 			break;
718 718
 		case MODULE_T:
719
-			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && ((cmd_export_t*)a->val[0].u.data)->function ){
720
-				ret=((cmd_export_t*)a->val[0].u.data)->function(msg,
719
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
720
+					((union cmd_export_u*)a->val[0].u.data)->c.function){
721
+				ret=((union cmd_export_u*)a->val[0].u.data)->c.function(msg,
721 722
 					(char*)a->val[2].u.data,
722 723
 					(char*)a->val[3].u.data
723 724
 				);
... ...
@@ -976,9 +977,11 @@ end:
976 977
 	/* process module onbreak handlers if present */
977 978
 	if (h->rec_lev==0 && ret==0)
978 979
 		for (mod=modules;mod;mod=mod->next)
979
-			if (mod->exports && mod->exports->onbreak_f) {
980
-				mod->exports->onbreak_f( msg );
981
-				DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);
980
+			if ((mod->mod_interface_ver==0) && mod->exports && 
981
+					mod->exports->v0.onbreak_f) {
982
+				mod->exports->v0.onbreak_f( msg );
983
+				DBG("DEBUG: %s onbreak handler called\n",
984
+						mod->exports->c.name);
982 985
 			}
983 986
 	return ret;
984 987
 
... ...
@@ -174,6 +174,7 @@ extern int yylex();
174 174
 static void yyerror(char* s);
175 175
 static char* tmp;
176 176
 static int i_tmp;
177
+static unsigned u_tmp;
177 178
 static struct socket_id* lst_tmp;
178 179
 static struct name_lst*  nl_tmp;
179 180
 static int rt;  /* Type of route block for find_export */
... ...
@@ -2359,9 +2360,12 @@ cmd:
2359 2360
 	}
2360 2361
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
2361 2362
 	| ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST, 0); } LPAREN func_params RPAREN	{
2362
-		mod_func_action->val[0].u.data = find_export_record($1, mod_func_action->val[1].u.number, rt);
2363
+		mod_func_action->val[0].u.data = 
2364
+			find_export_record($1, mod_func_action->val[1].u.number, rt,
2365
+								&u_tmp);
2363 2366
 		if (mod_func_action->val[0].u.data == 0) {
2364
-			if (find_export_record($1, mod_func_action->val[1].u.number, 0) ) {
2367
+			if (find_export_record($1, mod_func_action->val[1].u.number, 0,
2368
+									&u_tmp) ) {
2365 2369
 					yyerror("Command cannot be used in the block\n");
2366 2370
 			} else {
2367 2371
 				yyerror("unknown command, missing loadmodule?\n");
... ...
@@ -198,7 +198,8 @@ static void system_listMethods(rpc_t* rpc, void* c)
198 198
 	}
199 199
 
200 200
 	for(t = modules; t; t = t->next) {
201
-		for(ptr = t->exports->rpc_methods; ptr && ptr->name; ptr++) {
201
+		if (t->mod_interface_ver!=0) continue;
202
+		for(ptr = t->exports->v0.rpc_methods; ptr && ptr->name; ptr++) {
202 203
 			if (rpc->add(c, "s", ptr->name) < 0) return;
203 204
 		}
204 205
 	}
... ...
@@ -232,7 +233,8 @@ static void system_methodHelp(rpc_t* rpc, void* c)
232 233
 	}
233 234
 
234 235
 	for(t = modules; t; t = t->next) {
235
-		for(ptr = t->exports->rpc_methods; ptr && ptr->name; ptr++) {
236
+		if (t->mod_interface_ver!=0) continue;
237
+		for(ptr = t->exports->v0.rpc_methods; ptr && ptr->name; ptr++) {
236 238
 			if (strcmp(name, ptr->name) == 0) {
237 239
 				if (ptr->doc_str && ptr->doc_str[0]) {
238 240
 					rpc->add(c, "s", ptr->doc_str[0]);
... ...
@@ -244,13 +244,34 @@ int log_facility_fixup(void *handle, str *name, void **val);
244 244
 		#define WARN(...) LOG(L_WARN, "WARNING: " LOC_INFO __VA_ARGS__)
245 245
 		#define INFO(...) LOG(L_INFO, "INFO: "    LOC_INFO __VA_ARGS__)
246 246
 		#define BUG(...) LOG(L_CRIT, "BUG: "      LOC_INFO __VA_ARGS__)
247
+		#define NOTICE(...) LOG(L_NOTICE, "NOTICE: " LOC_INFO __VA_ARGS__)
248
+		#define ALERT(...) LOG(L_ALERT, "ALERT: " LOC_INFO __VA_ARGS__)
249
+		#define CRIT(...) LOG(L_CRIT, "CRITICAL: " LOC_INFO __VA_ARGS__)
247 250
 #else
248 251
 		#define DEBUG(fmt, args...) DBG("DEBUG: "       LOC_INFO fmt, ## args)
249 252
 		#define ERR(fmt, args...) LOG(L_ERR, "ERROR: "  LOC_INFO fmt, ## args)
250 253
 		#define WARN(fmt, args...) LOG(L_WARN, "WARN: " LOC_INFO fmt, ## args)
251 254
 		#define INFO(fmt, args...) LOG(L_INFO, "INFO: " LOC_INFO fmt, ## args)
252 255
 		#define BUG(fmt, args...) LOG(L_CRIT, "BUG: "   LOC_INFO fmt, ## args)
256
+		#define NOTICE(fmt, args...) \
257
+			LOG(L_NOTICE, "NOTICE: " LOC_INFO fmt, ## args)
258
+		#define ALERT(fmt, args...) \
259
+			LOG(L_ALERT, "ALERT: " LOC_INFO fmt, ## args)
260
+		#define CRIT(fmt, args...) \
261
+			LOG(L_CRIT, "CRITICAL: " LOC_INFO fmt, ## args)
253 262
 #endif
254 263
 
264
+/* kamailio/openser compatibility */
265
+
266
+#define LM_GEN1 LOG
267
+
268
+#define LM_ALERT ALERT
269
+#define LM_CRIT  CRIT
270
+#define LM_ERR ERR
271
+#define LM_WARN WARN
272
+#define LM_NOTICE
273
+#define LM_INFO INFO
274
+#define LM_DBG DEBUG
275
+
255 276
 
256 277
 #endif /* ifndef dprint_h */
257 278
new file mode 100644
... ...
@@ -0,0 +1,99 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2008 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/*
19
+ * mi compatibility wrapper for kamailio
20
+ * for now it doesn't do anything, it just a compile helper
21
+ * (obsolete, do not use anymore)
22
+ *
23
+ * History:
24
+ * --------
25
+ *  2008-11-17  initial version compatible with kamailio mi/mi.h (andrei)
26
+ */
27
+
28
+#ifndef _mi_h_
29
+#define _mi_h_
30
+
31
+#include "../str.h"
32
+
33
+#define MI_DUP_NAME   (1<<0)
34
+#define MI_DUP_VALUE  (1<<1)
35
+
36
+#define MI_OK_S              "OK"
37
+#define MI_OK_LEN            (sizeof(MI_OK_S)-1)
38
+#define MI_INTERNAL_ERR_S    "Server Internal Error"
39
+#define MI_INTERNAL_ERR_LEN  (sizeof(MI_INTERNAL_ERR_S)-1)
40
+#define MI_MISSING_PARM_S    "Too few or too many arguments"
41
+#define MI_MISSING_PARM_LEN  (sizeof(MI_MISSING_PARM_S)-1)
42
+#define MI_BAD_PARM_S        "Bad parameter"
43
+#define MI_BAD_PARM_LEN      (sizeof(MI_BAD_PARM_S)-1)
44
+
45
+#define MI_SSTR(_s)           _s,(sizeof(_s)-1)
46
+#define MI_OK                 MI_OK_S
47
+#define MI_INTERNAL_ERR       MI_INTERNAL_ERR_S
48
+#define MI_MISSING_PARM       MI_MISSING_PARM_S
49
+#define MI_BAD_PARM           MI_BAD_PARM_S
50
+
51
+
52
+
53
+struct mi_attr{
54
+	str name;
55
+	str value;
56
+	struct mi_attr *next;
57
+};
58
+
59
+
60
+struct mi_node {
61
+	str value;
62
+	str name;
63
+	struct mi_node *kids;
64
+	struct mi_node *next;
65
+	struct mi_node *last;
66
+	struct mi_attr *attributes;
67
+};
68
+
69
+
70
+struct mi_root {
71
+	unsigned int       code;
72
+	str                reason;
73
+	struct mi_handler  *async_hdl;
74
+	struct mi_node     node;
75
+};
76
+
77
+typedef struct mi_root* (mi_cmd_f)(struct mi_root*, void *param);
78
+typedef int (mi_child_init_f)(void);
79
+
80
+
81
+typedef struct mi_export_ {
82
+	char *name;
83
+	mi_cmd_f *cmd;
84
+	unsigned int flags;
85
+	void *param;
86
+	mi_child_init_f *init_f;
87
+}mi_export_t;
88
+
89
+
90
+#define init_mi_tree(code, reason, reason_len) 0
91
+#define free_mi_tree(parent)
92
+#define add_mi_node_sibling(node, flags, name, name_len, val, val_len) 0
93
+#define add_mi_node_child(node, flags, name, name_len, val, val_len) 0
94
+#define addf_mi_node_child(node, flags, name, name_len, fmt, ...) 0
95
+
96
+
97
+#endif /* _mi_h_ */
98
+
99
+
... ...
@@ -84,8 +84,9 @@ int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val)
84 84
 
85 85
 	mod_found = 0;
86 86
 	for(t = modules; t; t = t->next) {
87
-		if (regexec(&preg, t->exports->name, 0, 0, 0) == 0) {
88
-			DBG("set_mod_param_regex: '%s' matches module '%s'\n", regex, t->exports->name);
87
+		if (regexec(&preg, t->exports->c.name, 0, 0, 0) == 0) {
88
+			DBG("set_mod_param_regex: '%s' matches module '%s'\n",
89
+					regex, t->exports->c.name);
89 90
 			mod_found = 1;
90 91
 			/* PARAM_STR (PARAM_STRING) may be assigned also to PARAM_STRING(PARAM_STR) so let get both module param */
91 92
 			ptr = find_param_export(t, name, type | ((type & (PARAM_STR|PARAM_STRING))?PARAM_STR|PARAM_STRING:0), &param_type);
... ...
@@ -100,7 +101,8 @@ int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val)
100 101
 				} else {
101 102
 					val2 = val;
102 103
 				}
103
-				DBG("set_mod_param_regex: found <%s> in module %s [%s]\n", name, t->exports->name, t->path);
104
+				DBG("set_mod_param_regex: found <%s> in module %s [%s]\n",
105
+						name, t->exports->c.name, t->path);
104 106
 				if (param_type & PARAM_USE_FUNC) {
105 107
 					if ( ((param_func_t)(ptr))(param_type, val2) < 0) {
106 108
 						regfree(&preg);
... ...
@@ -137,8 +139,8 @@ int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val)
137 139
 				}
138 140
 			}
139 141
 			else {
140
-				LOG(L_ERR, "set_mod_param_regex: parameter <%s> not found in module <%s>\n",
141
-				    name, t->exports->name);
142
+				LOG(L_ERR, "set_mod_param_regex: parameter <%s> not found in"
143
+							" module <%s>\n", name, t->exports->c.name);
142 144
 				regfree(&preg);
143 145
 				pkg_free(reg);
144 146
 				return -3;
... ...
@@ -9,5 +9,6 @@ include ../../Makefile.defs
9 9
 auto_gen=
10 10
 NAME=tm.so
11 11
 LIBS=
12
+DEFS+= -DSER_MOD_INTERFACE
12 13
 
13 14
 include ../../Makefile.modules
14 15
new file mode 100644
... ...
@@ -0,0 +1,145 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2008 
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/*
19
+ * pvar compatibility wrapper for kamailio
20
+ * for now it doesn't do anything (feel free to rm & replace the file)
21
+ *
22
+ * History:
23
+ * --------
24
+ *  2008-11-17  initial version compatible with kamailio pvar.h (andrei)
25
+ */
26
+
27
+#ifndef _pvar_h_
28
+#define _pvar_h_
29
+
30
+#include "str.h"
31
+#include "usr_avp.h"
32
+#include "parser/msg_parser.h"
33
+
34
+
35
+
36
+
37
+enum _pv_type { 
38
+	PVT_NONE=0,           PVT_EMPTY,             PVT_NULL, 
39
+	PVT_MARKER,           PVT_AVP,               PVT_HDR,
40
+	PVT_PID,              PVT_RETURN_CODE,       PVT_TIMES,
41
+	PVT_TIMEF,            PVT_MSGID,             PVT_METHOD,
42
+	PVT_STATUS,           PVT_REASON,            PVT_RURI,
43
+	PVT_RURI_USERNAME,    PVT_RURI_DOMAIN,       PVT_RURI_PORT,
44
+	PVT_FROM,             PVT_FROM_USERNAME,     PVT_FROM_DOMAIN,
45
+	PVT_FROM_TAG,         PVT_TO,                PVT_TO_USERNAME,
46
+	PVT_TO_DOMAIN,        PVT_TO_TAG,            PVT_CSEQ,
47
+	PVT_CONTACT,          PVT_CALLID,            PVT_USERAGENT,
48
+	PVT_MSG_BUF,          PVT_MSG_LEN,           PVT_FLAGS,
49
+	PVT_HEXFLAGS,         PVT_SRCIP,             PVT_SRCPORT,
50
+	PVT_RCVIP,            PVT_RCVPORT,           PVT_REFER_TO,
51
+	PVT_DSET,             PVT_DSTURI,            PVT_COLOR,
52
+	PVT_BRANCH,           PVT_BRANCHES,          PVT_CONTENT_TYPE,
53
+	PVT_CONTENT_LENGTH,   PVT_MSG_BODY,          PVT_AUTH_USERNAME,
54
+	PVT_AUTH_REALM,       PVT_RURI_PROTOCOL,     PVT_DSTURI_DOMAIN,
55
+	PVT_DSTURI_PORT,      PVT_DSTURI_PROTOCOL,   PVT_FROM_DISPLAYNAME,
56
+	PVT_TO_DISPLAYNAME,   PVT_OURI,              PVT_OURI_USERNAME,
57
+	PVT_OURI_DOMAIN,      PVT_OURI_PORT,         PVT_OURI_PROTOCOL,
58
+	PVT_FORCE_SOCK,       PVT_RPID_URI,          PVT_DIVERSION_URI,
59
+	PVT_ACC_USERNAME,     PVT_PPI,               PVT_PPI_DISPLAYNAME,
60
+	PVT_PPI_DOMAIN,       PVT_PPI_USERNAME,      PVT_PAI_URI,
61
+	PVT_BFLAGS,           PVT_HEXBFLAGS,         PVT_SFLAGS,
62
+	PVT_HEXSFLAGS,        PVT_ERR_CLASS,         PVT_ERR_LEVEL,
63
+	PVT_ERR_INFO,         PVT_ERR_RCODE,         PVT_ERR_RREASON,
64
+	PVT_SCRIPTVAR,        PVT_PROTO,             PVT_AUTH_USERNAME_WHOLE,
65
+	PVT_AUTH_DURI,        PVT_DIV_REASON,        PVT_DIV_PRIVACY,
66
+	PVT_AUTH_DOMAIN,      PVT_EXTRA /* keep it last */
67
+};
68
+
69
+typedef enum _pv_type pv_type_t;
70
+typedef int pv_flags_t;
71
+
72
+typedef struct _pv_value
73
+{
74
+	str rs;    /*!< string value */
75
+	int ri;    /*!< integer value */
76
+	int flags; /*!< flags about the type of value */
77
+} pv_value_t, *pv_value_p;
78
+
79
+typedef struct _pv_name
80
+{
81
+	int type;             /*!< type of name */
82
+	union {
83
+		struct {
84
+			int type;     /*!< type of int_str name - compatibility with AVPs */
85
+			int_str name; /*!< the value of the name */
86
+		} isname;
87
+		void *dname;      /*!< PV value - dynamic name */
88
+	} u;
89
+} pv_name_t, *pv_name_p;
90
+
91
+typedef struct _pv_index
92
+{
93
+	int type; /*!< type of PV index */
94
+	union {
95
+		int ival;   /*!< integer value */
96
+		void *dval; /*!< PV value - dynamic index */
97
+	} u;
98
+} pv_index_t, *pv_index_p;
99
+
100
+typedef struct _pv_param
101
+{
102
+	pv_name_t    pvn; /*!< PV name */
103
+	pv_index_t   pvi; /*!< PV index */
104
+} pv_param_t, *pv_param_p;
105
+
106
+typedef int (*pv_getf_t) (struct sip_msg*,  pv_param_t*, pv_value_t*);
107
+typedef int (*pv_setf_t) (struct sip_msg*,  pv_param_t*, int, pv_value_t*);
108
+
109
+typedef struct _pv_spec {
110
+	pv_type_t    type;   /*!< type of PV */
111
+	pv_getf_t    getf;   /*!< get PV value function */
112
+	pv_setf_t    setf;   /*!< set PV value function */
113
+	pv_param_t   pvp;    /*!< parameter to be given to get/set functions */
114
+	void         *trans; /*!< transformations */
115
+} pv_spec_t, *pv_spec_p;
116
+
117
+
118
+
119
+typedef int (*pv_parse_name_f)(pv_spec_p sp, str *in);
120
+typedef int (*pv_parse_index_f)(pv_spec_p sp, str *in);
121
+typedef int (*pv_init_param_f)(pv_spec_p sp, int param);
122
+
123
+/*! \brief
124
+ * PV spec format:
125
+ * - $class_name
126
+ * - $class_name(inner_name)
127
+ * - $(class_name[index])
128
+ * - $(class_name(inner_name)[index])
129
+ * - $(class_name{transformation})
130
+ * - $(class_name(inner_name){transformation})
131
+ * - $(class_name[index]{transformation})
132
+ * - $(class_name(inner_name)[index]{transformation})
133
+ */
134
+typedef struct _pv_export {
135
+	str name;                      /*!< class name of PV */
136
+	pv_type_t type;                /*!< type of PV */
137
+	pv_getf_t  getf;               /*!< function to get the value */
138
+	pv_setf_t  setf;               /*!< function to set the value */
139
+	pv_parse_name_f parse_name;    /*!< function to parse the inner name */
140
+	pv_parse_index_f parse_index;  /*!< function to parse the index of PV */
141
+	pv_init_param_f init_param;    /*!< function to init the PV spec */
142
+	int iparam;                    /*!< parameter for the init function */
143
+} pv_export_t;
144
+
145
+#endif /* _pvar_h_ */
... ...
@@ -386,7 +386,7 @@ static int fix_actions(struct action* a)
386 386
 	struct proxy_l* p;
387 387
 	char *tmp;
388 388
 	int ret;
389
-	cmd_export_t* cmd;
389
+	union cmd_export_u* cmd;
390 390
 	str s;
391 391
 	struct hostent* he;
392 392
 	struct ip_addr ip;
... ...
@@ -504,9 +504,9 @@ static int fix_actions(struct action* a)
504 504
 
505 505
 			case MODULE_T:
506 506
 				cmd = t->val[0].u.data;
507
-				if (cmd && cmd->fixup) {
507
+				if (cmd && cmd->c.fixup) {
508 508
 					int i;
509
-					DBG("fixing %s()\n", cmd->name);
509
+					DBG("fixing %s()\n", cmd->c.name);
510 510
 					/* type cast NUMBER to STRING, old modules may expect
511 511
 					 * all STRING params during fixup */
512 512
 					for (i=0; i<t->val[1].u.number; i++) {
... ...
@@ -527,7 +527,7 @@ static int fix_actions(struct action* a)
527 527
 					for (i=0; i<t->val[1].u.number; i++) {
528 528
 						void *p;
529 529
 						p = t->val[i+2].u.data;
530
-						ret = cmd->fixup(&t->val[i+2].u.data, i+1);
530
+						ret = cmd->c.fixup(&t->val[i+2].u.data, i+1);
531 531
 						if (t->val[i+2].u.data != p)
532 532
 							t->val[i+2].type = MODFIXUP_ST;
533 533
 						if (ret < 0)
... ...
@@ -37,6 +37,7 @@
37 37
  *               find_export_record
38 38
  *  2006-02-07  added fix_flag (andrei)
39 39
  *  2008-02-29  store all the reponse callbacks in their own array (andrei)
40
+ *  2008-11-17  support dual module interface: ser & kamailio (andrei)
40 41
  */
41 42
 
42 43
 
... ...
@@ -63,30 +64,30 @@
63 64
 struct sr_module* modules=0;
64 65
 
65 66
 #ifdef STATIC_EXEC
66
-	extern struct module_exports* exec_exports();
67
+	extern struct module_exports exec_exports;
67 68
 #endif
68 69
 #ifdef STATIC_TM
69
-	extern struct module_exports* tm_exports();
70
+	extern struct module_exports tm_exports;
70 71
 #endif
71 72
 
72 73
 #ifdef STATIC_MAXFWD
73
-	extern struct module_exports* maxfwd_exports();
74
+	extern struct module_exports maxfwd_exports;
74 75
 #endif
75 76
 
76 77
 #ifdef STATIC_AUTH
77
-	extern struct module_exports* auth_exports();
78
+	extern struct module_exports auth_exports;
78 79
 #endif
79 80
 
80 81
 #ifdef STATIC_RR
81
-	extern struct module_exports* rr_exports();
82
+	extern struct module_exports rr_exports;
82 83
 #endif
83 84
 
84 85
 #ifdef STATIC_USRLOC
85
-	extern struct module_exports* usrloc_exports();
86
+	extern struct module_exports usrloc_exports;
86 87
 #endif
87 88
 
88 89
 #ifdef STATIC_SL
89
-	extern struct module_exports* sl_exports();
90
+	extern struct module_exports sl_exports;
90 91
 #endif
91 92
 
92 93
 
... ...
@@ -101,37 +102,37 @@ int register_builtin_modules()
101 102
 
102 103
 	ret=0;
103 104
 #ifdef STATIC_TM
104
-	ret=register_module(tm_exports,"built-in", 0);
105
+	ret=register_module(MODULE_INTERFACE_VER, &tm_exports,"built-in", 0);
105 106
 	if (ret<0) return ret;
106 107
 #endif
107 108
 
108 109
 #ifdef STATIC_EXEC
109
-	ret=register_module(exec_exports,"built-in", 0);
110
+	ret=register_module(MODULE_INTERFACE_VER, &exec_exports,"built-in", 0);
110 111
 	if (ret<0) return ret;
111 112
 #endif
112 113
 
113 114
 #ifdef STATIC_MAXFWD
114
-	ret=register_module(maxfwd_exports, "built-in", 0);
115
+	ret=register_module(MODULE_INTERFACE_VER, &maxfwd_exports, "built-in", 0);
115 116
 	if (ret<0) return ret;
116 117
 #endif
117 118
 
118 119
 #ifdef STATIC_AUTH
119
-	ret=register_module(auth_exports, "built-in", 0);
120
+	ret=register_module(MODULE_INTERFACE_VER, &auth_exports, "built-in", 0);
120 121
 	if (ret<0) return ret;
121 122
 #endif
122 123
 
123 124
 #ifdef STATIC_RR
124
-	ret=register_module(rr_exports, "built-in", 0);
125
+	ret=register_module(MODULE_INTERFACE_VER, &rr_exports, "built-in", 0);
125 126
 	if (ret<0) return ret;
126 127
 #endif
127 128
 
128 129
 #ifdef STATIC_USRLOC
129
-	ret=register_module(usrloc_exports, "built-in", 0);
130
+	ret=register_module(MODULE_INTERFACE_VER, &usrloc_exports, "built-in", 0);
130 131
 	if (ret<0) return ret;
131 132
 #endif
132 133
 
133 134
 #ifdef STATIC_SL
134
-	ret=register_module(sl_exports, "built-in", 0);
135
+	ret=register_module(MODULE_INTERFACE_VER, &sl_exports, "built-in", 0);
135 136
 	if (ret<0) return ret;
136 137
 #endif
137 138
 
... ...
@@ -142,7 +143,8 @@ int register_builtin_modules()
142 143
 
143 144
 /* registers a module,  register_f= module register  functions
144 145
  * returns <0 on error, 0 on success */
145
-int register_module(struct module_exports* e, char* path, void* handle)
146
+static int register_module(unsigned ver, union module_exports_u* e,
147
+					char* path, void* handle)
146 148
 {
147 149
 	int ret;
148 150
 	struct sr_module* mod;
... ...
@@ -158,6 +160,7 @@ int register_module(struct module_exports* e, char* path, void* handle)
158 160
 	memset(mod,0, sizeof(struct sr_module));
159 161
 	mod->path=path;
160 162
 	mod->handle=handle;
163
+	mod->mod_interface_ver=ver;
161 164
 	mod->exports=e;
162 165
 	mod->next=modules;
163 166
 	modules=mod;
... ...
@@ -218,7 +221,8 @@ int load_module(char* path)
218 221
 {
219 222
 	void* handle;
220 223
 	char* error;
221
-	struct module_exports* exp;
224
+	union module_exports_u* exp;
225
+	unsigned* mod_if_ver;
222 226
 	struct sr_module* t;
223 227
 	struct stat stat_buf;
224 228
 	char* modname;
... ...
@@ -302,13 +306,20 @@ int load_module(char* path)
302 306
 	if (!version_control(handle, path)) {
303 307
 		exit(0);
304 308
 	}
309
+	mod_if_ver = (unsigned *)dlsym(handle,
310
+									DLSYM_PREFIX "module_interface_ver");
311
+	if ( (error =(char*)dlerror())!=0 ){
312
+		LOG(L_ERR, "ERROR: no module interface version in module <%s>\n",
313
+					path );
314
+		goto error1;
315
+	}
305 316
 	/* launch register */
306
-	exp = (struct module_exports*)dlsym(handle, DLSYM_PREFIX "exports");
317
+	exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
307 318
 	if ( (error =(char*)dlerror())!=0 ){
308 319
 		LOG(L_ERR, "ERROR: load_module: %s\n", error);
309 320
 		goto error1;
310 321
 	}
311
-	if (register_module(exp, path, handle)<0) goto error1;
322
+	if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
312 323
 	return 0;
313 324
 
314 325
 error1:
... ...
@@ -321,25 +332,51 @@ skip:
321 332
 
322 333
 
323 334
 
324
-/* searches the module list and returns pointer to the "name" function record or
325
- * 0 if not found
335
+/* searches the module list for function name in module mod and returns 
336
+ *  a pointer to the "name" function record union or 0 if not found
337
+ * sets also *mod_if_ver to the module interface version (needed to know
338
+ * which member of the union should be accessed v0 or v1)
339
+ * mod==0 is a wildcard matching all modules
326 340
  * flags parameter is OR value of all flags that must match
327 341
  */
328
-cmd_export_t* find_export_record(char* name, int param_no, int flags)
342
+union cmd_export_u* find_mod_export_record(char* mod, char* name,
343
+											int param_no, int flags,
344
+											unsigned* mod_if_ver)
329 345
 {
330 346
 	struct sr_module* t;
331
-	cmd_export_t* cmd;
347
+	union cmd_export_u* cmd;
348
+	int i;
349
+	unsigned mver;
350
+
351
+#define FIND_EXPORT_IN_MOD(VER) \
352
+		if (t->exports->VER.cmds) \
353
+			for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
354
+					i++, cmd=(void*)&t->exports->VER.cmds[i]){\
355
+				if((strcmp(name, cmd->VER.name)==0)&& \
356
+					(cmd->VER.param_no==param_no) &&  \
357
+					((cmd->VER.flags & flags) == flags) \
358
+				){ \
359
+					DBG("find_export_record: found <%s> in module %s [%s]\n", \
360
+						name, t->exports->VER.name, t->path); \
361
+					*mod_if_ver=mver; \
362
+					return cmd; \
363
+				} \
364
+			}
332 365
 
333 366
 	for(t=modules;t;t=t->next){
334
-		for(cmd=t->exports->cmds; cmd && cmd->name; cmd++){
335
-			if((strcmp(name, cmd->name)==0)&&
336
-			   (cmd->param_no==param_no) &&
337
-			   ((cmd->flags & flags) == flags)
338
-			  ){
339
-				DBG("find_export_record: found <%s> in module %s [%s]\n",
340
-				    name, t->exports->name, t->path);
341
-				return cmd;
342
-			}
367
+		if (mod!=0 && (strcmp(t->exports->c.name, mod) !=0))
368
+			continue;
369
+		mver=t->mod_interface_ver;
370
+		switch (mver){
371
+			case 0:
372
+				FIND_EXPORT_IN_MOD(v0);
373
+				break;
374
+			case 1:
375
+				FIND_EXPORT_IN_MOD(v1);
376
+				break;
377
+			default:
378
+				BUG("invalid module interface version %d for modules %s\n",
379
+						t->mod_interface_ver, t->path);
343 380
 		}
344 381
 	}
345 382
 	DBG("find_export_record: <%s> not found \n", name);
... ...
@@ -347,11 +384,30 @@ cmd_export_t* find_export_record(char* name, int param_no, int flags)
347 384
 }
348 385
 
349 386
 
387
+
388
+/* searches the module list for function name and returns 
389
+ *  a pointer to the "name" function record union or 0 if not found
390
+ * sets also *mod_if_ver to the module interface version (needed to know
391
+ * which member of the union should be accessed v0 or v1)
392
+ * mod==0 is a wildcard matching all modules
393
+ * flags parameter is OR value of all flags that must match
394
+ */
395
+union cmd_export_u* find_export_record(char* name,
396
+											int param_no, int flags,
397
+											unsigned* mod_if_ver)
398
+{
399
+	return find_mod_export_record(0, name, param_no, flags, mod_if_ver);
400
+}
401
+
402
+
403
+
350 404
 cmd_function find_export(char* name, int param_no, int flags)
351 405
 {
352
-	cmd_export_t* cmd;
353
-	cmd = find_export_record(name, param_no, flags);
354
-	return cmd?cmd->function:0;
406
+	union cmd_export_u* cmd;
407
+	unsigned mver;
408
+	
409
+	cmd = find_export_record(name, param_no, flags, &mver);
410
+	return cmd?cmd->c.function:0;
355 411
 }
356 412
 
357 413
 
... ...
@@ -372,7 +428,8 @@ rpc_export_t* find_rpc_export(char* name, int flags)
372 428
 	}
373 429
 	     /* Continue with modules if not found */
374 430
 	for(t = modules; t; t = t->next) {
375
-		for(rpc = t->exports->rpc_methods; rpc && rpc->name; rpc++) {
431
+		if (t->mod_interface_ver!=0) continue;
432
+		for(rpc = t->exports->v0.rpc_methods; rpc && rpc->name; rpc++) {
376 433
 			if ((strcmp(name, rpc->name) == 0) &&
377 434
 			    ((rpc->flags & flags) == flags)
378 435
 			   ) {
... ...
@@ -385,30 +442,20 @@ rpc_export_t* find_rpc_export(char* name, int flags)
385 442
 
386 443
 
387 444
 /*
388
- * searches the module list and returns pointer to "name" function in module "mod"
445
+ * searches the module list and returns pointer to "name" function in module
446
+ * "mod"
389 447
  * 0 if not found
390 448
  * flags parameter is OR value of all flags that must match
391 449
  */
392 450
 cmd_function find_mod_export(char* mod, char* name, int param_no, int flags)
393 451
 {
394
-	struct sr_module* t;
395
-	cmd_export_t* cmd;
396
-
397
-	for (t = modules; t; t = t->next) {
398
-		if (strcmp(t->exports->name, mod) == 0) {
399
-			for (cmd = t->exports->cmds;  cmd && cmd->name; cmd++) {
400
-				if ((strcmp(name, cmd->name) == 0) &&
401
-				    (cmd->param_no == param_no) &&
402
-				    ((cmd->flags & flags) == flags)
403
-				   ){
404
-					DBG("find_mod_export: found <%s> in module %s [%s]\n",
405
-					    name, t->exports->name, t->path);
406
-					return cmd->function;
407
-				}
408
-			}
409
-		}
410
-	}
452
+	union cmd_export_u* cmd;
453
+	unsigned mver;
411 454
 
455
+	cmd=find_mod_export_record(mod, name, param_no, flags, &mver);
456
+	if (cmd)
457
+		return cmd->c.function;
458
+	
412 459
 	DBG("find_mod_export: <%s> in module <%s> not found\n", name, mod);
413 460
 	return 0;
414 461
 }
... ...
@@ -418,7 +465,7 @@ struct sr_module* find_module_by_name(char* mod) {
418 465
 	struct sr_module* t;
419 466
 
420 467
 	for(t = modules; t; t = t->next) {
421
-		if (strcmp(mod, t->exports->name) == 0) {
468
+		if (strcmp(mod, t->exports->c.name) == 0) {
422 469
 			return t;
423 470
 		}
424 471
 	}
... ...
@@ -427,23 +474,37 @@ struct sr_module* find_module_by_name(char* mod) {
427 474
 }
428 475
 
429 476
 
430
-void* find_param_export(struct sr_module* mod, char* name, modparam_t type_mask, modparam_t *param_type)
477
+void* find_param_export(struct sr_module* mod, char* name,
478
+						modparam_t type_mask, modparam_t *param_type)
431 479
 {
432 480
 	param_export_t* param;
433 481
 
434 482
 	if (!mod)
435 483
 		return 0;
436
-	for(param=mod->exports->params;param && param->name ; param++) {
484
+	param=0;
485
+	switch(mod->mod_interface_ver){
486
+		case 0:
487
+			param=mod->exports->v0.params;
488
+			break;
489
+		case 1:
490
+			param=mod->exports->v1.params;
491
+			break;
492
+		default:
493
+			BUG("bad module interface version %d in module %s [%s]\n",
494
+					mod->mod_interface_ver, mod->exports->c.name, mod->path);
495
+			return 0;
496
+	}
497
+	for(;param && param->name ; param++) {
437 498
 		if ((strcmp(name, param->name) == 0) &&
438 499
 			((param->type & PARAM_TYPE_MASK(type_mask)) != 0)) {
439 500
 			DBG("find_param_export: found <%s> in module %s [%s]\n",
440
-				name, mod->exports->name, mod->path);
501
+				name, mod->exports->c.name, mod->path);
441 502
 			*param_type = param->type;
442 503
 			return param->param_pointer;
443 504
 		}
444 505
 	}
445 506
 	DBG("find_param_export: parameter <%s> not found in module <%s>\n",
446
-			name, mod->exports->name);
507
+			name, mod->exports->c.name);
447 508
 	return 0;
448 509
 }
449 510
 
... ...
@@ -455,7 +516,20 @@ void destroy_modules()
455 516
 	t=modules;
456 517
 	while(t) {
457 518
 		foo=t->next;
458
-		if ((t->exports)&&(t->exports->destroy_f)) t->exports->destroy_f();
519
+		if (t->exports){
520
+			switch(t->mod_interface_ver){
521
+				case 0:
522
+					if ((t->exports->v0.destroy_f)) t->exports->v0.destroy_f();
523
+					break;
524
+				case 1:
525
+					if ((t->exports->v1.destroy_f)) t->exports->v1.destroy_f();
526
+					break;
527
+				default:
528
+					BUG("bad module interface version %d in module %s [%s]\n",
529
+						t->mod_interface_ver, t->exports->c.name,
530
+						t->path);
531
+			}
532
+		}
459 533
 		pkg_free(t);
460 534
 		t=foo;
461 535
 	}
... ...
@@ -477,14 +551,36 @@ int init_modules(void)
477 551
 	struct sr_module* t;
478 552
 
479 553
 	for(t = modules; t; t = t->next) {
480
-		if ((t->exports) && (t->exports->init_f))
481
-			if (t->exports->init_f() != 0) {
482
-				LOG(L_ERR, "init_modules(): Error while initializing"
483
-							" module %s\n", t->exports->name);
484
-				return -1;
554
+		if (t->exports){
555
+			switch(t->mod_interface_ver){
556
+				case 0:
557
+					if (t->exports->v0.init_f)
558
+						if (t->exports->v0.init_f() != 0) {
559
+							LOG(L_ERR, "init_modules(): Error while"
560
+										" initializing module %s\n",
561
+										t->exports->v0.name);
562
+							return -1;
563
+						}
564
+					if (t->exports->v0.response_f)
565
+						mod_response_cbk_no++;
566
+					break;
567
+				case 1:
568
+					if (t->exports->v1.init_f)
569
+						if (t->exports->v1.init_f() != 0) {
570
+							LOG(L_ERR, "init_modules(): Error while"
571
+										" initializing module %s\n",
572
+										t->exports->v1.name);
573
+							return -1;
574
+						}
575
+					if (t->exports->v1.response_f)
576
+						mod_response_cbk_no++;
577
+					break;
578
+				default:
579
+					BUG("bad module interface version %d in module %s [%s]\n",
580
+						t->exports->c.name, t->path);
581
+					return -1;
485 582
 			}
486
-		if ( t->exports && t->exports->response_f)
487
-			mod_response_cbk_no++;
583
+		}
488 584
 	}
489 585
 	mod_response_cbks=pkg_malloc(mod_response_cbk_no * 
490 586
 									sizeof(response_function));
... ...
@@ -494,9 +590,21 @@ int init_modules(void)
494 590
 		return -1;
495 591
 	}
496 592
 	for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next){
497
-		if (t->exports && t->exports->response_f){
498
-			mod_response_cbks[i]=t->exports->response_f;
499
-			i++;
593
+		if (t->exports){
594
+			switch(t->mod_interface_ver){
595
+				case 0:
596
+					if (t->exports->v0.response_f){
597
+						mod_response_cbks[i]=t->exports->v0.response_f;
598
+						i++;
599
+					}
600
+					break;
601
+				case 1:
602
+					if (t->exports->v1.response_f){
603
+						mod_response_cbks[i]=t->exports->v1.response_f;
604
+						i++;
605
+					}
606
+					break;
607
+			}
500 608
 		}
501 609
 	}
502 610
 	return 0;
... ...
@@ -521,12 +629,30 @@ int init_child(int rank)
521 629
 
522 630
 
523 631
 	for(t = modules; t; t = t->next) {
524
-		if (t->exports->init_child_f) {
525
-			if ((t->exports->init_child_f(rank)) < 0) {
526
-				LOG(L_ERR, "init_child(): Initialization of child %d failed\n",
527
-						rank);
632
+		switch(t->mod_interface_ver){
633
+			case 0:
634
+				if (t->exports->v0.init_child_f) {
635
+					if ((t->exports->v0.init_child_f(rank)) < 0) {
636
+						LOG(L_ERR, "init_child(): Initialization of child"
637
+									" %d failed\n", rank);
638
+						return -1;
639
+					}
640
+				}
641
+				break;
642
+			case 1:
643
+				if (t->exports->v1.init_child_f) {
644
+					if ((t->exports->v1.init_child_f(rank)) < 0) {
645
+						LOG(L_ERR, "init_child(): Initialization of child"
646
+									" %d failed\n", rank);
647
+						return -1;
648
+					}
649
+				}
650
+				break;
651
+			default:
652
+				BUG("bad module interface version %d in module %s [%s]\n",
653
+						t->mod_interface_ver, t->exports->c.name,
654
+						t->path);
528 655
 				return -1;
529
-			}
530 656
 		}
531 657
 	}
532 658
 	return 0;
... ...
@@ -547,19 +673,43 @@ static int init_mod_child( struct sr_module* m, int rank )
547 673
 		   propagate it up the stack
548 674
 		 */
549 675
 		if (init_mod_child(m->next, rank)!=0) return -1;
550
-		if (m->exports && m->exports->init_child_f) {
551
-			DBG("DEBUG: init_mod_child (%d): %s\n",
552
-					rank, m->exports->name);
553
-			if (m->exports->init_child_f(rank)<0) {
554
-				LOG(L_ERR, "init_mod_child(): Error while initializing"
555
-							" module %s\n", m->exports->name);
556
-				return -1;
557
-			} else {
558
-				/* module correctly initialized */
559
-				return 0;
676
+		if (m->exports){
677
+			switch(m->mod_interface_ver){
678
+				case 0:
679
+					if (m->exports->v0.init_child_f) {
680
+						DBG("DEBUG: init_mod_child (%d): %s\n",
681
+								rank, m->exports->v0.name);
682
+						if (m->exports->v0.init_child_f(rank)<0) {
683
+							LOG(L_ERR, "init_mod_child(): Error while"
684
+										" initializing module %s\n",
685
+										m->exports->v0.name);
686
+							return -1;
687
+						} else {
688
+							/* module correctly initialized */
689
+							return 0;
690
+						}
691
+					}
692
+					/* no init function -- proceed with success */
693
+					return 0;
694
+				case 1:
695
+					if (m->exports->v1.init_child_f) {
696
+						DBG("DEBUG: init_mod_child (%d): %s\n",
697
+								rank, m->exports->v1.name);
698
+						if (m->exports->v1.init_child_f(rank)<0) {
699
+							LOG(L_ERR, "init_mod_child(): Error while"
700
+										" initializing module %s\n",
701
+										m->exports->v1.name);
702
+							return -1;
703
+						} else {
704
+							/* module correctly initialized */
705
+							return 0;
706
+						}
707
+					}
708
+					/* no init function -- proceed with success */
709
+					return 0;
560 710
 			}
561 711
 		}
562
-		/* no init function -- proceed with success */
712
+		/* no exports -- proceed with success */
563 713
 		return 0;
564 714
 	} else {
565 715
 		/* end of list */
... ...
@@ -590,18 +740,39 @@ static int init_mod( struct sr_module* m )
590 740
 		   propagate it up the stack
591 741
 		 */
592 742
 		if (init_mod(m->next)!=0) return -1;
593
-		if (m->exports && m->exports->init_f) {
594
-			DBG("DEBUG: init_mod: %s\n", m->exports->name);
595
-			if (m->exports->init_f()!=0) {
596
-				LOG(L_ERR, "init_mod(): Error while initializing"
597
-							" module %s\n", m->exports->name);
598
-				return -1;
599
-			} else {
600
-				/* module correctly initialized */
601
-				return 0;
743
+		if (m->exports){
744
+			switch(m->mod_interface_ver){
745
+				case 0:
746
+					if ( m->exports->v0.init_f) {
747
+						DBG("DEBUG: init_mod: %s\n", m->exports->v0.name);
748
+						if (m->exports->v0.init_f()!=0) {
749
+							LOG(L_ERR, "init_mod(): Error while initializing"
750
+										" module %s\n", m->exports->v0.name);
751
+							return -1;
752
+						} else {
753
+							/* module correctly initialized */
754
+							return 0;
755
+						}
756
+					}
757
+					/* no init function -- proceed with success */
758
+					return 0;
759
+				case 1:
760
+					if ( m->exports->v1.init_f) {
761
+						DBG("DEBUG: init_mod: %s\n", m->exports->v1.name);
762
+						if (m->exports->v1.init_f()!=0) {
763
+							LOG(L_ERR, "init_mod(): Error while initializing"
764
+										" module %s\n", m->exports->v1.name);
765
+							return -1;
766
+						} else {
767
+							/* module correctly initialized */
768
+							return 0;
769
+						}
770
+					}
771
+					/* no init function -- proceed with success */
772
+					return 0;
602 773
 			}
603 774
 		}
604
-		/* no init function -- proceed with success */
775
+		/* no exports -- proceed with success */
605 776
 		return 0;
606 777
 	} else {
607 778
 		/* end of list */
... ...
@@ -619,8 +790,18 @@ int init_modules(void)
619 790
 	int i;
620 791
 	
621 792
 	for(t = modules; t; t = t->next)
622
-		if ( t->exports && t->exports->response_f)
623
-			mod_response_cbk_no++;
793
+		if (t->exports){
794
+			switch(t->mod_interface_ver){
795
+				case 0:
796
+					if (t->exports->v0.response_f)
797
+						mod_response_cbk_no++;
798
+					break;
799
+				case 1:
800
+					if (t->exports->v1.response_f)
801
+						mod_response_cbk_no++;
802
+					break;
803
+			}
804
+		}
624 805
 	mod_response_cbks=pkg_malloc(mod_response_cbk_no * 
625 806
 									sizeof(response_function));
626 807
 	if (mod_response_cbks==0){
... ...
@@ -629,9 +810,21 @@ int init_modules(void)
629 810
 		return -1;
630 811
 	}
631 812
 	for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next){
632
-		if (t->exports && t->exports->response_f){
633
-			mod_response_cbks[i]=t->exports->response_f;
634
-			i++;
813
+		if (t->exports){
814
+			switch(t->mod_interface_ver){
815
+				case 0:
816
+					if (t->exports->v0.response_f){
817
+						mod_response_cbks[i]=t->exports->v0.response_f;
818
+						i++;
819
+					}
820
+					break;
821
+				case 1:
822
+					if (t->exports->v1.response_f){
823
+						mod_response_cbks[i]=t->exports->v1.response_f;
824
+						i++;
825
+					}
826
+					break;
827
+			}
635 828
 		}
636 829
 	}
637 830
 	
... ...
@@ -41,6 +41,14 @@
41 41
  *  2007-06-07  added PROC_INIT, called in the main process context
42 42
  *               (same as PROC_MAIN), buf guaranteed to be called before
43 43
  *               any other process is forked (andrei)
44
+ *  2008-11-17  sip-router version: includes some of the openser/kamailio
45
+ *               changes: f(void) instead of f(), free_fixup_function()
46
+ *              dual module interface support: ser & kamailio (andrei)
47
+ */
48
+
49
+/*!
50
+ * \file
51
+ * \brief modules/plug-in structures declarations
44 52
  */
45 53
 
46 54
 
... ...
@@ -53,12 +61,40 @@
53 61
 #include "route_struct.h"
54 62
 #include "str.h"
55 63
 
56
-typedef  struct module_exports* (*module_register)();
64
+/* kamailio compat */
65
+#include "statistics.h"
66
+#include "mi/mi.h"
67
+#include "pvar.h"
68
+
69
+
70
+
71
+#if defined KAMAILIO_MOD_INTERFACE || defined OPENSER_MOD_INTERFACE || \
72
+	defined MOD_INTERFACE_V1
73
+
74
+#define MODULE_INTERFACE_VER 1
75
+#define cmd_export_t kam_cmd_export_t
76
+#define module_exports kam_module_exports
77
+
78
+#elif defined SER_MOD_INTERFACE || defined MOD_INTERFACE_V0
79
+
80
+#define MODULE_INTERFACE_VER 0
81
+#define cmd_export_t ser_cmd_export_t
82
+#define module_exports ser_module_exports
83
+
84
+#else
85
+
86
+/* do nothing for core */
87
+
88
+#endif
89
+
90
+typedef  struct module_exports* (*module_register)(void);
57 91
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
58 92
 typedef  int (*fixup_function)(void** param, int param_no);
93
+typedef  int (*free_fixup_function)(void** param, int param_no);
59 94
 typedef  int (*response_function)(struct sip_msg*);
60 95
 typedef  void (*onbreak_function)(struct sip_msg*);
61
-typedef void (*destroy_function)();
96
+typedef void (*destroy_function)(void);
97
+
62 98
 typedef int (*init_function)(void);
63 99
 typedef int (*child_init_function)(int rank);
64 100
 
... ...
@@ -82,7 +118,8 @@ typedef int (*param_func_t)( modparam_t type, void* val);
82 118
 #define FAILURE_ROUTE 2  /* Function can be used in reply route blocks */
83 119
 #define ONREPLY_ROUTE 4  /* Function can be used in on_reply */
84 120
 #define BRANCH_ROUTE  8  /* Function can be used in branch_route blocks */
85
-#define ONSEND_ROUTE   16  /* Function can be used in onsend_route blocks */
121
+#define ONSEND_ROUTE 16  /* Function can be used in onsend_route blocks */
122
+#define ERROR_ROUTE  32  /* Function can be used in an error route */ 
86 123
 
87 124
 /* Macros - used as rank in child_init function */
88 125
 #define PROC_MAIN      0  /* Main ser process */
... ...
@@ -107,11 +144,24 @@ typedef int (*param_func_t)( modparam_t type, void* val);
107 144
 
108 145
 #define PROC_MIN PROC_NOCHLDINIT /* Minimum process rank */
109 146
 
147
+
148
+#define DEFAULT_DLFLAGS	0 /* value that signals to module loader to
149
+							use default dlopen flags in Kamailio */
150
+#ifndef RTLD_NOW
151
+/* for openbsd */
152
+#define RTLD_NOW DL_LAZY
153
+#endif
154
+
155
+#define KAMAILIO_DLFLAGS	RTLD_NOW
156
+
157
+
110 158
 #define MODULE_VERSION \
111 159
 	char *module_version=SER_FULL_VERSION; \
112
-	char *module_flags=SER_COMPILE_FLAGS;
160
+	char *module_flags=SER_COMPILE_FLAGS; \
161
+	unsigned int module_interface_ver=MODULE_INTERFACE_VER; 
113 162
 
114
-struct cmd_export_ {
163
+/* ser version */
164
+struct ser_cmd_export_ {
115 165
 	char* name;             /* null terminated command name */
116 166
 	cmd_function function;  /* pointer to the corresponding function */
117 167
 	int param_no;           /* number of parameters used by the function */
... ...
@@ -121,6 +171,29 @@ struct cmd_export_ {
121 171
 };
122 172
 
123 173
 
174
+/* kamailo/openser version */
175
+struct kam_cmd_export_ {
176
+	char* name;             /* null terminated command name */
177
+	cmd_function function;  /* pointer to the corresponding function */
178
+	int param_no;           /* number of parameters used by the function */
179
+	fixup_function fixup;   /* pointer to the function called to "fix" the
180
+							   parameters */
181
+	free_fixup_function free_fixup; /* function called to free the "fixed"
182
+									   parameters */
183
+	int flags;              /* Function flags */
184
+};
185
+
186
+
187
+/* members situated at the same place in memory in both ser & kamailio
188
+   cmd_export */
189
+struct cmd_export_common_ {
190
+	char* name;
191
+	cmd_function function; 
192
+	int param_no;
193
+	fixup_function fixup;
194
+};
195
+
196
+
124 197
 struct param_export_ {
125 198
 	char* name;             /* null terminated param. name */
126 199
 	modparam_t type;        /* param. type */
... ...
@@ -157,18 +230,26 @@ typedef struct fparam {
157 230
 } fparam_t;
158 231
 
159 232
 
160
-typedef struct cmd_export_ cmd_export_t;
161
-typedef struct param_export_ param_export_t;
233
+typedef struct param_export_ param_export_t;  
234
+typedef struct ser_cmd_export_ ser_cmd_export_t;
235
+typedef struct kam_cmd_export_ kam_cmd_export_t;
236
+typedef struct cmd_export_common_ cmd_export_common_t;
162 237
 
163
-struct module_exports {
164
-	char* name;                     /* null terminated module name */
238
+union cmd_export_u{
239
+	cmd_export_common_t c; /* common members for everybody */
240
+	ser_cmd_export_t v0;
241
+	kam_cmd_export_t v1;
242
+};
165 243
 
166
-	cmd_export_t* cmds;             /* null terminated array of the exported
244
+
245
+/* ser module exports version */
246
+struct ser_module_exports {
247
+	char* name;                     /* null terminated module name */
248
+	ser_cmd_export_t* cmds;         /* null terminated array of the exported
167 249
 									   commands */
168 250
 	rpc_export_t* rpc_methods;      /* null terminated array of exported rpc methods */
169 251
 	param_export_t* params;         /* null terminated array of the exported
170 252
 									   module parameters */
171
-
172 253
 	init_function init_f;           /* Initialization function */
173 254
 	response_function response_f;   /* function used for responses,
174 255
 									   returns yes or no; can be null */
... ...
@@ -181,10 +262,69 @@ struct module_exports {
181 262
 };
182 263
 
183 264
 
265
+/* kamailio/openser proc_export (missing from ser) */
266
+typedef void (*mod_proc)(int no);
267
+
268
+typedef int (*mod_proc_wrapper)(void);
269
+
270
+struct proc_export_ {
271
+	char *name;
272
+	mod_proc_wrapper pre_fork_function;
273
+	mod_proc_wrapper post_fork_function;
274
+	mod_proc function;
275
+	unsigned int no;
276
+};
277
+
278
+typedef struct proc_export_ proc_export_t;
279
+
280
+
281
+/* kamailio/openser module exports version */
282
+struct kam_module_exports {
283
+	char* name;                     /* null terminated module name */
284
+	unsigned int dlflags;			/*!< flags for dlopen  */
285
+	kam_cmd_export_t* cmds;			/* null terminated array of the exported
286
+									   commands */
287
+	param_export_t* params;			/* null terminated array of the exported
288
+									   module parameters */
289
+	stat_export_t* stats;			/*!< null terminated array of the exported
290
+									  module statistics */
291
+	mi_export_t* mi_cmds;			/*!< null terminated array of the exported
292
+									  MI functions */
293
+	pv_export_t* items;				/*!< null terminated array of the exported
294
+									   module items (pseudo-variables) */
295
+	proc_export_t* procs;			/*!< null terminated array of the
296
+									  additional processes required by the
297
+									  module */
298
+	init_function init_f;           /* Initialization function */
299
+	response_function response_f;   /* function used for responses,
300
+									   returns yes or no; can be null */
301
+	destroy_function destroy_f;     /* function called when the module should
302
+									   be "destroyed", e.g: on ser exit;
303
+									   can be null */
304
+	child_init_function init_child_f;  /* function called by all processes
305
+										  after the fork */
306
+};
307
+
308
+
309
+
310
+/* module exports in the same place in memory in both ser & kamailio */
311
+struct module_exports_common{
312
+	char* name;
313
+};
314
+
315
+
316
+union module_exports_u {
317
+		struct module_exports_common c; /*common members for all the versions*/
318
+		struct ser_module_exports v0;
319
+		struct kam_module_exports v1;
320
+};
321
+
322
+
184 323
 struct sr_module{
185 324
 	char* path;
186 325
 	void* handle;
187
-	struct module_exports* exports;
326
+	unsigned int mod_interface_ver;
327
+	union module_exports_u* exports;
188 328
 	struct sr_module* next;
189 329
 };
190 330
 
... ...
@@ -193,19 +333,20 @@ extern struct sr_module* modules; /* global module list*/
193 333
 extern response_function* mod_response_cbks;/* response callback array */
194 334
 extern int mod_response_cbk_no;    /* size of reponse callbacks array */
195 335
 
196
-int register_builtin_modules();
197
-int register_module(struct module_exports*, char*,  void*);
336
+int register_builtin_modules(void);
337
+/*int register_module(unsigned , struct module_exports*, char*,  void*);*/
198 338
 int load_module(char* path);
199
-cmd_export_t* find_export_record(char* name, int param_no, int flags);
339
+union cmd_export_u* find_export_record(char* name, int param_no, int flags,
340
+										unsigned *ver);
200 341
 cmd_function find_export(char* name, int param_no, int flags);
201 342
 cmd_function find_mod_export(char* mod, char* name, int param_no, int flags);
202 343
 rpc_export_t* find_rpc_export(char* name, int flags);
203
-void destroy_modules();
344
+void destroy_modules(void);
204 345
 int init_child(int rank);
205 346
 int init_modules(void);
206 347
 struct sr_module* find_module_by_name(char* mod);
207 348
 
208
-/*
349
+/*! \brief
209 350
  * Find a parameter with given type and return it's
210 351
  * address in memory
211 352
  * If there is no such parameter, NULL is returned
... ...
@@ -329,4 +470,20 @@ int get_int_fparam(int* dst, struct sip_msg* msg, fparam_t* param);
329 470
  * @return: 0 for success, negative on error.
330 471
  */
331 472
 int get_regex_fparam(regex_t *dst, struct sip_msg* msg, fparam_t* param);
473
+
474
+
475
+/* functions needed for kamailio/openser compatibility */
476
+
477
+/*! \brief Check if module is loaded
478
+ * \return Returns 1 if the module with name 'name' is loaded, and zero otherwise. */
479
+int module_loaded(char *name);
480
+
481
+/*! \brief Counts the additional the number of processes
482
+ requested by modules */
483
+int count_module_procs(void);
484
+
485
+
486
+/*! \brief Forks and starts the additional processes required by modules */
487
+int start_module_procs(void);
488
+
332 489
 #endif /* sr_module_h */
333 490
new file mode 100644
... ...
@@ -0,0 +1,72 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2008 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/*
19
+ * statistics compatibility wrapper for kamailio
20
+ * for now it doesn't do anything
21
+ * (obsolete, do not use anymore)
22
+ *
23
+ * History:
24
+ * --------
25
+ *  2008-11-17  initial version compatible with kamailio statistics.h (andrei)
26
+ */
27
+
28
+#ifndef _STATISTICS_H_
29
+#define _STATISTICS_H_
30
+
31
+#include "str.h"
32
+
33
+#define STAT_NO_RESET  1
34
+#define STAT_NO_SYNC   2
35
+#define STAT_SHM_NAME  4
36
+#define STAT_IS_FUNC   8
37
+
38
+
39
+
40
+typedef unsigned int stat_val;
41
+typedef unsigned long (*stat_function)(void);
42
+
43
+typedef struct stat_var_{
44
+	unsigned int mod_idx;
45
+	str name;
46
+	int flags;
47
+	union{
48
+		stat_val *val;
49
+		stat_function f;
50
+	}u;
51
+	struct stat_var_ *hnext;
52
+	struct stat_var_ *lnext;
53
+} stat_var;
54
+
55
+
56
+typedef struct stat_export_ {
57
+	char* name;                /* null terminated statistic name */
58
+	int flags;                 /* flags */
59
+	stat_var** stat_pointer;   /* pointer to the variable's shm mem location */
60
+} stat_export_t;
61
+
62
+#define get_stat(name)  0
63
+#define get_stat_val(v) 0
64
+#define update_stat(v, n)
65
+#define reset_stat(v)
66
+#define if_update_stat (cond, v, n)
67
+
68
+#ifdef STATISTICS
69
+#warning "sorry sip-router does not support STATISTICS"
70
+#endif
71
+
72
+#endif /* _STATISTICS_H_ */