Browse code

script callbacks: support for all kind of route blocks

- Added pre- and post-script callback support
for all kind of route blocks.
- req/rpl is changed to be a flag, so more callback types
can be registered at once this way. The flag is passed to
the callback function.

Miklos Tirpak authored on 01/06/2009 11:13:45
Showing 3 changed files
... ...
@@ -1632,6 +1632,7 @@ int main(int argc, char** argv)
1632 1632
 	}
1633 1633
 	if (init_routes()<0) goto error;
1634 1634
 	if (init_nonsip_hooks()<0) goto error;
1635
+	if (init_script_cb()<0) goto error;
1635 1636
 	if (init_rpcs()<0) goto error;
1636 1637
 	if (register_core_rpcs()!=0) goto error;
1637 1638
 
... ...
@@ -34,6 +34,8 @@
34 34
  *  2003-03-29  cleaning pkg allocation introduced (jiri)
35 35
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
36 36
  *  2005-02-13  script callbacks devided into request and reply types (bogdan)
37
+ *  2009-06-01  Added pre- and post-script callback support for all types
38
+ *		of route blocks. (Miklos)
37 39
  */
38 40
 
39 41
 
... ...
@@ -43,15 +45,15 @@
43 45
 #include "error.h"
44 46
 #include "mem/mem.h"
45 47
 
46
-static struct script_cb *pre_req_cb=0;
47
-static struct script_cb *post_req_cb=0;
48
-
49
-static struct script_cb *pre_rpl_cb=0;
50
-static struct script_cb *post_rpl_cb=0;
51
-
52
-static unsigned int cb_id=0;
48
+/* Number of cb types = last cb type */
49
+#define SCRIPT_CB_NUM	EVENT_CB_TYPE
53 50
 
51
+static struct script_cb *pre_script_cb[SCRIPT_CB_NUM];
52
+static struct script_cb *post_script_cb[SCRIPT_CB_NUM];
54 53
 
54
+/* Add a script callback to the beginning of the linked list.
55
+ * Returns -1 on error
56
+ */
55 57
 static inline int add_callback( struct script_cb **list,
56 58
 	cb_function f, void *param)
57 59
 {
... ...
@@ -59,11 +61,10 @@ static inline int add_callback( struct script_cb **list,
59 61
 
60 62
 	new_cb=pkg_malloc(sizeof(struct script_cb));
61 63
 	if (new_cb==0) {
62
-		LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
64
+		LOG(L_CRIT, "add_script_callback: out of memory\n");
63 65
 		return -1;
64 66
 	}
65 67
 	new_cb->cbf = f;
66
-	new_cb->id = cb_id++;
67 68
 	new_cb->param = param;
68 69
 	/* link at the beginning of the list */
69 70
 	new_cb->next = *list;
... ...
@@ -71,50 +72,58 @@ static inline int add_callback( struct script_cb **list,
71 72
 	return 0;
72 73
 }
73 74
 
74
-
75
-int register_script_cb( cb_function f, int type, void *param )
75
+/* Register pre- or post-script callbacks.
76
+ * Returns -1 on error, 0 on success
77
+ */
78
+int register_script_cb( cb_function f, unsigned int flags, void *param )
76 79
 {
80
+	struct script_cb	**cb_array;
81
+	int	i;
82
+
77 83
 	/* type checkings */
78
-	if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
79
-		LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
80
-			"type not specified\n");
81
-		goto error;
84
+	if ( (flags&((1<<SCRIPT_CB_NUM)-1))==0 ) {
85
+		LOG(L_BUG, "register_script_cb: callback flag not specified\n");
86
+		return -1;
87
+	}
88
+	if ( (flags&(~(PRE_SCRIPT_CB|POST_SCRIPT_CB))) >= 1<<SCRIPT_CB_NUM ) {
89
+		LOG(L_BUG, "register_script_cb: unsupported callback flags: %u\n",
90
+			flags);
91
+		return -1;
82 92
 	}
83
-	if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
84
-	(type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
85
-		LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
93
+	if ( (flags&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
94
+	(flags&PRE_SCRIPT_CB && flags&POST_SCRIPT_CB) ) {
95
+		LOG(L_BUG, "register_script_cb: callback POST or PRE type must "
86 96
 			"be exactly one\n");
87
-		goto error;
97
+		return -1;
88 98
 	}
89 99
 
90
-	if (type&REQ_TYPE_CB) {
91
-		/* callback for request script */
92
-		if (type&PRE_SCRIPT_CB) {
93
-			if (add_callback( &pre_req_cb, f, param)<0)
94
-				goto add_error;
95
-		} else if (type&POST_SCRIPT_CB) {
96
-			if (add_callback( &post_req_cb, f, param)<0)
97
-				goto add_error;
98
-		}
99
-	}
100
-	if (type&RPL_TYPE_CB) {
101
-		/* callback (also) for reply script */
102
-		if (type&PRE_SCRIPT_CB) {
103
-			if (add_callback( &pre_rpl_cb, f, param)<0)
104
-				goto add_error;
105
-		} else if (type&POST_SCRIPT_CB) {
106
-			if (add_callback( &post_rpl_cb, f, param)<0)
107
-				goto add_error;
108
-		}
100
+	if (flags&PRE_SCRIPT_CB)
101
+		cb_array = pre_script_cb;
102
+	else
103
+		cb_array = post_script_cb;
104
+
105
+	/* Add the callback to the lists.
106
+	 * (as many times as many flags are set)
107
+	 */
108
+	for (i=0; i<SCRIPT_CB_NUM; i++) {
109
+		if ((flags&(1<<i)) == 0)
110
+			continue;
111
+		if (add_callback(&cb_array[i], f, param) < 0)
112
+			goto add_error;
109 113
 	}
110
-
111 114
 	return 0;
115
+
112 116
 add_error:
113
-	LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
114
-error:
117
+	LOG(L_ERR,"register_script_cb: failed to add callback\n");
115 118
 	return -1;
116 119
 }
117 120
 
121
+int init_script_cb()
122
+{
123
+	memset(pre_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
124
+	memset(post_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
125
+	return 0;
126
+}
118 127
 
119 128
 static inline void destroy_cb_list(struct script_cb **list)
120 129
 {
... ...
@@ -127,53 +136,56 @@ static inline void destroy_cb_list(struct script_cb **list)
127 136
 	}
128 137
 }
129 138
 
130
-
131 139
 void destroy_script_cb()
132 140
 {
133
-	destroy_cb_list( &pre_req_cb  );
134
-	destroy_cb_list( &post_req_cb );
135
-	destroy_cb_list( &pre_rpl_cb  );
136
-	destroy_cb_list( &post_req_cb );
137
-}
141
+	int	i;
138 142
 
143
+	for (i=0; i<SCRIPT_CB_NUM; i++) {
144
+		destroy_cb_list(&pre_script_cb[i]);
145
+		destroy_cb_list(&post_script_cb[i]);
146
+	}
147
+}
139 148
 
140
-static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
149
+/* Execute pre-script callbacks of a given type.
150
+ * Returns 0 on error, 1 on success
151
+ */
152
+int exec_pre_script_cb( struct sip_msg *msg, enum script_cb_type type)
141 153
 {
142
-	for ( ; cb ; cb=cb->next ) {
154
+	struct script_cb	*cb;
155
+	unsigned int	flags;
156
+
157
+#ifdef EXTRA_DEBUG
158
+	if (type >= SCRIPT_CB_NUM) {
159
+		LOG(L_BUG, "exec_pre_script_cb: Uknown callback type\n");
160
+		abort();
161
+	}
162
+#endif
163
+	flags = PRE_SCRIPT_CB & (1<<(type-1));
164
+	for (cb=pre_script_cb[type]; cb ; cb=cb->next ) {
143 165
 		/* stop on error */
144
-		if (cb->cbf(msg, cb->param)==0)
166
+		if (cb->cbf(msg, flags, cb->param)==0)
145 167
 			return 0;
146 168
 	}
147 169
 	return 1;
148 170
 }
149 171
 
150
-
151
-static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
172
+/* Execute post-script callbacks of a given type.
173
+ * Always returns 1, success.
174
+ */
175
+int exec_post_script_cb( struct sip_msg *msg, enum script_cb_type type)
152 176
 {
153
-	for ( ; cb ; cb=cb->next){
154
-		cb->cbf( msg, cb->param);
177
+	struct script_cb	*cb;
178
+	unsigned int	flags;
179
+
180
+#ifdef EXTRA_DEBUG
181
+	if (type >= SCRIPT_CB_NUM) {
182
+		LOG(L_BUG, "exec_pre_script_cb: Uknown callback type\n");
183
+		abort();
184
+	}
185
+#endif
186
+	flags = POST_SCRIPT_CB & (1<<(type-1));
187
+	for (cb=post_script_cb[type]; cb ; cb=cb->next){
188
+		cb->cbf(msg, flags, cb->param);
155 189
 	}
156 190
 	return 1;
157 191
 }
158
-
159
-
160
-int exec_pre_req_cb( struct sip_msg *msg)
161
-{
162
-	return exec_pre_cb( msg, pre_req_cb);
163
-}
164
-
165
-int exec_pre_rpl_cb( struct sip_msg *msg)
166
-{
167
-	return exec_pre_cb( msg, pre_rpl_cb);
168
-}
169
-
170
-int exec_post_req_cb( struct sip_msg *msg)
171
-{
172
-	return exec_post_cb( msg, post_req_cb);
173
-}
174
-
175
-int exec_post_rpl_cb( struct sip_msg *msg)
176
-{
177
-	return exec_post_cb( msg, post_rpl_cb);
178
-}
179
-
... ...
@@ -27,6 +27,8 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2005-02-13  script callbacks devided into request and reply types (bogdan)
30
+ *  2009-06-01  Added pre- and post-script callback support for all types
31
+ *		of route blocks. (Miklos)
30 32
  */
31 33
 
32 34
 #ifndef _SCRIPT_CB_H_
... ...
@@ -34,30 +36,51 @@
34 36
 
35 37
 #include "parser/msg_parser.h"
36 38
 
37
-typedef int (cb_function)( struct sip_msg *msg, void *param );
39
+typedef int (cb_function)(struct sip_msg *msg, unsigned int flags, void *param);
38 40
 
39 41
 
40
-#define PRE_SCRIPT_CB    (1<<0)
41
-#define POST_SCRIPT_CB   (1<<1)
42
-#define REQ_TYPE_CB      (1<<2)
43
-#define RPL_TYPE_CB      (1<<3)
42
+#define PRE_SCRIPT_CB    (1<<30)
43
+#define POST_SCRIPT_CB   (1<<31)
44 44
 
45
+/* Pre- and post-script callback flags. Use these flags to register
46
+ * for the callbacks, and to check the type of the callback from the
47
+ * functions.
48
+ * (Power of 2 so more callbacks can be registered at once.)
49
+ */
50
+enum script_cb_flag { REQUEST_CB=1, FAILURE_CB=2, ONREPLY_CB=4,
51
+			BRANCH_CB=8, ONSEND_CB=16, ERROR_CB=32,
52
+			LOCAL_CB=64, EVENT_CB=128 };
53
+
54
+/* Callback types used for executing the callbacks.
55
+ * Keep in sync with script_cb_flag!!!
56
+ */
57
+enum script_cb_type { REQUEST_CB_TYPE=1, FAILURE_CB_TYPE, ONREPLY_CB_TYPE,
58
+			BRANCH_CB_TYPE, ONSEND_CB_TYPE, ERROR_CB_TYPE,
59
+			LOCAL_CB_TYPE, EVENT_CB_TYPE };
45 60
 
46 61
 struct script_cb{
47 62
 	cb_function *cbf;
48 63
 	struct script_cb *next;
49
-	unsigned int id;
50 64
 	void *param;
51 65
 };
52 66
 
53
-int register_script_cb( cb_function f, int type, void *param );
67
+/* Register pre- or post-script callbacks.
68
+ * Returns -1 on error, 0 on success
69
+ */
70
+int register_script_cb( cb_function f, unsigned int flags, void *param );
71
+
72
+int init_script_cb();
54 73
 void destroy_script_cb();
55 74
 
56
-int exec_pre_req_cb( struct sip_msg *msg);
57
-int exec_post_req_cb( struct sip_msg *msg);
75
+/* Execute pre-script callbacks of a given type.
76
+ * Returns 0 on error, 1 on success
77
+ */
78
+int exec_pre_script_cb( struct sip_msg *msg, enum script_cb_type type);
58 79
 
59
-int exec_pre_rpl_cb( struct sip_msg *msg);
60
-int exec_post_rpl_cb( struct sip_msg *msg);
80
+/* Execute post-script callbacks of a given type.
81
+ * Always returns 1, success.
82
+ */
83
+int exec_post_script_cb( struct sip_msg *msg, enum script_cb_type type);
61 84
 
62 85
 #endif
63 86