Module: sip-router Branch: tirpi/script_callbacks Commit: 0a99f1b390d57e236f989b8a496f751b9d5d26a6 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0a99f1b3...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@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