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