[sr-dev] git:tirpi/script_callbacks: script callbacks: support for all kind of route blocks

Miklos Tirpak miklos at iptel.org
Mon Jun 1 15:26:07 CEST 2009


Module: sip-router
Branch: tirpi/script_callbacks
Commit: 0a99f1b390d57e236f989b8a496f751b9d5d26a6
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0a99f1b390d57e236f989b8a496f751b9d5d26a6

Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at iptel.org>
Date:   Mon Jun  1 13:13:45 2009 +0200

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.

---

 main.c      |    1 +
 script_cb.c |  164 +++++++++++++++++++++++++++++++---------------------------
 script_cb.h |   45 ++++++++++++----
 3 files changed, 123 insertions(+), 87 deletions(-)

diff --git a/main.c b/main.c
index 235d66e..d3329c5 100644
--- a/main.c
+++ b/main.c
@@ -1632,6 +1632,7 @@ int main(int argc, char** argv)
 	}
 	if (init_routes()<0) goto error;
 	if (init_nonsip_hooks()<0) goto error;
+	if (init_script_cb()<0) goto error;
 	if (init_rpcs()<0) goto error;
 	if (register_core_rpcs()!=0) goto error;
 
diff --git a/script_cb.c b/script_cb.c
index 5099745..729eda4 100644
--- a/script_cb.c
+++ b/script_cb.c
@@ -34,6 +34,8 @@
  *  2003-03-29  cleaning pkg allocation introduced (jiri)
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
  *  2005-02-13  script callbacks devided into request and reply types (bogdan)
+ *  2009-06-01  Added pre- and post-script callback support for all types
+ *		of route blocks. (Miklos)
  */
 
 
@@ -43,15 +45,15 @@
 #include "error.h"
 #include "mem/mem.h"
 
-static struct script_cb *pre_req_cb=0;
-static struct script_cb *post_req_cb=0;
-
-static struct script_cb *pre_rpl_cb=0;
-static struct script_cb *post_rpl_cb=0;
-
-static unsigned int cb_id=0;
+/* Number of cb types = last cb type */
+#define SCRIPT_CB_NUM	EVENT_CB_TYPE
 
+static struct script_cb *pre_script_cb[SCRIPT_CB_NUM];
+static struct script_cb *post_script_cb[SCRIPT_CB_NUM];
 
+/* Add a script callback to the beginning of the linked list.
+ * Returns -1 on error
+ */
 static inline int add_callback( struct script_cb **list,
 	cb_function f, void *param)
 {
@@ -59,11 +61,10 @@ static inline int add_callback( struct script_cb **list,
 
 	new_cb=pkg_malloc(sizeof(struct script_cb));
 	if (new_cb==0) {
-		LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
+		LOG(L_CRIT, "add_script_callback: out of memory\n");
 		return -1;
 	}
 	new_cb->cbf = f;
-	new_cb->id = cb_id++;
 	new_cb->param = param;
 	/* link at the beginning of the list */
 	new_cb->next = *list;
@@ -71,50 +72,58 @@ static inline int add_callback( struct script_cb **list,
 	return 0;
 }
 
-
-int register_script_cb( cb_function f, int type, void *param )
+/* Register pre- or post-script callbacks.
+ * Returns -1 on error, 0 on success
+ */
+int register_script_cb( cb_function f, unsigned int flags, void *param )
 {
+	struct script_cb	**cb_array;
+	int	i;
+
 	/* type checkings */
-	if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
-		LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
-			"type not specified\n");
-		goto error;
+	if ( (flags&((1<<SCRIPT_CB_NUM)-1))==0 ) {
+		LOG(L_BUG, "register_script_cb: callback flag not specified\n");
+		return -1;
+	}
+	if ( (flags&(~(PRE_SCRIPT_CB|POST_SCRIPT_CB))) >= 1<<SCRIPT_CB_NUM ) {
+		LOG(L_BUG, "register_script_cb: unsupported callback flags: %u\n",
+			flags);
+		return -1;
 	}
-	if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
-	(type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
-		LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
+	if ( (flags&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
+	(flags&PRE_SCRIPT_CB && flags&POST_SCRIPT_CB) ) {
+		LOG(L_BUG, "register_script_cb: callback POST or PRE type must "
 			"be exactly one\n");
-		goto error;
+		return -1;
 	}
 
-	if (type&REQ_TYPE_CB) {
-		/* callback for request script */
-		if (type&PRE_SCRIPT_CB) {
-			if (add_callback( &pre_req_cb, f, param)<0)
-				goto add_error;
-		} else if (type&POST_SCRIPT_CB) {
-			if (add_callback( &post_req_cb, f, param)<0)
-				goto add_error;
-		}
-	}
-	if (type&RPL_TYPE_CB) {
-		/* callback (also) for reply script */
-		if (type&PRE_SCRIPT_CB) {
-			if (add_callback( &pre_rpl_cb, f, param)<0)
-				goto add_error;
-		} else if (type&POST_SCRIPT_CB) {
-			if (add_callback( &post_rpl_cb, f, param)<0)
-				goto add_error;
-		}
+	if (flags&PRE_SCRIPT_CB)
+		cb_array = pre_script_cb;
+	else
+		cb_array = post_script_cb;
+
+	/* Add the callback to the lists.
+	 * (as many times as many flags are set)
+	 */
+	for (i=0; i<SCRIPT_CB_NUM; i++) {
+		if ((flags&(1<<i)) == 0)
+			continue;
+		if (add_callback(&cb_array[i], f, param) < 0)
+			goto add_error;
 	}
-
 	return 0;
+
 add_error:
-	LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
-error:
+	LOG(L_ERR,"register_script_cb: failed to add callback\n");
 	return -1;
 }
 
+int init_script_cb()
+{
+	memset(pre_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
+	memset(post_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
+	return 0;
+}
 
 static inline void destroy_cb_list(struct script_cb **list)
 {
@@ -127,53 +136,56 @@ static inline void destroy_cb_list(struct script_cb **list)
 	}
 }
 
-
 void destroy_script_cb()
 {
-	destroy_cb_list( &pre_req_cb  );
-	destroy_cb_list( &post_req_cb );
-	destroy_cb_list( &pre_rpl_cb  );
-	destroy_cb_list( &post_req_cb );
-}
+	int	i;
 
+	for (i=0; i<SCRIPT_CB_NUM; i++) {
+		destroy_cb_list(&pre_script_cb[i]);
+		destroy_cb_list(&post_script_cb[i]);
+	}
+}
 
-static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
+/* Execute pre-script callbacks of a given type.
+ * Returns 0 on error, 1 on success
+ */
+int exec_pre_script_cb( struct sip_msg *msg, enum script_cb_type type)
 {
-	for ( ; cb ; cb=cb->next ) {
+	struct script_cb	*cb;
+	unsigned int	flags;
+
+#ifdef EXTRA_DEBUG
+	if (type >= SCRIPT_CB_NUM) {
+		LOG(L_BUG, "exec_pre_script_cb: Uknown callback type\n");
+		abort();
+	}
+#endif
+	flags = PRE_SCRIPT_CB & (1<<(type-1));
+	for (cb=pre_script_cb[type]; cb ; cb=cb->next ) {
 		/* stop on error */
-		if (cb->cbf(msg, cb->param)==0)
+		if (cb->cbf(msg, flags, cb->param)==0)
 			return 0;
 	}
 	return 1;
 }
 
-
-static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
+/* Execute post-script callbacks of a given type.
+ * Always returns 1, success.
+ */
+int exec_post_script_cb( struct sip_msg *msg, enum script_cb_type type)
 {
-	for ( ; cb ; cb=cb->next){
-		cb->cbf( msg, cb->param);
+	struct script_cb	*cb;
+	unsigned int	flags;
+
+#ifdef EXTRA_DEBUG
+	if (type >= SCRIPT_CB_NUM) {
+		LOG(L_BUG, "exec_pre_script_cb: Uknown callback type\n");
+		abort();
+	}
+#endif
+	flags = POST_SCRIPT_CB & (1<<(type-1));
+	for (cb=post_script_cb[type]; cb ; cb=cb->next){
+		cb->cbf(msg, flags, cb->param);
 	}
 	return 1;
 }
-
-
-int exec_pre_req_cb( struct sip_msg *msg)
-{
-	return exec_pre_cb( msg, pre_req_cb);
-}
-
-int exec_pre_rpl_cb( struct sip_msg *msg)
-{
-	return exec_pre_cb( msg, pre_rpl_cb);
-}
-
-int exec_post_req_cb( struct sip_msg *msg)
-{
-	return exec_post_cb( msg, post_req_cb);
-}
-
-int exec_post_rpl_cb( struct sip_msg *msg)
-{
-	return exec_post_cb( msg, post_rpl_cb);
-}
-
diff --git a/script_cb.h b/script_cb.h
index 0c81028..eb455a2 100644
--- a/script_cb.h
+++ b/script_cb.h
@@ -27,6 +27,8 @@
  * History:
  * --------
  *  2005-02-13  script callbacks devided into request and reply types (bogdan)
+ *  2009-06-01  Added pre- and post-script callback support for all types
+ *		of route blocks. (Miklos)
  */
 
 #ifndef _SCRIPT_CB_H_
@@ -34,30 +36,51 @@
 
 #include "parser/msg_parser.h"
 
-typedef int (cb_function)( struct sip_msg *msg, void *param );
+typedef int (cb_function)(struct sip_msg *msg, unsigned int flags, void *param);
 
 
-#define PRE_SCRIPT_CB    (1<<0)
-#define POST_SCRIPT_CB   (1<<1)
-#define REQ_TYPE_CB      (1<<2)
-#define RPL_TYPE_CB      (1<<3)
+#define PRE_SCRIPT_CB    (1<<30)
+#define POST_SCRIPT_CB   (1<<31)
 
+/* Pre- and post-script callback flags. Use these flags to register
+ * for the callbacks, and to check the type of the callback from the
+ * functions.
+ * (Power of 2 so more callbacks can be registered at once.)
+ */
+enum script_cb_flag { REQUEST_CB=1, FAILURE_CB=2, ONREPLY_CB=4,
+			BRANCH_CB=8, ONSEND_CB=16, ERROR_CB=32,
+			LOCAL_CB=64, EVENT_CB=128 };
+
+/* Callback types used for executing the callbacks.
+ * Keep in sync with script_cb_flag!!!
+ */
+enum script_cb_type { REQUEST_CB_TYPE=1, FAILURE_CB_TYPE, ONREPLY_CB_TYPE,
+			BRANCH_CB_TYPE, ONSEND_CB_TYPE, ERROR_CB_TYPE,
+			LOCAL_CB_TYPE, EVENT_CB_TYPE };
 
 struct script_cb{
 	cb_function *cbf;
 	struct script_cb *next;
-	unsigned int id;
 	void *param;
 };
 
-int register_script_cb( cb_function f, int type, void *param );
+/* Register pre- or post-script callbacks.
+ * Returns -1 on error, 0 on success
+ */
+int register_script_cb( cb_function f, unsigned int flags, void *param );
+
+int init_script_cb();
 void destroy_script_cb();
 
-int exec_pre_req_cb( struct sip_msg *msg);
-int exec_post_req_cb( struct sip_msg *msg);
+/* Execute pre-script callbacks of a given type.
+ * Returns 0 on error, 1 on success
+ */
+int exec_pre_script_cb( struct sip_msg *msg, enum script_cb_type type);
 
-int exec_pre_rpl_cb( struct sip_msg *msg);
-int exec_post_rpl_cb( struct sip_msg *msg);
+/* Execute post-script callbacks of a given type.
+ * Always returns 1, success.
+ */
+int exec_post_script_cb( struct sip_msg *msg, enum script_cb_type type);
 
 #endif
 




More information about the sr-dev mailing list