Browse code

Merge branch 'module_interface' into mod_f_params

* 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 18/11/2008 00:13:21
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 976
 	/* process module onbreak handlers if present */
977 977
 	if (h->rec_lev==0 && ret==0)
978 978
 		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);
979
+			if ((mod->mod_interface_ver==0) && mod->exports && 
980
+					mod->exports->v0.onbreak_f) {
981
+				mod->exports->v0.onbreak_f( msg );
982
+				DBG("DEBUG: %s onbreak handler called\n",
983
+						mod->exports->c.name);
982 984
 			}
983 985
 	return ret;
984 986
 
... ...
@@ -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 2359
 	}
2360 2360
 	| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
2361 2361
 	| 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);
2362
+		mod_func_action->val[0].u.data = 
2363
+			find_export_record($1, mod_func_action->val[1].u.number, rt,
2364
+								&u_tmp);
2363 2365
 		if (mod_func_action->val[0].u.data == 0) {
2364
-			if (find_export_record($1, mod_func_action->val[1].u.number, 0) ) {
2366
+			if (find_export_record($1, mod_func_action->val[1].u.number, 0,
2367
+									&u_tmp) ) {
2365 2368
 					yyerror("Command cannot be used in the block\n");
2366 2369
 			} else {
2367 2370
 				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 232
 	}
233 233
 
234 234
 	for(t = modules; t; t = t->next) {
235
-		for(ptr = t->exports->rpc_methods; ptr && ptr->name; ptr++) {
235
+		if (t->mod_interface_ver!=0) continue;
236
+		for(ptr = t->exports->v0.rpc_methods; ptr && ptr->name; ptr++) {
236 237
 			if (strcmp(name, ptr->name) == 0) {
237 238
 				if (ptr->doc_str && ptr->doc_str[0]) {
238 239
 					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 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2008 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+/*
18
+ * mi compatibility wrapper for kamailio
19
+ * for now it doesn't do anything, it just a compile helper
20
+ * (obsolete, do not use anymore)
21
+ *
22
+ * History:
23
+ * --------
24
+ *  2008-11-17  initial version compatible with kamailio mi/mi.h (andrei)
25
+ */
26
+
27
+#ifndef _mi_h_
28
+#define _mi_h_
29
+
30
+#include "../str.h"
31
+
32
+#define MI_DUP_NAME   (1<<0)
33
+#define MI_DUP_VALUE  (1<<1)
34
+
35
+#define MI_OK_S              "OK"
36
+#define MI_OK_LEN            (sizeof(MI_OK_S)-1)
37
+#define MI_INTERNAL_ERR_S    "Server Internal Error"
38
+#define MI_INTERNAL_ERR_LEN  (sizeof(MI_INTERNAL_ERR_S)-1)
39
+#define MI_MISSING_PARM_S    "Too few or too many arguments"
40
+#define MI_MISSING_PARM_LEN  (sizeof(MI_MISSING_PARM_S)-1)
41
+#define MI_BAD_PARM_S        "Bad parameter"
42
+#define MI_BAD_PARM_LEN      (sizeof(MI_BAD_PARM_S)-1)
43
+
44
+#define MI_SSTR(_s)           _s,(sizeof(_s)-1)
45
+#define MI_OK                 MI_OK_S
46
+#define MI_INTERNAL_ERR       MI_INTERNAL_ERR_S
47
+#define MI_MISSING_PARM       MI_MISSING_PARM_S
48
+#define MI_BAD_PARM           MI_BAD_PARM_S
49
+
50
+
51
+
52
+struct mi_attr{
53
+	str name;
54
+	str value;
55
+	struct mi_attr *next;
56
+};
57
+
58
+
59
+struct mi_node {
60
+	str value;
61
+	str name;
62
+	struct mi_node *kids;
63
+	struct mi_node *next;
64
+	struct mi_node *last;
65
+	struct mi_attr *attributes;
66
+};
67
+
68
+
69
+struct mi_root {
70
+	unsigned int       code;
71
+	str                reason;
72
+	struct mi_handler  *async_hdl;
73
+	struct mi_node     node;
74
+};
75
+
76
+typedef struct mi_root* (mi_cmd_f)(struct mi_root*, void *param);
77
+typedef int (mi_child_init_f)(void);
78
+
79
+
80
+typedef struct mi_export_ {
81
+	char *name;
82
+	mi_cmd_f *cmd;
83
+	unsigned int flags;
84
+	void *param;
85
+	mi_child_init_f *init_f;
86
+}mi_export_t;
87
+
88
+
89
+#define init_mi_tree(code, reason, reason_len) 0
90
+#define free_mi_tree(parent)
91
+#define add_mi_node_sibling(node, flags, name, name_len, val, val_len) 0
92
+#define add_mi_node_child(node, flags, name, name_len, val, val_len) 0
93
+#define addf_mi_node_child(node, flags, name, name_len, fmt, ...) 0
94
+
95
+
96
+#endif /* _mi_h_ */
97
+
98
+
... ...
@@ -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 100
 				} else {
101 101
 					val2 = val;
102 102
 				}
103
-				DBG("set_mod_param_regex: found <%s> in module %s [%s]\n", name, t->exports->name, t->path);
103
+				DBG("set_mod_param_regex: found <%s> in module %s [%s]\n",
104
+						name, t->exports->c.name, t->path);
104 105
 				if (param_type & PARAM_USE_FUNC) {
105 106
 					if ( ((param_func_t)(ptr))(param_type, val2) < 0) {
106 107
 						regfree(&preg);
... ...
@@ -137,8 +139,8 @@ int set_mod_param_regex(char* regex, char* name, modparam_t type, void* val)
137 137
 				}
138 138
 			}
139 139
 			else {
140
-				LOG(L_ERR, "set_mod_param_regex: parameter <%s> not found in module <%s>\n",
141
-				    name, t->exports->name);
140
+				LOG(L_ERR, "set_mod_param_regex: parameter <%s> not found in"
141
+							" module <%s>\n", name, t->exports->c.name);
142 142
 				regfree(&preg);
143 143
 				pkg_free(reg);
144 144
 				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 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2008 
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+/*
18
+ * pvar compatibility wrapper for kamailio
19
+ * for now it doesn't do anything (feel free to rm & replace the file)
20
+ *
21
+ * History:
22
+ * --------
23
+ *  2008-11-17  initial version compatible with kamailio pvar.h (andrei)
24
+ */
25
+
26
+#ifndef _pvar_h_
27
+#define _pvar_h_
28
+
29
+#include "str.h"
30
+#include "usr_avp.h"
31
+#include "parser/msg_parser.h"
32
+
33
+
34
+
35
+
36
+enum _pv_type { 
37
+	PVT_NONE=0,           PVT_EMPTY,             PVT_NULL, 
38
+	PVT_MARKER,           PVT_AVP,               PVT_HDR,
39
+	PVT_PID,              PVT_RETURN_CODE,       PVT_TIMES,
40
+	PVT_TIMEF,            PVT_MSGID,             PVT_METHOD,
41
+	PVT_STATUS,           PVT_REASON,            PVT_RURI,
42
+	PVT_RURI_USERNAME,    PVT_RURI_DOMAIN,       PVT_RURI_PORT,
43
+	PVT_FROM,             PVT_FROM_USERNAME,     PVT_FROM_DOMAIN,
44
+	PVT_FROM_TAG,         PVT_TO,                PVT_TO_USERNAME,
45
+	PVT_TO_DOMAIN,        PVT_TO_TAG,            PVT_CSEQ,
46
+	PVT_CONTACT,          PVT_CALLID,            PVT_USERAGENT,
47
+	PVT_MSG_BUF,          PVT_MSG_LEN,           PVT_FLAGS,
48
+	PVT_HEXFLAGS,         PVT_SRCIP,             PVT_SRCPORT,
49
+	PVT_RCVIP,            PVT_RCVPORT,           PVT_REFER_TO,
50
+	PVT_DSET,             PVT_DSTURI,            PVT_COLOR,
51
+	PVT_BRANCH,           PVT_BRANCHES,          PVT_CONTENT_TYPE,
52
+	PVT_CONTENT_LENGTH,   PVT_MSG_BODY,          PVT_AUTH_USERNAME,
53
+	PVT_AUTH_REALM,       PVT_RURI_PROTOCOL,     PVT_DSTURI_DOMAIN,
54
+	PVT_DSTURI_PORT,      PVT_DSTURI_PROTOCOL,   PVT_FROM_DISPLAYNAME,
55
+	PVT_TO_DISPLAYNAME,   PVT_OURI,              PVT_OURI_USERNAME,
56
+	PVT_OURI_DOMAIN,      PVT_OURI_PORT,         PVT_OURI_PROTOCOL,
57
+	PVT_FORCE_SOCK,       PVT_RPID_URI,          PVT_DIVERSION_URI,
58
+	PVT_ACC_USERNAME,     PVT_PPI,               PVT_PPI_DISPLAYNAME,
59
+	PVT_PPI_DOMAIN,       PVT_PPI_USERNAME,      PVT_PAI_URI,
60
+	PVT_BFLAGS,           PVT_HEXBFLAGS,         PVT_SFLAGS,
61
+	PVT_HEXSFLAGS,        PVT_ERR_CLASS,         PVT_ERR_LEVEL,
62
+	PVT_ERR_INFO,         PVT_ERR_RCODE,         PVT_ERR_RREASON,
63
+	PVT_SCRIPTVAR,        PVT_PROTO,             PVT_AUTH_USERNAME_WHOLE,
64
+	PVT_AUTH_DURI,        PVT_DIV_REASON,        PVT_DIV_PRIVACY,
65
+	PVT_AUTH_DOMAIN,      PVT_EXTRA /* keep it last */
66
+};
67
+
68
+typedef enum _pv_type pv_type_t;
69
+typedef int pv_flags_t;
70
+
71
+typedef struct _pv_value
72
+{
73
+	str rs;    /*!< string value */
74
+	int ri;    /*!< integer value */
75
+	int flags; /*!< flags about the type of value */
76
+} pv_value_t, *pv_value_p;
77
+
78
+typedef struct _pv_name
79
+{
80
+	int type;             /*!< type of name */
81
+	union {
82
+		struct {
83
+			int type;     /*!< type of int_str name - compatibility with AVPs */
84
+			int_str name; /*!< the value of the name */
85
+		} isname;
86
+		void *dname;      /*!< PV value - dynamic name */
87
+	} u;
88
+} pv_name_t, *pv_name_p;
89
+
90
+typedef struct _pv_index
91
+{
92
+	int type; /*!< type of PV index */
93
+	union {
94
+		int ival;   /*!< integer value */
95
+		void *dval; /*!< PV value - dynamic index */
96
+	} u;
97
+} pv_index_t, *pv_index_p;
98
+
99
+typedef struct _pv_param
100
+{
101
+	pv_name_t    pvn; /*!< PV name */
102
+	pv_index_t   pvi; /*!< PV index */
103
+} pv_param_t, *pv_param_p;
104
+
105
+typedef int (*pv_getf_t) (struct sip_msg*,  pv_param_t*, pv_value_t*);
106
+typedef int (*pv_setf_t) (struct sip_msg*,  pv_param_t*, int, pv_value_t*);
107
+
108
+typedef struct _pv_spec {
109
+	pv_type_t    type;   /*!< type of PV */
110
+	pv_getf_t    getf;   /*!< get PV value function */
111
+	pv_setf_t    setf;   /*!< set PV value function */
112
+	pv_param_t   pvp;    /*!< parameter to be given to get/set functions */
113
+	void         *trans; /*!< transformations */
114
+} pv_spec_t, *pv_spec_p;
115
+
116
+
117
+
118
+typedef int (*pv_parse_name_f)(pv_spec_p sp, str *in);
119
+typedef int (*pv_parse_index_f)(pv_spec_p sp, str *in);
120
+typedef int (*pv_init_param_f)(pv_spec_p sp, int param);
121
+
122
+/*! \brief
123
+ * PV spec format:
124
+ * - $class_name
125
+ * - $class_name(inner_name)
126
+ * - $(class_name[index])
127
+ * - $(class_name(inner_name)[index])
128
+ * - $(class_name{transformation})
129
+ * - $(class_name(inner_name){transformation})
130
+ * - $(class_name[index]{transformation})
131
+ * - $(class_name(inner_name)[index]{transformation})
132
+ */
133
+typedef struct _pv_export {
134
+	str name;                      /*!< class name of PV */
135
+	pv_type_t type;                /*!< type of PV */
136
+	pv_getf_t  getf;               /*!< function to get the value */
137
+	pv_setf_t  setf;               /*!< function to set the value */
138
+	pv_parse_name_f parse_name;    /*!< function to parse the inner name */
139
+	pv_parse_index_f parse_index;  /*!< function to parse the index of PV */
140
+	pv_init_param_f init_param;    /*!< function to init the PV spec */
141
+	int iparam;                    /*!< parameter for the init function */
142
+} pv_export_t;
143
+
144
+#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 63
 struct sr_module* modules=0;
64 64
 
65 65
 #ifdef STATIC_EXEC
66
-	extern struct module_exports* exec_exports();
66
+	extern struct module_exports exec_exports;
67 67
 #endif
68 68
 #ifdef STATIC_TM
69
-	extern struct module_exports* tm_exports();
69
+	extern struct module_exports tm_exports;
70 70
 #endif
71 71
 
72 72
 #ifdef STATIC_MAXFWD
73
-	extern struct module_exports* maxfwd_exports();
73
+	extern struct module_exports maxfwd_exports;
74 74
 #endif
75 75
 
76 76
 #ifdef STATIC_AUTH
77
-	extern struct module_exports* auth_exports();
77
+	extern struct module_exports auth_exports;
78 78
 #endif
79 79
 
80 80
 #ifdef STATIC_RR
81
-	extern struct module_exports* rr_exports();
81
+	extern struct module_exports rr_exports;
82 82
 #endif
83 83
 
84 84
 #ifdef STATIC_USRLOC
85
-	extern struct module_exports* usrloc_exports();
85
+	extern struct module_exports usrloc_exports;
86 86
 #endif
87 87
 
88 88
 #ifdef STATIC_SL
89
-	extern struct module_exports* sl_exports();
89
+	extern struct module_exports sl_exports;
90 90
 #endif
91 91
 
92 92
 
... ...
@@ -101,37 +102,37 @@ int register_builtin_modules()
101 101
 
102 102
 	ret=0;
103 103
 #ifdef STATIC_TM
104
-	ret=register_module(tm_exports,"built-in", 0);
104
+	ret=register_module(MODULE_INTERFACE_VER, &tm_exports,"built-in", 0);
105 105
 	if (ret<0) return ret;
106 106
 #endif
107 107
 
108 108
 #ifdef STATIC_EXEC
109
-	ret=register_module(exec_exports,"built-in", 0);
109
+	ret=register_module(MODULE_INTERFACE_VER, &exec_exports,"built-in", 0);
110 110
 	if (ret<0) return ret;
111 111
 #endif
112 112
 
113 113
 #ifdef STATIC_MAXFWD
114
-	ret=register_module(maxfwd_exports, "built-in", 0);
114
+	ret=register_module(MODULE_INTERFACE_VER, &maxfwd_exports, "built-in", 0);
115 115
 	if (ret<0) return ret;
116 116
 #endif
117 117
 
118 118
 #ifdef STATIC_AUTH
119
-	ret=register_module(auth_exports, "built-in", 0);
119
+	ret=register_module(MODULE_INTERFACE_VER, &auth_exports, "built-in", 0);
120 120
 	if (ret<0) return ret;
121 121
 #endif
122 122
 
123 123
 #ifdef STATIC_RR
124
-	ret=register_module(rr_exports, "built-in", 0);
124
+	ret=register_module(MODULE_INTERFACE_VER, &rr_exports, "built-in", 0);
125 125
 	if (ret<0) return ret;
126 126
 #endif
127 127
 
128 128
 #ifdef STATIC_USRLOC
129
-	ret=register_module(usrloc_exports, "built-in", 0);
129
+	ret=register_module(MODULE_INTERFACE_VER, &usrloc_exports, "built-in", 0);
130 130
 	if (ret<0) return ret;
131 131
 #endif
132 132
 
133 133
 #ifdef STATIC_SL
134
-	ret=register_module(sl_exports, "built-in", 0);
134
+	ret=register_module(MODULE_INTERFACE_VER, &sl_exports, "built-in", 0);
135 135
 	if (ret<0) return ret;
136 136
 #endif
137 137
 
... ...
@@ -142,7 +143,8 @@ int register_builtin_modules()
142 142
 
143 143
 /* registers a module,  register_f= module register  functions
144 144
  * returns <0 on error, 0 on success */
145
-int register_module(struct module_exports* e, char* path, void* handle)
145
+static int register_module(unsigned ver, union module_exports_u* e,
146
+					char* path, void* handle)
146 147
 {
147 148
 	int ret;
148 149
 	struct sr_module* mod;
... ...
@@ -158,6 +160,7 @@ int register_module(struct module_exports* e, char* path, void* handle)
158 158
 	memset(mod,0, sizeof(struct sr_module));
159 159
 	mod->path=path;
160 160
 	mod->handle=handle;
161
+	mod->mod_interface_ver=ver;
161 162
 	mod->exports=e;
162 163
 	mod->next=modules;
163 164
 	modules=mod;
... ...
@@ -218,7 +221,8 @@ int load_module(char* path)
218 218
 {
219 219
 	void* handle;
220 220
 	char* error;
221
-	struct module_exports* exp;
221
+	union module_exports_u* exp;
222
+	unsigned* mod_if_ver;
222 223
 	struct sr_module* t;
223 224
 	struct stat stat_buf;
224 225
 	char* modname;
... ...
@@ -302,13 +306,20 @@ int load_module(char* path)
302 302
 	if (!version_control(handle, path)) {
303 303
 		exit(0);
304 304
 	}
305
+	mod_if_ver = (unsigned *)dlsym(handle,
306
+									DLSYM_PREFIX "module_interface_ver");
307
+	if ( (error =(char*)dlerror())!=0 ){
308
+		LOG(L_ERR, "ERROR: no module interface version in module <%s>\n",
309
+					path );
310
+		goto error1;
311
+	}
305 312
 	/* launch register */
306
-	exp = (struct module_exports*)dlsym(handle, DLSYM_PREFIX "exports");
313
+	exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
307 314
 	if ( (error =(char*)dlerror())!=0 ){
308 315
 		LOG(L_ERR, "ERROR: load_module: %s\n", error);
309 316
 		goto error1;
310 317
 	}
311
-	if (register_module(exp, path, handle)<0) goto error1;
318
+	if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
312 319
 	return 0;
313 320
 
314 321
 error1:
... ...
@@ -321,25 +332,51 @@ skip:
321 321
 
322 322
 
323 323
 
324
-/* searches the module list and returns pointer to the "name" function record or
325
- * 0 if not found
324
+/* searches the module list for function name in module mod and returns 
325
+ *  a pointer to the "name" function record union or 0 if not found
326
+ * sets also *mod_if_ver to the module interface version (needed to know
327
+ * which member of the union should be accessed v0 or v1)
328
+ * mod==0 is a wildcard matching all modules
326 329
  * flags parameter is OR value of all flags that must match
327 330
  */
328
-cmd_export_t* find_export_record(char* name, int param_no, int flags)
331
+union cmd_export_u* find_mod_export_record(char* mod, char* name,
332
+											int param_no, int flags,
333
+											unsigned* mod_if_ver)
329 334
 {
330 335
 	struct sr_module* t;
331
-	cmd_export_t* cmd;
336
+	union cmd_export_u* cmd;
337
+	int i;
338
+	unsigned mver;
339
+
340
+#define FIND_EXPORT_IN_MOD(VER) \
341
+		if (t->exports->VER.cmds) \
342
+			for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
343
+					i++, cmd=(void*)&t->exports->VER.cmds[i]){\
344
+				if((strcmp(name, cmd->VER.name)==0)&& \
345
+					(cmd->VER.param_no==param_no) &&  \
346
+					((cmd->VER.flags & flags) == flags) \
347
+				){ \
348
+					DBG("find_export_record: found <%s> in module %s [%s]\n", \
349
+						name, t->exports->VER.name, t->path); \
350
+					*mod_if_ver=mver; \
351
+					return cmd; \
352
+				} \
353
+			}
332 354
 
333 355
 	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
-			}
356
+		if (mod!=0 && (strcmp(t->exports->c.name, mod) !=0))
357
+			continue;
358
+		mver=t->mod_interface_ver;
359
+		switch (mver){
360
+			case 0:
361
+				FIND_EXPORT_IN_MOD(v0);
362
+				break;
363
+			case 1:
364
+				FIND_EXPORT_IN_MOD(v1);
365
+				break;
366
+			default:
367
+				BUG("invalid module interface version %d for modules %s\n",
368
+						t->mod_interface_ver, t->path);
343 369
 		}
344 370
 	}
345 371
 	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 347
 }
348 348
 
349 349
 
350
+
351
+/* searches the module list for function name and returns 
352
+ *  a pointer to the "name" function record union or 0 if not found
353
+ * sets also *mod_if_ver to the module interface version (needed to know
354
+ * which member of the union should be accessed v0 or v1)
355
+ * mod==0 is a wildcard matching all modules
356
+ * flags parameter is OR value of all flags that must match
357
+ */
358
+union cmd_export_u* find_export_record(char* name,
359
+											int param_no, int flags,
360
+											unsigned* mod_if_ver)
361
+{
362
+	return find_mod_export_record(0, name, param_no, flags, mod_if_ver);
363
+}
364
+
365
+
366
+
350 367
 cmd_function find_export(char* name, int param_no, int flags)
351 368
 {
352
-	cmd_export_t* cmd;
353
-	cmd = find_export_record(name, param_no, flags);
354
-	return cmd?cmd->function:0;
369
+	union cmd_export_u* cmd;
370
+	unsigned mver;
371
+	
372
+	cmd = find_export_record(name, param_no, flags, &mver);
373
+	return cmd?cmd->c.function:0;
355 374
 }
356 375
 
357 376
 
... ...
@@ -372,7 +428,8 @@ rpc_export_t* find_rpc_export(char* name, int flags)
372 372
 	}
373 373
 	     /* Continue with modules if not found */
374 374
 	for(t = modules; t; t = t->next) {
375
-		for(rpc = t->exports->rpc_methods; rpc && rpc->name; rpc++) {
375
+		if (t->mod_interface_ver!=0) continue;
376
+		for(rpc = t->exports->v0.rpc_methods; rpc && rpc->name; rpc++) {
376 377
 			if ((strcmp(name, rpc->name) == 0) &&
377 378
 			    ((rpc->flags & flags) == flags)
378 379
 			   ) {
... ...
@@ -385,30 +442,20 @@ rpc_export_t* find_rpc_export(char* name, int flags)
385 385
 
386 386
 
387 387
 /*
388
- * searches the module list and returns pointer to "name" function in module "mod"
388
+ * searches the module list and returns pointer to "name" function in module
389
+ * "mod"
389 390
  * 0 if not found
390 391
  * flags parameter is OR value of all flags that must match
391 392
  */
392 393
 cmd_function find_mod_export(char* mod, char* name, int param_no, int flags)
393 394
 {
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
-	}
395
+	union cmd_export_u* cmd;
396
+	unsigned mver;
411 397
 
398
+	cmd=find_mod_export_record(mod, name, param_no, flags, &mver);
399
+	if (cmd)
400
+		return cmd->c.function;
401
+	
412 402
 	DBG("find_mod_export: <%s> in module <%s> not found\n", name, mod);
413 403
 	return 0;
414 404
 }
... ...
@@ -418,7 +465,7 @@ struct sr_module* find_module_by_name(char* mod) {
418 418
 	struct sr_module* t;
419 419
 
420 420
 	for(t = modules; t; t = t->next) {
421
-		if (strcmp(mod, t->exports->name) == 0) {
421
+		if (strcmp(mod, t->exports->c.name) == 0) {
422 422
 			return t;
423 423
 		}
424 424
 	}
... ...
@@ -427,23 +474,37 @@ struct sr_module* find_module_by_name(char* mod) {
427 427
 }
428 428
 
429 429
 
430
-void* find_param_export(struct sr_module* mod, char* name, modparam_t type_mask, modparam_t *param_type)
430
+void* find_param_export(struct sr_module* mod, char* name,
431
+						modparam_t type_mask, modparam_t *param_type)
431 432
 {
432 433
 	param_export_t* param;
433 434
 
434 435
 	if (!mod)
435 436
 		return 0;
436
-	for(param=mod->exports->params;param && param->name ; param++) {
437
+	param=0;
438
+	switch(mod->mod_interface_ver){
439
+		case 0:
440
+			param=mod->exports->v0.params;
441
+			break;
442
+		case 1:
443
+			param=mod->exports->v1.params;
444
+			break;
445
+		default:
446
+			BUG("bad module interface version %d in module %s [%s]\n",
447
+					mod->mod_interface_ver, mod->exports->c.name, mod->path);
448
+			return 0;
449
+	}
450
+	for(;param && param->name ; param++) {
437 451
 		if ((strcmp(name, param->name) == 0) &&
438 452
 			((param->type & PARAM_TYPE_MASK(type_mask)) != 0)) {
439 453
 			DBG("find_param_export: found <%s> in module %s [%s]\n",
440
-				name, mod->exports->name, mod->path);
454
+				name, mod->exports->c.name, mod->path);
441 455
 			*param_type = param->type;
442 456
 			return param->param_pointer;
443 457
 		}
444 458
 	}
445 459
 	DBG("find_param_export: parameter <%s> not found in module <%s>\n",
446
-			name, mod->exports->name);
460
+			name, mod->exports->c.name);
447 461
 	return 0;
448 462
 }
449 463
 
... ...
@@ -455,7 +516,20 @@ void destroy_modules()
455 455
 	t=modules;
456 456
 	while(t) {
457 457
 		foo=t->next;
458
-		if ((t->exports)&&(t->exports->destroy_f)) t->exports->destroy_f();
458
+		if (t->exports){
459
+			switch(t->mod_interface_ver){
460
+				case 0:
461
+					if ((t->exports->v0.destroy_f)) t->exports->v0.destroy_f();
462
+					break;
463
+				case 1:
464
+					if ((t->exports->v1.destroy_f)) t->exports->v1.destroy_f();
465
+					break;
466
+				default:
467
+					BUG("bad module interface version %d in module %s [%s]\n",
468
+						t->mod_interface_ver, t->exports->c.name,
469
+						t->path);
470
+			}
471
+		}
459 472
 		pkg_free(t);
460 473
 		t=foo;
461 474
 	}
... ...
@@ -477,14 +551,36 @@ int init_modules(void)
477 477
 	struct sr_module* t;
478 478
 
479 479
 	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;
480
+		if (t->exports){
481
+			switch(t->mod_interface_ver){
482
+				case 0:
483
+					if (t->exports->v0.init_f)
484
+						if (t->exports->v0.init_f() != 0) {
485
+							LOG(L_ERR, "init_modules(): Error while"
486
+										" initializing module %s\n",
487
+										t->exports->v0.name);
488
+							return -1;
489
+						}
490
+					if (t->exports->v0.response_f)
491
+						mod_response_cbk_no++;
492
+					break;
493
+				case 1:
494
+					if (t->exports->v1.init_f)
495
+						if (t->exports->v1.init_f() != 0) {
496
+							LOG(L_ERR, "init_modules(): Error while"
497
+										" initializing module %s\n",
498
+										t->exports->v1.name);
499
+							return -1;
500
+						}
501
+					if (t->exports->v1.response_f)
502
+						mod_response_cbk_no++;
503
+					break;
504
+				default:
505
+					BUG("bad module interface version %d in module %s [%s]\n",
506
+						t->exports->c.name, t->path);
507
+					return -1;
485 508
 			}
486
-		if ( t->exports && t->exports->response_f)
487
-			mod_response_cbk_no++;
509
+		}
488 510
 	}
489 511
 	mod_response_cbks=pkg_malloc(mod_response_cbk_no * 
490 512
 									sizeof(response_function));
... ...
@@ -494,9 +590,21 @@ int init_modules(void)
494 494
 		return -1;
495 495
 	}
496 496
 	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++;
497
+		if (t->exports){
498
+			switch(t->mod_interface_ver){
499
+				case 0:
500
+					if (t->exports->v0.response_f){
501
+						mod_response_cbks[i]=t->exports->v0.response_f;
502
+						i++;
503
+					}
504
+					break;
505
+				case 1:
506
+					if (t->exports->v1.response_f){
507
+						mod_response_cbks[i]=t->exports->v1.response_f;
508
+						i++;
509
+					}
510
+					break;
511
+			}
500 512
 		}
501 513
 	}
502 514
 	return 0;
... ...
@@ -521,12 +629,30 @@ int init_child(int rank)
521 521
 
522 522
 
523 523
 	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);
524
+		switch(t->mod_interface_ver){
525
+			case 0:
526
+				if (t->exports->v0.init_child_f) {
527
+					if ((t->exports->v0.init_child_f(rank)) < 0) {
528
+						LOG(L_ERR, "init_child(): Initialization of child"
529
+									" %d failed\n", rank);
530
+						return -1;
531
+					}
532
+				}
533
+				break;
534
+			case 1:
535
+				if (t->exports->v1.init_child_f) {
536
+					if ((t->exports->v1.init_child_f(rank)) < 0) {
537
+						LOG(L_ERR, "init_child(): Initialization of child"
538
+									" %d failed\n", rank);
539
+						return -1;
540
+					}
541
+				}
542
+				break;
543
+			default:
544
+				BUG("bad module interface version %d in module %s [%s]\n",
545
+						t->mod_interface_ver, t->exports->c.name,
546
+						t->path);
528 547
 				return -1;
529
-			}
530 548
 		}
531 549
 	}
532 550
 	return 0;
... ...
@@ -547,19 +673,43 @@ static int init_mod_child( struct sr_module* m, int rank )
547 547
 		   propagate it up the stack
548 548
 		 */
549 549
 		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;
550
+		if (m->exports){
551
+			switch(m->mod_interface_ver){
552
+				case 0:
553
+					if (m->exports->v0.init_child_f) {
554
+						DBG("DEBUG: init_mod_child (%d): %s\n",
555
+								rank, m->exports->v0.name);
556
+						if (m->exports->v0.init_child_f(rank)<0) {
557
+							LOG(L_ERR, "init_mod_child(): Error while"
558
+										" initializing module %s\n",
559
+										m->exports->v0.name);
560
+							return -1;
561
+						} else {
562
+							/* module correctly initialized */
563
+							return 0;
564
+						}
565
+					}
566
+					/* no init function -- proceed with success */
567
+					return 0;
568
+				case 1:
569
+					if (m->exports->v1.init_child_f) {
570
+						DBG("DEBUG: init_mod_child (%d): %s\n",
571
+								rank, m->exports->v1.name);
572
+						if (m->exports->v1.init_child_f(rank)<0) {
573
+							LOG(L_ERR, "init_mod_child(): Error while"
574
+										" initializing module %s\n",
575
+										m->exports->v1.name);
576
+							return -1;
577
+						} else {
578
+							/* module correctly initialized */
579
+							return 0;
580
+						}
581
+					}
582
+					/* no init function -- proceed with success */
583
+					return 0;
560 584
 			}
561 585
 		}
562
-		/* no init function -- proceed with success */
586
+		/* no exports -- proceed with success */
563 587
 		return 0;
564 588
 	} else {
565 589
 		/* end of list */
... ...
@@ -590,18 +740,39 @@ static int init_mod( struct sr_module* m )
590 590
 		   propagate it up the stack
591 591
 		 */
592 592
 		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;
593
+		if (m->exports){
594
+			switch(m->mod_interface_ver){
595
+				case 0:
596
+					if ( m->exports->v0.init_f) {
597
+						DBG("DEBUG: init_mod: %s\n", m->exports->v0.name);
598
+						if (m->exports->v0.init_f()!=0) {
599
+							LOG(L_ERR, "init_mod(): Error while initializing"
600
+										" module %s\n", m->exports->v0.name);
601
+							return -1;
602
+						} else {
603
+							/* module correctly initialized */
604
+							return 0;
605
+						}
606
+					}
607
+					/* no init function -- proceed with success */
608
+					return 0;
609
+				case 1:
610
+					if ( m->exports->v1.init_f) {
611
+						DBG("DEBUG: init_mod: %s\n", m->exports->v1.name);
612
+						if (m->exports->v1.init_f()!=0) {
613
+							LOG(L_ERR, "init_mod(): Error while initializing"
614
+										" module %s\n", m->exports->v1.name);
615
+							return -1;
616
+						} else {
617
+							/* module correctly initialized */
618
+							return 0;
619
+						}
620
+					}
621
+					/* no init function -- proceed with success */
622
+					return 0;
602 623
 			}
603 624
 		}
604
-		/* no init function -- proceed with success */
625
+		/* no exports -- proceed with success */
605 626
 		return 0;
606 627
 	} else {
607 628
 		/* end of list */
... ...
@@ -619,8 +790,18 @@ int init_modules(void)
619 619
 	int i;
620 620
 	
621 621
 	for(t = modules; t; t = t->next)
622
-		if ( t->exports && t->exports->response_f)
623
-			mod_response_cbk_no++;
622
+		if (t->exports){
623
+			switch(t->mod_interface_ver){
624
+				case 0:
625
+					if (t->exports->v0.response_f)
626
+						mod_response_cbk_no++;
627
+					break;
628
+				case 1:
629
+					if (t->exports->v1.response_f)
630
+						mod_response_cbk_no++;
631
+					break;
632
+			}
633
+		}
624 634
 	mod_response_cbks=pkg_malloc(mod_response_cbk_no * 
625 635
 									sizeof(response_function));
626 636
 	if (mod_response_cbks==0){
... ...
@@ -629,9 +810,21 @@ int init_modules(void)
629 629
 		return -1;
630 630
 	}
631 631
 	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++;
632
+		if (t->exports){
633
+			switch(t->mod_interface_ver){
634
+				case 0:
635
+					if (t->exports->v0.response_f){
636
+						mod_response_cbks[i]=t->exports->v0.response_f;
637
+						i++;
638
+					}
639
+					break;
640
+				case 1:
641
+					if (t->exports->v1.response_f){
642
+						mod_response_cbks[i]=t->exports->v1.response_f;
643
+						i++;
644
+					}
645
+					break;
646
+			}
635 647
 		}
636 648
 	}
637 649
 	
... ...
@@ -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 53
 #include "route_struct.h"
54 54
 #include "str.h"
55 55
 
56
-typedef  struct module_exports* (*module_register)();
56
+/* kamailio compat */
57
+#include "statistics.h"
58
+#include "mi/mi.h"
59
+#include "pvar.h"
60
+
61
+
62
+
63
+#if defined KAMAILIO_MOD_INTERFACE || defined OPENSER_MOD_INTERFACE || \
64
+	defined MOD_INTERFACE_V1
65
+
66
+#define MODULE_INTERFACE_VER 1
67
+#define cmd_export_t kam_cmd_export_t
68
+#define module_exports kam_module_exports
69
+
70
+#elif defined SER_MOD_INTERFACE || defined MOD_INTERFACE_V0
71
+
72
+#define MODULE_INTERFACE_VER 0
73
+#define cmd_export_t ser_cmd_export_t
74
+#define module_exports ser_module_exports
75
+
76
+#else
77
+
78
+/* do nothing for core */
79
+
80
+#endif
81
+
82
+typedef  struct module_exports* (*module_register)(void);
57 83
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
58 84
 typedef  int (*fixup_function)(void** param, int param_no);
85
+typedef  int (*free_fixup_function)(void** param, int param_no);
59 86
 typedef  int (*response_function)(struct sip_msg*);
60 87
 typedef  void (*onbreak_function)(struct sip_msg*);
61
-typedef void (*destroy_function)();
88
+typedef void (*destroy_function)(void);
89
+
62 90
 typedef int (*init_function)(void);
63 91
 typedef int (*child_init_function)(int rank);
64 92
 
... ...
@@ -82,7 +118,8 @@ typedef int (*param_func_t)( modparam_t type, void* val);
82 82
 #define FAILURE_ROUTE 2  /* Function can be used in reply route blocks */
83 83
 #define ONREPLY_ROUTE 4  /* Function can be used in on_reply */
84 84
 #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 */
85
+#define ONSEND_ROUTE 16  /* Function can be used in onsend_route blocks */
86
+#define ERROR_ROUTE  32  /* Function can be used in an error route */ 
86 87
 
87 88
 /* Macros - used as rank in child_init function */
88 89
 #define PROC_MAIN      0  /* Main ser process */
... ...
@@ -107,11 +144,24 @@ typedef int (*param_func_t)( modparam_t type, void* val);
107 107
 
108 108
 #define PROC_MIN PROC_NOCHLDINIT /* Minimum process rank */
109 109
 
110
+
111
+#define DEFAULT_DLFLAGS	0 /* value that signals to module loader to
112
+							use default dlopen flags in Kamailio */
113
+#ifndef RTLD_NOW
114
+/* for openbsd */
115
+#define RTLD_NOW DL_LAZY
116
+#endif
117
+
118
+#define KAMAILIO_DLFLAGS	RTLD_NOW
119
+
120
+
110 121
 #define MODULE_VERSION \
111 122
 	char *module_version=SER_FULL_VERSION; \
112
-	char *module_flags=SER_COMPILE_FLAGS;
123
+	char *module_flags=SER_COMPILE_FLAGS; \
124
+	unsigned int module_interface_ver=MODULE_INTERFACE_VER; 
113 125
 
114
-struct cmd_export_ {
126
+/* ser version */
127
+struct ser_cmd_export_ {
115 128
 	char* name;             /* null terminated command name */
116 129
 	cmd_function function;  /* pointer to the corresponding function */
117 130
 	int param_no;           /* number of parameters used by the function */
... ...
@@ -121,6 +171,29 @@ struct cmd_export_ {
121 121
 };
122 122
 
123 123
 
124
+/* kamailo/openser version */
125
+struct kam_cmd_export_ {
126
+	char* name;             /* null terminated command name */
127
+	cmd_function function;  /* pointer to the corresponding function */
128
+	int param_no;           /* number of parameters used by the function */
129
+	fixup_function fixup;   /* pointer to the function called to "fix" the
130
+							   parameters */
131
+	free_fixup_function free_fixup; /* function called to free the "fixed"
132
+									   parameters */
133
+	int flags;              /* Function flags */
134
+};
135
+
136
+
137
+/* members situated at the same place in memory in both ser & kamailio
138
+   cmd_export */
139
+struct cmd_export_common_ {
140
+	char* name;
141
+	cmd_function function; 
142
+	int param_no;
143
+	fixup_function fixup;
144
+};
145
+
146
+
124 147
 struct param_export_ {
125 148
 	char* name;             /* null terminated param. name */
126 149
 	modparam_t type;        /* param. type */
... ...
@@ -157,18 +230,26 @@ typedef struct fparam {
157 157
 } fparam_t;
158 158
 
159 159
 
160
-typedef struct cmd_export_ cmd_export_t;
161
-typedef struct param_export_ param_export_t;
160
+typedef struct param_export_ param_export_t;  
161
+typedef struct ser_cmd_export_ ser_cmd_export_t;
162
+typedef struct kam_cmd_export_ kam_cmd_export_t;
163
+typedef struct cmd_export_common_ cmd_export_common_t;
162 164
 
163
-struct module_exports {
164
-	char* name;                     /* null terminated module name */
165
+union cmd_export_u{
166
+	cmd_export_common_t c; /* common members for everybody */
167
+	ser_cmd_export_t v0;
168
+	kam_cmd_export_t v1;
169
+};
165 170
 
166
-	cmd_export_t* cmds;             /* null terminated array of the exported
171
+
172
+/* ser module exports version */
173
+struct ser_module_exports {
174
+	char* name;                     /* null terminated module name */
175
+	ser_cmd_export_t* cmds;         /* null terminated array of the exported
167 176
 									   commands */
168 177
 	rpc_export_t* rpc_methods;      /* null terminated array of exported rpc methods */
169 178
 	param_export_t* params;         /* null terminated array of the exported
170 179
 									   module parameters */
171
-
172 180
 	init_function init_f;           /* Initialization function */
173 181
 	response_function response_f;   /* function used for responses,
174 182
 									   returns yes or no; can be null */
... ...
@@ -181,10 +262,69 @@ struct module_exports {
181 181
 };
182 182
 
183 183
 
184
+/* kamailio/openser proc_export (missing from ser) */
185
+typedef void (*mod_proc)(int no);
186
+
187
+typedef int (*mod_proc_wrapper)(void);
188
+
189
+struct proc_export_ {
190
+	char *name;
191
+	mod_proc_wrapper pre_fork_function;
192
+	mod_proc_wrapper post_fork_function;
193
+	mod_proc function;
194
+	unsigned int no;
195
+};
196
+
197
+typedef struct proc_export_ proc_export_t;
198
+
199
+
200
+/* kamailio/openser module exports version */
201
+struct kam_module_exports {
202
+	char* name;                     /* null terminated module name */
203
+	unsigned int dlflags;			/*!< flags for dlopen  */
204
+	kam_cmd_export_t* cmds;			/* null terminated array of the exported
205
+									   commands */
206
+	param_export_t* params;			/* null terminated array of the exported
207
+									   module parameters */
208
+	stat_export_t* stats;			/*!< null terminated array of the exported
209
+									  module statistics */
210
+	mi_export_t* mi_cmds;			/*!< null terminated array of the exported
211
+									  MI functions */
212
+	pv_export_t* items;				/*!< null terminated array of the exported
213
+									   module items (pseudo-variables) */
214
+	proc_export_t* procs;			/*!< null terminated array of the
215
+									  additional processes required by the
216
+									  module */
217
+	init_function init_f;           /* Initialization function */
218
+	response_function response_f;   /* function used for responses,
219
+									   returns yes or no; can be null */
220
+	destroy_function destroy_f;     /* function called when the module should
221
+									   be "destroyed", e.g: on ser exit;
222
+									   can be null */
223
+	child_init_function init_child_f;  /* function called by all processes
224
+										  after the fork */
225
+};
226
+
227
+
228
+
229
+/* module exports in the same place in memory in both ser & kamailio */
230
+struct module_exports_common{
231
+	char* name;
232
+};
233
+
234
+
235
+union module_exports_u {
236
+		struct module_exports_common c; /*common members for all the versions*/
237
+		struct ser_module_exports v0;
238
+		struct kam_module_exports v1;
239
+};
240
+
241
+
184 242
 struct sr_module{
185 243
 	char* path;
186 244
 	void* handle;
187
-	struct module_exports* exports;
245
+	unsigned int mod_interface_ver;
246
+	union module_exports_u* exports;
188 247
 	struct sr_module* next;
189 248
 };
190 249
 
... ...
@@ -193,19 +333,20 @@ extern struct sr_module* modules; /* global module list*/
193 193
 extern response_function* mod_response_cbks;/* response callback array */
194 194
 extern int mod_response_cbk_no;    /* size of reponse callbacks array */
195 195
 
196
-int register_builtin_modules();
197
-int register_module(struct module_exports*, char*,  void*);
196
+int register_builtin_modules(void);
197
+/*int register_module(unsigned , struct module_exports*, char*,  void*);*/
198 198
 int load_module(char* path);
199
-cmd_export_t* find_export_record(char* name, int param_no, int flags);
199
+union cmd_export_u* find_export_record(char* name, int param_no, int flags,
200
+										unsigned *ver);
200 201
 cmd_function find_export(char* name, int param_no, int flags);
201 202
 cmd_function find_mod_export(char* mod, char* name, int param_no, int flags);
202 203
 rpc_export_t* find_rpc_export(char* name, int flags);
203
-void destroy_modules();
204
+void destroy_modules(void);
204 205
 int init_child(int rank);
205 206
 int init_modules(void);
206 207
 struct sr_module* find_module_by_name(char* mod);
207 208
 
208
-/*
209
+/*! \brief
209 210
  * Find a parameter with given type and return it's
210 211
  * address in memory
211 212
  * 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 329
  * @return: 0 for success, negative on error.
330 330
  */
331 331
 int get_regex_fparam(regex_t *dst, struct sip_msg* msg, fparam_t* param);
332
+
333
+
334
+/* functions needed for kamailio/openser compatibility */
335
+
336
+/*! \brief Check if module is loaded
337
+ * \return Returns 1 if the module with name 'name' is loaded, and zero otherwise. */
338
+int module_loaded(char *name);
339
+
340
+/*! \brief Counts the additional the number of processes
341
+ requested by modules */
342
+int count_module_procs(void);
343
+
344
+
345
+/*! \brief Forks and starts the additional processes required by modules */
346
+int start_module_procs(void);
347
+
332 348
 #endif /* sr_module_h */
333 349
new file mode 100644
... ...
@@ -0,0 +1,72 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2008 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+/*
18
+ * statistics compatibility wrapper for kamailio
19
+ * for now it doesn't do anything
20
+ * (obsolete, do not use anymore)
21
+ *
22
+ * History:
23
+ * --------
24
+ *  2008-11-17  initial version compatible with kamailio statistics.h (andrei)
25
+ */
26
+
27
+#ifndef _STATISTICS_H_
28
+#define _STATISTICS_H_
29
+
30
+#include "str.h"
31
+
32
+#define STAT_NO_RESET  1
33
+#define STAT_NO_SYNC   2
34
+#define STAT_SHM_NAME  4
35
+#define STAT_IS_FUNC   8
36
+
37
+
38
+
39
+typedef unsigned int stat_val;
40
+typedef unsigned long (*stat_function)(void);
41
+
42
+typedef struct stat_var_{
43
+	unsigned int mod_idx;
44
+	str name;
45
+	int flags;
46
+	union{
47
+		stat_val *val;
48
+		stat_function f;
49
+	}u;
50
+	struct stat_var_ *hnext;
51
+	struct stat_var_ *lnext;
52
+} stat_var;
53
+
54
+
55
+typedef struct stat_export_ {
56
+	char* name;                /* null terminated statistic name */
57
+	int flags;                 /* flags */
58
+	stat_var** stat_pointer;   /* pointer to the variable's shm mem location */
59
+} stat_export_t;
60
+
61
+#define get_stat(name)  0
62
+#define get_stat_val(v) 0
63
+#define update_stat(v, n)
64
+#define reset_stat(v)
65
+#define if_update_stat (cond, v, n)
66
+
67
+#ifdef STATISTICS
68
+#warning "sorry sip-router does not support STATISTICS"
69
+#endif
70
+
71
+#endif /* _STATISTICS_H_ */