00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <stdlib.h>
00041 #include "script_cb.h"
00042 #include "dprint.h"
00043 #include "error.h"
00044 #include "mem/mem.h"
00045
00046 static struct script_cb *pre_req_cb=0;
00047 static struct script_cb *post_req_cb=0;
00048
00049 static struct script_cb *pre_rpl_cb=0;
00050 static struct script_cb *post_rpl_cb=0;
00051
00052 static unsigned int cb_id=0;
00053
00054
00055 static inline int add_callback( struct script_cb **list,
00056 cb_function f, void *param)
00057 {
00058 struct script_cb *new_cb;
00059
00060 new_cb=pkg_malloc(sizeof(struct script_cb));
00061 if (new_cb==0) {
00062 LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
00063 return -1;
00064 }
00065 new_cb->cbf = f;
00066 new_cb->id = cb_id++;
00067 new_cb->param = param;
00068
00069 new_cb->next = *list;
00070 *list = new_cb;
00071 return 0;
00072 }
00073
00074
00075 int register_script_cb( cb_function f, int type, void *param )
00076 {
00077
00078 if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
00079 LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
00080 "type not specified\n");
00081 goto error;
00082 }
00083 if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
00084 (type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
00085 LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
00086 "be exactly one\n");
00087 goto error;
00088 }
00089
00090 if (type&REQ_TYPE_CB) {
00091
00092 if (type&PRE_SCRIPT_CB) {
00093 if (add_callback( &pre_req_cb, f, param)<0)
00094 goto add_error;
00095 } else if (type&POST_SCRIPT_CB) {
00096 if (add_callback( &post_req_cb, f, param)<0)
00097 goto add_error;
00098 }
00099 }
00100 if (type&RPL_TYPE_CB) {
00101
00102 if (type&PRE_SCRIPT_CB) {
00103 if (add_callback( &pre_rpl_cb, f, param)<0)
00104 goto add_error;
00105 } else if (type&POST_SCRIPT_CB) {
00106 if (add_callback( &post_rpl_cb, f, param)<0)
00107 goto add_error;
00108 }
00109 }
00110
00111 return 0;
00112 add_error:
00113 LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
00114 error:
00115 return -1;
00116 }
00117
00118
00119 static inline void destroy_cb_list(struct script_cb **list)
00120 {
00121 struct script_cb *foo;
00122
00123 while( *list ) {
00124 foo = *list;
00125 *list = (*list)->next;
00126 pkg_free( foo );
00127 }
00128 }
00129
00130
00131 void destroy_script_cb()
00132 {
00133 destroy_cb_list( &pre_req_cb );
00134 destroy_cb_list( &post_req_cb );
00135 destroy_cb_list( &pre_rpl_cb );
00136 destroy_cb_list( &post_req_cb );
00137 }
00138
00139
00140 static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
00141 {
00142 for ( ; cb ; cb=cb->next ) {
00143
00144 if (cb->cbf(msg, cb->param)==0)
00145 return 0;
00146 }
00147 return 1;
00148 }
00149
00150
00151 static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
00152 {
00153 for ( ; cb ; cb=cb->next){
00154 cb->cbf( msg, cb->param);
00155 }
00156 return 1;
00157 }
00158
00159
00160 int exec_pre_req_cb( struct sip_msg *msg)
00161 {
00162 return exec_pre_cb( msg, pre_req_cb);
00163 }
00164
00165 int exec_pre_rpl_cb( struct sip_msg *msg)
00166 {
00167 return exec_pre_cb( msg, pre_rpl_cb);
00168 }
00169
00170 int exec_post_req_cb( struct sip_msg *msg)
00171 {
00172 return exec_post_cb( msg, post_req_cb);
00173 }
00174
00175 int exec_post_rpl_cb( struct sip_msg *msg)
00176 {
00177 return exec_post_cb( msg, post_rpl_cb);
00178 }
00179