00001
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <sys/types.h>
00027 #include <sys/ipc.h>
00028 #include <unistd.h>
00029 #include <fcntl.h>
00030
00031 #include "../../sr_module.h"
00032 #include "../../timer.h"
00033 #include "../../dprint.h"
00034 #include "../../route.h"
00035 #include "../../receive.h"
00036 #include "../../action.h"
00037 #include "../../socket_info.h"
00038 #include "../../dset.h"
00039 #include "../../pt.h"
00040 #include "../../timer_proc.h"
00041 #include "../../script_cb.h"
00042 #include "../../parser/parse_param.h"
00043 #include "../../lib/kcore/faked_msg.h"
00044
00045
00046 MODULE_VERSION
00047
00048 typedef struct _stm_route {
00049 str timer;
00050 unsigned int route;
00051 struct _stm_route *next;
00052 } stm_route_t;
00053
00054 typedef struct _stm_timer {
00055 str name;
00056 unsigned int mode;
00057 unsigned int flags;
00058 unsigned int interval;
00059 stm_route_t *rt;
00060 struct _stm_timer *next;
00061 } stm_timer_t;
00062
00063 #define RTIMER_INTERVAL_USEC (1<<0)
00064
00065 stm_timer_t *_stm_list = NULL;
00066
00068 static int mod_init(void);
00069 static int child_init(int);
00070
00071 int stm_t_param(modparam_t type, void* val);
00072 int stm_e_param(modparam_t type, void* val);
00073 void stm_timer_exec(unsigned int ticks, void *param);
00074
00075
00076 static param_export_t params[]={
00077 {"timer", STR_PARAM|USE_FUNC_PARAM, (void*)stm_t_param},
00078 {"exec", STR_PARAM|USE_FUNC_PARAM, (void*)stm_e_param},
00079 {0,0,0}
00080 };
00081
00082
00084 struct module_exports exports= {
00085 "rtimer",
00086 DEFAULT_DLFLAGS,
00087 0,
00088 params,
00089 0,
00090 0,
00091 0,
00092 0,
00093 mod_init,
00094 0,
00095 0,
00096 child_init
00097 };
00098
00099
00103 static int mod_init(void)
00104 {
00105 stm_timer_t *it;
00106 if(_stm_list==NULL)
00107 return 0;
00108
00109
00110 if(faked_msg_init()<0)
00111 {
00112 LM_ERR("failed to init timer local sip msg\n");
00113 return -1;
00114 }
00115
00116
00117 it = _stm_list;
00118 while(it)
00119 {
00120 if(it->mode==0)
00121 {
00122 if(register_timer(stm_timer_exec, (void*)it, it->interval)<0)
00123 {
00124 LM_ERR("failed to register timer function\n");
00125 return -1;
00126 }
00127 } else {
00128 register_basic_timers(1);
00129 }
00130 it = it->next;
00131 }
00132
00133 return 0;
00134 }
00135
00136 static int child_init(int rank)
00137 {
00138 stm_timer_t *it;
00139 if(_stm_list==NULL)
00140 return 0;
00141
00142 if (rank!=PROC_MAIN)
00143 return 0;
00144
00145 it = _stm_list;
00146 while(it)
00147 {
00148 if(it->mode!=0)
00149 {
00150 if(it->flags & RTIMER_INTERVAL_USEC)
00151 {
00152 if(fork_basic_utimer(PROC_TIMER, "RTIMER USEC EXEC", 1 ,
00153 stm_timer_exec, (void*)it, it->interval
00154 )<0) {
00155 LM_ERR("failed to start utimer routine as process\n");
00156 return -1;
00157 }
00158 } else {
00159 if(fork_basic_timer(PROC_TIMER, "RTIMER SEC EXEC", 1 ,
00160 stm_timer_exec, (void*)it, it->interval
00161 )<0) {
00162 LM_ERR("failed to start timer routine as process\n");
00163 return -1;
00164 }
00165 }
00166 }
00167 it = it->next;
00168 }
00169
00170 return 0;
00171 }
00172
00173 void stm_timer_exec(unsigned int ticks, void *param)
00174 {
00175 stm_timer_t *it;
00176 stm_route_t *rt;
00177 sip_msg_t *fmsg;
00178
00179 if(param==NULL)
00180 return;
00181 it = (stm_timer_t*)param;
00182 if(it->rt==NULL)
00183 return;
00184
00185 for(rt=it->rt; rt; rt=rt->next)
00186 {
00187 fmsg = faked_msg_next();
00188 if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)==0 )
00189 continue;
00190 set_route_type(REQUEST_ROUTE);
00191 run_top_route(main_rt.rlist[rt->route], fmsg, 0);
00192 exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
00193 }
00194 }
00195
00196 int stm_t_param(modparam_t type, void *val)
00197 {
00198 param_t* params_list = NULL;
00199 param_hooks_t phooks;
00200 param_t *pit=NULL;
00201 stm_timer_t tmp;
00202 stm_timer_t *nt;
00203 str s;
00204
00205 if(val==NULL)
00206 return -1;
00207 s.s = (char*)val;
00208 s.len = strlen(s.s);
00209 if(s.s[s.len-1]==';')
00210 s.len--;
00211 if (parse_params(&s, CLASS_ANY, &phooks, ¶ms_list)<0)
00212 return -1;
00213 memset(&tmp, 0, sizeof(stm_timer_t));
00214 for (pit = params_list; pit; pit=pit->next)
00215 {
00216 if (pit->name.len==4
00217 && strncasecmp(pit->name.s, "name", 4)==0) {
00218 tmp.name = pit->body;
00219 } else if(pit->name.len==4
00220 && strncasecmp(pit->name.s, "mode", 4)==0) {
00221 if(tmp.mode==0)
00222 str2int(&pit->body, &tmp.mode);
00223 } else if(pit->name.len==8
00224 && strncasecmp(pit->name.s, "interval", 8)==0) {
00225 if(pit->body.s[pit->body.len-1]=='u'
00226 || pit->body.s[pit->body.len-1]=='U') {
00227 pit->body.len--;
00228 tmp.flags |= RTIMER_INTERVAL_USEC;
00229 tmp.mode = 1;
00230 }
00231 str2int(&pit->body, &tmp.interval);
00232 }
00233 }
00234 if(tmp.name.s==NULL)
00235 {
00236 LM_ERR("invalid timer name\n");
00237 free_params(params_list);
00238 return -1;
00239 }
00240
00241 nt = _stm_list;
00242 while(nt) {
00243 if(nt->name.len==tmp.name.len
00244 && strncasecmp(nt->name.s, tmp.name.s, tmp.name.len)==0)
00245 break;
00246 nt = nt->next;
00247 }
00248 if(nt!=NULL)
00249 {
00250 LM_ERR("duplicate timer with same name: %.*s\n",
00251 tmp.name.len, tmp.name.s);
00252 free_params(params_list);
00253 return -1;
00254 }
00255 if(tmp.interval==0)
00256 tmp.interval = 120;
00257
00258 nt = (stm_timer_t*)pkg_malloc(sizeof(stm_timer_t));
00259 if(nt==0)
00260 {
00261 LM_ERR("no more pkg memory\n");
00262 free_params(params_list);
00263 return -1;
00264 }
00265 memcpy(nt, &tmp, sizeof(stm_timer_t));
00266 nt->next = _stm_list;
00267 _stm_list = nt;
00268 free_params(params_list);
00269 return 0;
00270 }
00271
00272 int stm_e_param(modparam_t type, void *val)
00273 {
00274 param_t* params_list = NULL;
00275 param_hooks_t phooks;
00276 param_t *pit=NULL;
00277 stm_route_t tmp;
00278 stm_route_t *rt;
00279 stm_timer_t *nt;
00280 str s;
00281 char c;
00282
00283 if(val==NULL)
00284 return -1;
00285 s.s = (char*)val;
00286 s.len = strlen(s.s);
00287 if(s.s[s.len-1]==';')
00288 s.len--;
00289 if (parse_params(&s, CLASS_ANY, &phooks, ¶ms_list)<0)
00290 return -1;
00291 memset(&tmp, 0, sizeof(stm_route_t));
00292 for (pit = params_list; pit; pit=pit->next)
00293 {
00294 if (pit->name.len==5
00295 && strncasecmp(pit->name.s, "timer", 5)==0) {
00296 tmp.timer = pit->body;
00297 } else if(pit->name.len==5
00298 && strncasecmp(pit->name.s, "route", 5)==0) {
00299 s = pit->body;
00300 }
00301 }
00302 if(tmp.timer.s==NULL)
00303 {
00304 LM_ERR("invalid timer name\n");
00305 free_params(params_list);
00306 return -1;
00307 }
00308
00309 nt = _stm_list;
00310 while(nt) {
00311 if(nt->name.len==tmp.timer.len
00312 && strncasecmp(nt->name.s, tmp.timer.s, tmp.timer.len)==0)
00313 break;
00314 nt = nt->next;
00315 }
00316 if(nt==NULL)
00317 {
00318 LM_ERR("timer not found - name: %.*s\n",
00319 tmp.timer.len, tmp.timer.s);
00320 free_params(params_list);
00321 return -1;
00322 }
00323 c = s.s[s.len];
00324 s.s[s.len] = '\0';
00325 tmp.route = route_get(&main_rt, s.s);
00326 s.s[s.len] = c;
00327 if(tmp.route == -1)
00328 {
00329 LM_ERR("invalid route: %.*s\n",
00330 s.len, s.s);
00331 free_params(params_list);
00332 return -1;
00333 }
00334
00335 rt = (stm_route_t*)pkg_malloc(sizeof(stm_route_t));
00336 if(rt==0)
00337 {
00338 LM_ERR("no more pkg memory\n");
00339 free_params(params_list);
00340 return -1;
00341 }
00342 memcpy(rt, &tmp, sizeof(stm_route_t));
00343 rt->next = nt->rt;
00344 nt->rt = rt;
00345 free_params(params_list);
00346 return 0;
00347 }
00348