app_lua: init timeval structures
[kamailio] / src / modules / app_lua / app_lua_api.c
1 /**
2  * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <sys/stat.h>
26
27 #include "../../core/sr_module.h"
28 #include "../../core/dprint.h"
29 #include "../../core/ut.h"
30 #include "../../core/mem/mem.h"
31 #include "../../core/locking.h"
32 #include "../../core/data_lump.h"
33 #include "../../core/data_lump_rpl.h"
34 #include "../../core/strutils.h"
35 #include "../../core/rpc.h"
36 #include "../../core/rpc_lookup.h"
37
38 #include "app_lua_api.h"
39 #include "app_lua_kemi_export.h"
40
41 #define KSRVERSION "2.0"
42
43 #define KSR_APP_LUA_LOG_EXPORTS (1<<0)
44
45 extern int _ksr_app_lua_log_mode;
46
47 void lua_sr_kemi_register_libs(lua_State *L);
48
49 static app_lua_openlibs_f app_lua_openlibs_cb = NULL;
50
51 /**
52  *
53  */
54 int app_lua_openlibs_register(app_lua_openlibs_f rfunc)
55 {
56         app_lua_openlibs_cb = rfunc;
57         return 0;
58 }
59
60 /**
61  * reload enabled param
62  * default: 0 (off)
63  */
64 static unsigned int _app_lua_sr_reload = 1;
65 /**
66  *
67  */
68 static sr_lua_env_t _sr_L_env;
69
70 /**
71  *
72  */
73 static int *_app_lua_sv = NULL;
74
75 /**
76  * @return the static Lua env
77  */
78 sr_lua_env_t *sr_lua_env_get(void)
79 {
80         return &_sr_L_env;
81 }
82
83 /**
84  *
85  */
86 static sr_lua_load_t *_sr_lua_load_list = NULL;
87 /**
88  * set of locks to manage the shared variable.
89  */
90 static gen_lock_set_t *sr_lua_locks = NULL;
91 static sr_lua_script_ver_t *sr_lua_script_ver = NULL;
92
93
94 int lua_sr_alloc_script_ver(void)
95 {
96         int size = _sr_L_env.nload;
97
98         sr_lua_script_ver = (sr_lua_script_ver_t *) shm_malloc(sizeof(sr_lua_script_ver_t));
99         if(sr_lua_script_ver==NULL)
100         {
101                 SHM_MEM_ERROR;
102                 return -1;
103         }
104
105         sr_lua_script_ver->version = (unsigned int *) shm_malloc(sizeof(unsigned int)*size);
106         if(sr_lua_script_ver->version==NULL)
107         {
108                 SHM_MEM_ERROR;
109                 goto error;
110         }
111         memset(sr_lua_script_ver->version, 0, sizeof(unsigned int)*size);
112         sr_lua_script_ver->len = size;
113
114         if((sr_lua_locks=lock_set_alloc(size))==0)
115         {
116                 LM_CRIT("failed to alloc lock set\n");
117                 goto error;
118         }
119         if(lock_set_init(sr_lua_locks)==0 )
120         {
121                 LM_CRIT("failed to init lock set\n");
122                 goto error;
123         }
124
125         return 0;
126 error:
127         if(sr_lua_script_ver!=NULL)
128         {
129                 if(sr_lua_script_ver->version!=NULL)
130                 {
131                         shm_free(sr_lua_script_ver->version);
132                         sr_lua_script_ver->version = NULL;
133                 }
134                 shm_free(sr_lua_script_ver);
135                 sr_lua_script_ver = NULL;
136         }
137         if(sr_lua_locks!=NULL)
138         {
139                 lock_set_destroy( sr_lua_locks );
140                 lock_set_dealloc( sr_lua_locks );
141                 sr_lua_locks = NULL;
142         }
143         return -1;
144 }
145
146 /**
147  *
148  */
149 int sr_lua_load_script(char *script)
150 {
151         sr_lua_load_t *li;
152
153         li = (sr_lua_load_t*)pkg_malloc(sizeof(sr_lua_load_t));
154         if(li==NULL)
155         {
156                 PKG_MEM_ERROR;
157                 return -1;
158         }
159         memset(li, 0, sizeof(sr_lua_load_t));
160         li->script = script;
161         li->version = 0;
162         li->next = _sr_lua_load_list;
163         _sr_lua_load_list = li;
164         _sr_L_env.nload += 1;
165         LM_DBG("loaded script:[%s].\n", script);
166         LM_DBG("Now there are %d scripts loaded\n", _sr_L_env.nload);
167
168         return 0;
169 }
170
171 /**
172  *
173  */
174 int sr_lua_reload_module(unsigned int reload)
175 {
176         LM_DBG("reload:%d\n", reload);
177         if(reload!=0) {
178                 _app_lua_sr_reload = 1;
179                 LM_DBG("reload param activated!\n");
180         } else {
181                 _app_lua_sr_reload = 0;
182                 LM_DBG("reload param inactivated!\n");
183         }
184         return 0;
185 }
186
187 /**
188  *
189  */
190 void lua_sr_openlibs(lua_State *L)
191 {
192         if(app_lua_openlibs_cb!=NULL) {
193                 app_lua_openlibs_cb(L);
194         }
195         lua_sr_kemi_register_libs(L);
196 }
197
198 /**
199  *
200  */
201 int lua_sr_init_mod(void)
202 {
203         /* allocate shm */
204         if(lua_sr_alloc_script_ver()<0) {
205                 LM_CRIT("failed to alloc shm for version\n");
206                 return -1;
207         }
208
209         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
210
211         return 0;
212
213 }
214
215 /**
216  *
217  */
218 int lua_sr_init_probe(void)
219 {
220         lua_State *L;
221         char *txt;
222         sr_lua_load_t *li;
223         struct stat sbuf;
224
225         L = luaL_newstate();
226         if(L==NULL)
227         {
228                 LM_ERR("cannot open lua\n");
229                 return -1;
230         }
231         luaL_openlibs(L);
232         lua_sr_openlibs(L);
233
234         /* force loading lua lib now */
235         if(luaL_dostring(L, "KSR.x.probe()")!=0)
236         {
237                 txt = (char*)lua_tostring(L, -1);
238                 LM_ERR("error initializing Lua: %s\n", (txt)?txt:"unknown");
239                 lua_pop(L, 1);
240                 lua_close(L);
241                 return -1;
242         }
243
244         /* test if files to be loaded exist */
245         if(_sr_lua_load_list != NULL)
246         {
247                 li = _sr_lua_load_list;
248                 while(li)
249                 {
250                         if(stat(li->script, &sbuf)!=0)
251                         {
252                                 /* file does not exist */
253                                 LM_ERR("cannot find script: %s (wrong path?)\n",
254                                                 li->script);
255                                 lua_close(L);
256                                 return -1;
257                         }
258                         li = li->next;
259                 }
260         }
261         lua_close(L);
262         LM_DBG("Lua probe was ok!\n");
263         return 0;
264 }
265
266 /**
267  *
268  */
269 int lua_sr_init_child(void)
270 {
271         sr_lua_load_t *li;
272         int ret;
273         char *txt;
274
275         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
276         _sr_L_env.L = luaL_newstate();
277         if(_sr_L_env.L==NULL)
278         {
279                 LM_ERR("cannot open lua\n");
280                 return -1;
281         }
282         luaL_openlibs(_sr_L_env.L);
283         lua_sr_openlibs(_sr_L_env.L);
284
285         /* set KSR lib version */
286 #if LUA_VERSION_NUM >= 502
287         lua_pushstring(_sr_L_env.L, KSRVERSION);
288         lua_setglobal(_sr_L_env.L, "KSRVERSION");
289 #else
290         lua_pushstring(_sr_L_env.L, "KSRVERSION");
291         lua_pushstring(_sr_L_env.L, KSRVERSION);
292         lua_settable(_sr_L_env.L, LUA_GLOBALSINDEX);
293 #endif
294         if(_sr_lua_load_list != NULL)
295         {
296                 _sr_L_env.LL = luaL_newstate();
297                 if(_sr_L_env.LL==NULL)
298                 {
299                         LM_ERR("cannot open lua loading state\n");
300                         return -1;
301                 }
302                 luaL_openlibs(_sr_L_env.LL);
303                 lua_sr_openlibs(_sr_L_env.LL);
304
305                 /* set SR lib version */
306 #if LUA_VERSION_NUM >= 502
307                 lua_pushstring(_sr_L_env.LL, KSRVERSION);
308                 lua_setglobal(_sr_L_env.LL, "KSRVERSION");
309 #else
310                 lua_pushstring(_sr_L_env.LL, "KSRVERSION");
311                 lua_pushstring(_sr_L_env.LL, KSRVERSION);
312                 lua_settable(_sr_L_env.LL, LUA_GLOBALSINDEX);
313 #endif
314                 /* force loading lua lib now */
315                 if(luaL_dostring(_sr_L_env.LL, "KSR.x.probe()")!=0)
316                 {
317                         txt = (char*)lua_tostring(_sr_L_env.LL, -1);
318                         LM_ERR("error initializing Lua: %s\n", (txt)?txt:"unknown");
319                         lua_pop(_sr_L_env.LL, 1);
320                         lua_sr_destroy();
321                         return -1;
322                 }
323
324                 li = _sr_lua_load_list;
325                 while(li)
326                 {
327                         ret = luaL_dofile(_sr_L_env.LL, (const char*)li->script);
328                         if(ret!=0)
329                         {
330                                 LM_ERR("failed to load Lua script: %s (err: %d)\n",
331                                                 li->script, ret);
332                                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
333                                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
334                                 lua_pop(_sr_L_env.LL, 1);
335                                 lua_sr_destroy();
336                                 return -1;
337                         }
338                         li = li->next;
339                 }
340         }
341         LM_DBG("Lua initialized!\n");
342         return 0;
343 }
344
345 /**
346  *
347  */
348 void lua_sr_destroy(void)
349 {
350         if(_sr_L_env.L!=NULL)
351         {
352                 lua_close(_sr_L_env.L);
353                 _sr_L_env.L = NULL;
354         }
355         if(_sr_L_env.LL!=NULL)
356         {
357                 lua_close(_sr_L_env.LL);
358                 _sr_L_env.LL = NULL;
359         }
360         memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
361
362         if(sr_lua_script_ver!=NULL)
363         {
364                 shm_free(sr_lua_script_ver->version);
365                 shm_free(sr_lua_script_ver);
366         }
367
368         if (sr_lua_locks!=NULL)
369         {
370                 lock_set_destroy( sr_lua_locks );
371                 lock_set_dealloc( sr_lua_locks );
372                 sr_lua_locks = 0;
373         }
374
375         if(_app_lua_sv!=NULL) {
376                 pkg_free(_app_lua_sv);
377                 _app_lua_sv = 0;
378         }
379 }
380
381 /**
382  *
383  */
384 int lua_sr_list_script(sr_lua_load_t **list)
385 {
386         *list = _sr_lua_load_list;
387         return 0;
388 }
389
390 /**
391  * Mark script in pos to be reloaded
392  * pos -1: reload all scritps
393  */
394 int lua_sr_reload_script(int pos)
395 {
396         int i, len = sr_lua_script_ver->len;
397         if(_sr_lua_load_list!= NULL)
398         {
399                 if (!sr_lua_script_ver)
400                 {
401                         LM_CRIT("shm for version not allocated\n");
402                         return -1;
403                 }
404                 if (_app_lua_sr_reload==0)
405                 {
406                         LM_ERR("reload is not activated\n");
407                         return -3;
408                 }
409                 if (pos<0)
410                 {
411                         // let's mark all the scripts to be reloaded
412                         for (i=0;i<len;i++)
413                         {
414                                 lock_set_get(sr_lua_locks, i);
415                                 sr_lua_script_ver->version[i] += 1;
416                                 lock_set_release(sr_lua_locks, i);
417                         }
418                 }
419                 else
420                 {
421                         if (pos>=0 && pos<len)
422                         {
423                                 lock_set_get(sr_lua_locks, pos);
424                                 sr_lua_script_ver->version[pos] += 1;
425                                 lock_set_release(sr_lua_locks, pos);
426                                 LM_DBG("pos: %d set to reloaded\n", pos);
427                         }
428                         else
429                         {
430                                 LM_ERR("pos out of range\n");
431                                 return -2;
432                         }
433                 }
434                 return 0;
435         }
436         LM_ERR("No script loaded\n");
437         return -1;
438 }
439
440 /**
441  * Checks if loaded version matches the shared
442  * counter. If not equal reloads the script.
443  */
444 int sr_lua_reload_script(void)
445 {
446         sr_lua_load_t *li = _sr_lua_load_list;
447         int ret, i;
448         char *txt;
449         int sv_len = sr_lua_script_ver->len;
450
451         if(li==NULL)
452         {
453                 LM_DBG("No script loaded\n");
454                 return 0;
455         }
456
457         if(_app_lua_sv==NULL) {
458                 _app_lua_sv = (int *) pkg_malloc(sizeof(int)*sv_len);
459                 if(_app_lua_sv==NULL)
460                 {
461                         PKG_MEM_ERROR;
462                         return -1;
463                 }
464         }
465
466         for(i=0;i<sv_len;i++)
467         {
468                 lock_set_get(sr_lua_locks, i);
469                 _app_lua_sv[i] = sr_lua_script_ver->version[i];
470                 lock_set_release(sr_lua_locks, i);
471
472                 if(li->version!=_app_lua_sv[i])
473                 {
474                         LM_DBG("loaded version:%d needed: %d Let's reload <%s>\n",
475                                 li->version, _app_lua_sv[i], li->script);
476                         ret = luaL_dofile(_sr_L_env.LL, (const char*)li->script);
477                         if(ret!=0)
478                         {
479                                 LM_ERR("failed to load Lua script: %s (err: %d)\n",
480                                                 li->script, ret);
481                                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
482                                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
483                                 lua_pop(_sr_L_env.LL, 1);
484                                 return -1;
485                         }
486                         li->version = _app_lua_sv[i];
487                         LM_DBG("<%s> set to version %d\n", li->script, li->version);
488                 }
489                 else LM_DBG("No need to reload [%s] is version %d\n",
490                         li->script, li->version);
491                 li = li->next;
492         }
493         return 1;
494 }
495
496 /**
497  *
498  */
499 int lua_sr_initialized(void)
500 {
501         if(_sr_L_env.L==NULL)
502                 return 0;
503
504         return 1;
505 }
506
507 /**
508  *
509  */
510 int app_lua_return_int(lua_State *L, int v)
511 {
512         lua_pushinteger(L, v);
513         return 1;
514 }
515
516 /**
517  *
518  */
519 int app_lua_return_error(lua_State *L)
520 {
521         lua_pushinteger(L, -1);
522         return 1;
523 }
524
525 /**
526  *
527  */
528 int app_lua_return_boolean(lua_State *L, int b)
529 {
530         if(b==SRLUA_FALSE)
531                 lua_pushboolean(L, SRLUA_FALSE);
532         else
533                 lua_pushboolean(L, SRLUA_TRUE);
534         return 1;
535 }
536
537 /**
538  *
539  */
540 int app_lua_return_false(lua_State *L)
541 {
542         lua_pushboolean(L, SRLUA_FALSE);
543         return 1;
544 }
545
546 /**
547  *
548  */
549 int app_lua_return_true(lua_State *L)
550 {
551         lua_pushboolean(L, SRLUA_TRUE);
552         return 1;
553 }
554
555 /**
556  *
557  */
558 int app_lua_dostring(sip_msg_t *msg, char *script)
559 {
560         int ret;
561         char *txt;
562         sip_msg_t *bmsg;
563
564         LM_DBG("executing Lua string: [[%s]]\n", script);
565         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
566         bmsg = _sr_L_env.msg;
567         _sr_L_env.msg = msg;
568         ret = luaL_dostring(_sr_L_env.L, script);
569         if(ret!=0)
570         {
571                 txt = (char*)lua_tostring(_sr_L_env.L, -1);
572                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
573                 lua_pop (_sr_L_env.L, 1);
574         }
575         _sr_L_env.msg = bmsg;
576         return (ret==0)?1:-1;
577 }
578
579 /**
580  *
581  */
582 int app_lua_dofile(sip_msg_t *msg, char *script)
583 {
584         int ret;
585         char *txt;
586         sip_msg_t *bmsg;
587
588         LM_DBG("executing Lua file: [[%s]]\n", script);
589         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
590         bmsg = _sr_L_env.msg;
591         _sr_L_env.msg = msg;
592         ret = luaL_dofile(_sr_L_env.L, script);
593         if(ret!=0)
594         {
595                 txt = (char*)lua_tostring(_sr_L_env.L, -1);
596                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
597                 lua_pop(_sr_L_env.L, 1);
598         }
599         _sr_L_env.msg = bmsg;
600         return (ret==0)?1:-1;
601 }
602
603 /**
604  *
605  */
606 int app_lua_runstring(sip_msg_t *msg, char *script)
607 {
608         int ret;
609         char *txt;
610         sip_msg_t *bmsg;
611
612         if(_sr_L_env.LL==NULL)
613         {
614                 LM_ERR("lua loading state not initialized (call: %s)\n", script);
615                 return -1;
616         }
617
618         LM_DBG("running Lua string: [[%s]]\n", script);
619         LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.LL));
620         bmsg = _sr_L_env.msg;
621         _sr_L_env.msg = msg;
622         ret = luaL_dostring(_sr_L_env.LL, script);
623         if(ret!=0)
624         {
625                 txt = (char*)lua_tostring(_sr_L_env.LL, -1);
626                 LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
627                 lua_pop (_sr_L_env.LL, 1);
628         }
629         _sr_L_env.msg = bmsg;
630         return (ret==0)?1:-1;
631 }
632
633 /**
634  *
635  */
636 static str _sr_kemi_lua_exit_string = str_init("~~ksr~exit~~");
637
638 /**
639  *
640  */
641 str* sr_kemi_lua_exit_string_get(void)
642 {
643         return &_sr_kemi_lua_exit_string;
644 }
645
646 /**
647  *
648  */
649 int app_lua_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2,
650                 char *p3, int emode)
651 {
652         int n;
653         int ret;
654         str txt;
655         sip_msg_t *bmsg;
656         int ltop;
657
658         if(_sr_L_env.LL==NULL)
659         {
660                 LM_ERR("lua loading state not initialized (call: %s)\n", func);
661                 return -1;
662         }
663         if(_app_lua_sr_reload!=0)
664         {
665                 /* check the script version loaded */
666                 if(!sr_lua_reload_script())
667                 {
668                         LM_ERR("lua reload failed\n");
669                         return -1;
670                 }
671         }
672         else LM_DBG("reload deactivated\n");
673         LM_DBG("executing Lua function: [[%s]]\n", func);
674         ltop = lua_gettop(_sr_L_env.LL);
675         LM_DBG("lua top index is: %d\n", ltop);
676         lua_getglobal(_sr_L_env.LL, func);
677         if(!lua_isfunction(_sr_L_env.LL, -1))
678         {
679                 if(emode) {
680                         LM_ERR("no such function [%s] in lua scripts\n", func);
681                         LM_ERR("top stack type [%d - %s]\n",
682                                 lua_type(_sr_L_env.LL, -1),
683                                 lua_typename(_sr_L_env.LL,lua_type(_sr_L_env.LL, -1)));
684                         txt.s = (char*)lua_tostring(_sr_L_env.LL, -1);
685                         LM_ERR("error from Lua: %s\n", (txt.s)?txt.s:"unknown");
686                         /* restores the original stack size */
687                         lua_settop(_sr_L_env.LL, ltop);
688                         return -1;
689                 } else {
690                         /* restores the original stack size */
691                         lua_settop(_sr_L_env.LL, ltop);
692                         return 1;
693                 }
694         }
695         n = 0;
696         if(p1!=NULL)
697         {
698                 lua_pushstring(_sr_L_env.LL, p1);
699                 n++;
700                 if(p2!=NULL)
701                 {
702                         lua_pushstring(_sr_L_env.LL, p2);
703                         n++;
704                         if(p3!=NULL)
705                         {
706                                 lua_pushstring(_sr_L_env.LL, p3);
707                                 n++;
708                         }
709                 }
710         }
711         bmsg = _sr_L_env.msg;
712         _sr_L_env.msg = msg;
713         ret = lua_pcall(_sr_L_env.LL, n, 0, 0);
714         _sr_L_env.msg = bmsg;
715         if(ret!=0)
716         {
717                 txt.s = (char*)lua_tostring(_sr_L_env.LL, -1);
718                 n = 0;
719                 if(txt.s!=NULL) {
720                         for(n=0; txt.s[n]!='\0' && _sr_kemi_lua_exit_string.s[n]!='\0';
721                                         n++) {
722                                 if(txt.s[n] != _sr_kemi_lua_exit_string.s[n])
723                                         break;
724                         }
725                         if(txt.s[n]!='\0' || _sr_kemi_lua_exit_string.s[n]!='\0') {
726                                 LM_ERR("error from Lua: %s\n", txt.s);
727                                 n = 0;
728                         } else {
729                                 LM_DBG("ksr error call from Lua: %s\n", txt.s);
730                                 n = 1;
731                         }
732                 } else {
733                         LM_ERR("error from Lua: unknown\n");
734                 }
735                 lua_pop(_sr_L_env.LL, 1);
736                 if(n==1) {
737                         /* restores the original stack size */
738                         lua_settop(_sr_L_env.LL, ltop);
739                         return 1;
740                 } else {
741                         LM_ERR("error executing: %s (err: %d)\n", func, ret);
742                         /* restores the original stack size */
743                         lua_settop(_sr_L_env.LL, ltop);
744                         return -1;
745                 }
746         }
747
748         /* restores the original stack size */
749         lua_settop(_sr_L_env.LL, ltop);
750
751         return 1;
752 }
753
754 /**
755  *
756  */
757 int app_lua_run(sip_msg_t *msg, char *func, char *p1, char *p2,
758                 char *p3)
759 {
760         return app_lua_run_ex(msg, func, p1, p2, p3, 1);
761 }
762
763 void app_lua_dump_stack(lua_State *L)
764 {
765         int i;
766         int t;
767         int top;
768
769         top = lua_gettop(L);
770
771         LM_DBG("lua stack top index: %d\n", top);
772         for (i = 1; i <= top; i++)
773         {
774                 t = lua_type(L, i);
775                 switch (t)
776                 {
777                         case LUA_TSTRING:  /* strings */
778                                 LM_DBG("[%i:s> %s\n", i, lua_tostring(L, i));
779                         break;
780                         case LUA_TBOOLEAN:  /* booleans */
781                                 LM_DBG("[%i:b> %s\n", i,
782                                         lua_toboolean(L, i) ? "true" : "false");
783                         break;
784                         case LUA_TNUMBER:  /* numbers */
785                                 LM_DBG("[%i:n> %g\n", i, lua_tonumber(L, i));
786                         break;
787                         default:  /* other values */
788                                 LM_DBG("[%i:t> %s\n", i, lua_typename(L, t));
789                         break;
790                 }
791         }
792 }
793
794 /**
795  *
796  */
797 int sr_kemi_lua_return_int(lua_State* L, sr_kemi_t *ket, int rc)
798 {
799         if(ket->rtype==SR_KEMIP_INT) {
800                 lua_pushinteger(L, rc);
801                 return 1;
802         }
803         if(ket->rtype==SR_KEMIP_BOOL && rc!=SR_KEMI_FALSE) {
804                 return app_lua_return_true(L);
805         }
806         return app_lua_return_false(L);
807 }
808
809 void sr_kemi_lua_push_dict_item(lua_State *L, sr_kemi_dict_item_t *item);
810
811 /**
812  * creates and push a table to the lua stack with
813  * the elements of the list
814  */
815 void sr_kemi_lua_push_array(lua_State *L, sr_kemi_dict_item_t *item) {
816         int i = 1;
817         sr_kemi_dict_item_t *k;
818         if(!item) {
819                 LM_CRIT("BUG: dict field empty\n");
820                 return;
821         }
822         if (item->vtype == SR_KEMIP_ARRAY) {
823                 k = item->v.dict;
824         } else {
825                 k = item;
826         }
827         if(k) {
828                 lua_newtable(L);
829         }
830         while(k){
831                 lua_pushnumber(L, i++);
832                 sr_kemi_lua_push_dict_item(L, k);
833                 lua_settable(L, -3);
834                 k = k->next;
835         }
836 }
837
838 void sr_kemi_lua_push_dict(lua_State *L, sr_kemi_dict_item_t *item) {
839         sr_kemi_dict_item_t *k = item;
840         if(!item) {
841                 LM_CRIT("BUG: dict field empty\n");
842                 return;
843         }
844         lua_newtable(L);
845         while(k){
846                 sr_kemi_lua_push_dict_item(L, k->v.dict);
847                 lua_setfield(L, -2, k->name.s);
848                 k = k->next;
849         }
850 }
851
852 void
853 sr_kemi_lua_push_dict_item(lua_State *L, sr_kemi_dict_item_t *item)
854 {
855         switch(item->vtype) {
856                 case SR_KEMIP_NONE:
857                         LM_CRIT("BUG: vtype is NONE\n");
858                         lua_pushnil(L);
859                 break;
860                 case SR_KEMIP_INT:
861                         lua_pushinteger(L, item->v.n);
862                 break;
863                 case SR_KEMIP_STR:
864                         lua_pushlstring(L, item->v.s.s, item->v.s.len);
865                 break;
866                 case SR_KEMIP_BOOL:
867                         if(item->v.n!=SR_KEMI_FALSE) {
868                                 lua_pushboolean(L, SRLUA_TRUE);
869                         } else {
870                                 lua_pushboolean(L, SRLUA_FALSE);
871                         }
872                 break;
873                 case SR_KEMIP_NULL:
874                         lua_pushnil(L);
875                 break;
876                 case SR_KEMIP_ARRAY:
877                         sr_kemi_lua_push_array(L, item);
878                 break;
879                 case SR_KEMIP_DICT:
880                         sr_kemi_lua_push_dict(L, item);
881                 break;
882                 default:
883                         LM_DBG("unknown type:%d\n", item->vtype);
884                         /* unknown type - return false */
885                         lua_pushboolean(L, SRLUA_FALSE);
886         }
887 }
888
889 /**
890  *
891  */
892 int sr_kemi_lua_return_xval(lua_State* L, sr_kemi_t *ket, sr_kemi_xval_t *rx)
893 {
894         switch(rx->vtype) {
895                 case SR_KEMIP_NONE:
896                         return 0;
897                 case SR_KEMIP_INT:
898                         lua_pushinteger(L, rx->v.n);
899                         return 1;
900                 case SR_KEMIP_STR:
901                         lua_pushlstring(L, rx->v.s.s, rx->v.s.len);
902                         return 1;
903                 case SR_KEMIP_BOOL:
904                         if(rx->v.n!=SR_KEMI_FALSE) {
905                                 lua_pushboolean(L, SRLUA_TRUE);
906                         } else {
907                                 lua_pushboolean(L, SRLUA_FALSE);
908                         }
909                         return 1;
910                 case SR_KEMIP_XVAL:
911                         /* unknown content - return false */
912                         lua_pushboolean(L, SRLUA_FALSE);
913                         return 1;
914                 case SR_KEMIP_NULL:
915                         lua_pushnil(L);
916                         return 1;
917                 case SR_KEMIP_ARRAY:
918                         sr_kemi_lua_push_array(L, rx->v.dict);
919                         sr_kemi_xval_free(rx);
920                         return 1;
921                 case SR_KEMIP_DICT:
922                         sr_kemi_lua_push_dict_item(L, rx->v.dict);
923                         sr_kemi_xval_free(rx);
924                         return 1;
925                 default:
926                         /* unknown type - return false */
927                         lua_pushboolean(L, SRLUA_FALSE);
928                         return 1;
929         }
930 }
931
932 /**
933  *
934  */
935 int sr_kemi_lua_exec_func_ex(lua_State* L, sr_kemi_t *ket, int pdelta)
936 {
937         int i;
938         int argc;
939         int ret;
940         str *fname;
941         str *mname;
942         sr_kemi_val_t vps[SR_KEMI_PARAMS_MAX];
943         sr_lua_env_t *env_L;
944         sr_kemi_xval_t *xret;
945
946         env_L = sr_lua_env_get();
947
948         if(env_L==NULL || env_L->msg==NULL || ket==NULL) {
949                 LM_ERR("invalid Lua environment attributes or parameters\n");
950                 return app_lua_return_false(L);
951         }
952
953         fname = &ket->fname;
954         mname = &ket->mname;
955
956         argc = lua_gettop(L);
957         if(argc==pdelta && ket->ptypes[0]==SR_KEMIP_NONE) {
958                 if(ket->rtype==SR_KEMIP_XVAL) {
959                         xret = ((sr_kemi_xfm_f)(ket->func))(env_L->msg);
960                         return sr_kemi_lua_return_xval(L, ket, xret);
961                 } else {
962                         ret = ((sr_kemi_fm_f)(ket->func))(env_L->msg);
963                         return sr_kemi_lua_return_int(L, ket, ret);
964                 }
965         }
966         if(argc==pdelta && ket->ptypes[0]!=SR_KEMIP_NONE) {
967                 LM_ERR("invalid number of parameters for: %.*s.%.*s\n",
968                                 mname->len, mname->s, fname->len, fname->s);
969                 return app_lua_return_false(L);
970         }
971
972         if(argc>SR_KEMI_PARAMS_MAX+pdelta) {
973                 LM_ERR("too many parameters for: %.*s.%.*s\n",
974                                 mname->len, mname->s, fname->len, fname->s);
975                 return app_lua_return_false(L);
976         }
977
978         memset(vps, 0, SR_KEMI_PARAMS_MAX*sizeof(sr_kemi_val_t));
979         for(i=0; i<SR_KEMI_PARAMS_MAX; i++) {
980                 if(ket->ptypes[i]==SR_KEMIP_NONE) {
981                         break;
982                 }
983                 if(argc<i+pdelta+1) {
984                         LM_ERR("not enough parameters for: %.*s.%.*s\n",
985                                         mname->len, mname->s, fname->len, fname->s);
986                         return app_lua_return_false(L);
987                 }
988                 if(ket->ptypes[i]==SR_KEMIP_STR) {
989                         vps[i].s.s = (char*)lua_tostring(L, i+pdelta+1);
990                         if(vps[i].s.s!=NULL) {
991                                 if(lua_isstring(L, i+pdelta+1)) {
992 #if LUA_VERSION_NUM > 501
993                                         vps[i].s.len = lua_rawlen(L, i+pdelta+1);
994 #else
995                                         vps[i].s.len = lua_strlen(L, i+pdelta+1);
996 #endif
997                                 } else {
998                                         vps[i].s.len = strlen(vps[i].s.s);
999                                 }
1000                         } else {
1001                                 vps[i].s.len = 0;
1002                         }
1003                         LM_DBG("param[%d] for: %.*s is str: %.*s\n", i,
1004                                 fname->len, fname->s, vps[i].s.len, vps[i].s.s);
1005                 } else if(ket->ptypes[i]==SR_KEMIP_INT) {
1006                         vps[i].n = lua_tointeger(L, i+pdelta+1);
1007                         LM_DBG("param[%d] for: %.*s is int: %d\n", i,
1008                                 fname->len, fname->s, vps[i].n);
1009                 } else {
1010                         LM_ERR("unknown parameter type %d (%d)\n", ket->ptypes[i], i);
1011                         return app_lua_return_false(L);
1012                 }
1013         }
1014
1015         switch(i) {
1016                 case 1:
1017                         if(ket->ptypes[0]==SR_KEMIP_INT) {
1018                                 if(ket->rtype==SR_KEMIP_XVAL) {
1019                                         xret = ((sr_kemi_xfmn_f)(ket->func))(env_L->msg, vps[0].n);
1020                                         return sr_kemi_lua_return_xval(L, ket, xret);
1021                                 } else {
1022                                         ret = ((sr_kemi_fmn_f)(ket->func))(env_L->msg, vps[0].n);
1023                                         return sr_kemi_lua_return_int(L, ket, ret);
1024                                 }
1025                         } else if(ket->ptypes[0]==SR_KEMIP_STR) {
1026                                 if(ket->rtype==SR_KEMIP_XVAL) {
1027                                         xret = ((sr_kemi_xfms_f)(ket->func))(env_L->msg, &vps[0].s);
1028                                         return sr_kemi_lua_return_xval(L, ket, xret);
1029                                 } else {
1030                                         ret = ((sr_kemi_fms_f)(ket->func))(env_L->msg, &vps[0].s);
1031                                         return sr_kemi_lua_return_int(L, ket, ret);
1032                                 }
1033                         } else {
1034                                 LM_ERR("invalid parameters for: %.*s\n",
1035                                                 fname->len, fname->s);
1036                                 return app_lua_return_false(L);
1037                         }
1038                 break;
1039                 case 2:
1040                         if(ket->ptypes[0]==SR_KEMIP_INT) {
1041                                 if(ket->ptypes[1]==SR_KEMIP_INT) {
1042                                         if(ket->rtype==SR_KEMIP_XVAL) {
1043                                                 xret = ((sr_kemi_xfmnn_f)(ket->func))(env_L->msg, vps[0].n, vps[1].n);
1044                                                 return sr_kemi_lua_return_xval(L, ket, xret);
1045                                         } else {
1046                                                 ret = ((sr_kemi_fmnn_f)(ket->func))(env_L->msg, vps[0].n, vps[1].n);
1047                                                 return sr_kemi_lua_return_int(L, ket, ret);
1048                                         }
1049                                 } else if(ket->ptypes[1]==SR_KEMIP_STR) {
1050                                         if(ket->rtype==SR_KEMIP_XVAL) {
1051                                                 xret = ((sr_kemi_xfmns_f)(ket->func))(env_L->msg, vps[0].n, &vps[1].s);
1052                                                 return sr_kemi_lua_return_xval(L, ket, xret);
1053                                         } else {
1054                                                 ret = ((sr_kemi_fmns_f)(ket->func))(env_L->msg, vps[0].n, &vps[1].s);
1055                                                 return sr_kemi_lua_return_int(L, ket, ret);
1056                                         }
1057                                 } else {
1058                                         LM_ERR("invalid parameters for: %.*s\n",
1059                                                         fname->len, fname->s);
1060                                         return app_lua_return_false(L);
1061                                 }
1062                         } else if(ket->ptypes[0]==SR_KEMIP_STR) {
1063                                 if(ket->ptypes[1]==SR_KEMIP_INT) {
1064                                         if(ket->rtype==SR_KEMIP_XVAL) {
1065                                                 xret = ((sr_kemi_xfmsn_f)(ket->func))(env_L->msg, &vps[0].s, vps[1].n);
1066                                                 return sr_kemi_lua_return_xval(L, ket, xret);
1067                                         } else {
1068                                                 ret = ((sr_kemi_fmsn_f)(ket->func))(env_L->msg, &vps[0].s, vps[1].n);
1069                                                 return sr_kemi_lua_return_int(L, ket, ret);
1070                                         }
1071                                 } else if(ket->ptypes[1]==SR_KEMIP_STR) {
1072                                         if(ket->rtype==SR_KEMIP_XVAL) {
1073                                                 xret = ((sr_kemi_xfmss_f)(ket->func))(env_L->msg, &vps[0].s, &vps[1].s);
1074                                                 return sr_kemi_lua_return_xval(L, ket, xret);
1075                                         } else {
1076                                                 ret = ((sr_kemi_fmss_f)(ket->func))(env_L->msg, &vps[0].s, &vps[1].s);
1077                                                 return sr_kemi_lua_return_int(L, ket, ret);
1078                                         }
1079                                 } else {
1080                                         LM_ERR("invalid parameters for: %.*s\n",
1081                                                         fname->len, fname->s);
1082                                         return app_lua_return_false(L);
1083                                 }
1084                         } else {
1085                                 LM_ERR("invalid parameters for: %.*s\n",
1086                                                 fname->len, fname->s);
1087                                 return app_lua_return_false(L);
1088                         }
1089                 break;
1090                 case 3:
1091                         if(ket->ptypes[0]==SR_KEMIP_INT) {
1092                                 if(ket->ptypes[1]==SR_KEMIP_INT) {
1093                                         if(ket->ptypes[2]==SR_KEMIP_INT) {
1094                                                 ret = ((sr_kemi_fmnnn_f)(ket->func))(env_L->msg,
1095                                                                 vps[0].n, vps[1].n, vps[2].n);
1096                                                 return sr_kemi_lua_return_int(L, ket, ret);
1097                                         } else if(ket->ptypes[2]==SR_KEMIP_STR) {
1098                                                 ret = ((sr_kemi_fmnns_f)(ket->func))(env_L->msg,
1099                                                                 vps[0].n, vps[1].n, &vps[2].s);
1100                                                 return sr_kemi_lua_return_int(L, ket, ret);
1101                                         } else {
1102                                                 LM_ERR("invalid parameters for: %.*s\n",
1103                                                                 fname->len, fname->s);
1104                                                 return app_lua_return_false(L);
1105                                         }
1106                                 } else if(ket->ptypes[1]==SR_KEMIP_STR) {
1107                                         if(ket->ptypes[2]==SR_KEMIP_INT) {
1108                                                 ret = ((sr_kemi_fmnsn_f)(ket->func))(env_L->msg,
1109                                                                 vps[0].n, &vps[1].s, vps[2].n);
1110                                                 return sr_kemi_lua_return_int(L, ket, ret);
1111                                         } else if(ket->ptypes[2]==SR_KEMIP_STR) {
1112                                                 ret = ((sr_kemi_fmnss_f)(ket->func))(env_L->msg,
1113                                                                 vps[0].n, &vps[1].s, &vps[2].s);
1114                                                 return sr_kemi_lua_return_int(L, ket, ret);
1115                                         } else {
1116                                                 LM_ERR("invalid parameters for: %.*s\n",
1117                                                                 fname->len, fname->s);
1118                                                 return app_lua_return_false(L);
1119                                         }
1120                                 } else {
1121                                         LM_ERR("invalid parameters for: %.*s\n",
1122                                                         fname->len, fname->s);
1123                                         return app_lua_return_false(L);
1124                                 }
1125                         } else if(ket->ptypes[0]==SR_KEMIP_STR) {
1126                                 if(ket->ptypes[1]==SR_KEMIP_INT) {
1127                                         if(ket->ptypes[2]==SR_KEMIP_INT) {
1128                                                 ret = ((sr_kemi_fmsnn_f)(ket->func))(env_L->msg,
1129                                                                 &vps[0].s, vps[1].n, vps[2].n);
1130                                                 return sr_kemi_lua_return_int(L, ket, ret);
1131                                         } else if(ket->ptypes[2]==SR_KEMIP_STR) {
1132                                                 ret = ((sr_kemi_fmsns_f)(ket->func))(env_L->msg,
1133                                                                 &vps[0].s, vps[1].n, &vps[2].s);
1134                                                 return sr_kemi_lua_return_int(L, ket, ret);
1135                                         } else {
1136                                                 LM_ERR("invalid parameters for: %.*s\n",
1137                                                                 fname->len, fname->s);
1138                                                 return app_lua_return_false(L);
1139                                         }
1140                                 } else if(ket->ptypes[1]==SR_KEMIP_STR) {
1141                                         if(ket->ptypes[2]==SR_KEMIP_INT) {
1142                                                 ret = ((sr_kemi_fmssn_f)(ket->func))(env_L->msg,
1143                                                                 &vps[0].s, &vps[1].s, vps[2].n);
1144                                                 return sr_kemi_lua_return_int(L, ket, ret);
1145                                         } else if(ket->ptypes[2]==SR_KEMIP_STR) {
1146                                                 ret = ((sr_kemi_fmsss_f)(ket->func))(env_L->msg,
1147                                                                 &vps[0].s, &vps[1].s, &vps[2].s);
1148                                                 return sr_kemi_lua_return_int(L, ket, ret);
1149                                         } else {
1150                                                 LM_ERR("invalid parameters for: %.*s\n",
1151                                                                 fname->len, fname->s);
1152                                                 return app_lua_return_false(L);
1153                                         }
1154                                 } else {
1155                                         LM_ERR("invalid parameters for: %.*s\n",
1156                                                         fname->len, fname->s);
1157                                         return app_lua_return_false(L);
1158                                 }
1159                         } else {
1160                                 LM_ERR("invalid parameters for: %.*s\n",
1161                                                 fname->len, fname->s);
1162                                 return app_lua_return_false(L);
1163                         }
1164                 break;
1165                 case 4:
1166                         if(ket->ptypes[0]==SR_KEMIP_STR
1167                                         && ket->ptypes[1]==SR_KEMIP_STR
1168                                         && ket->ptypes[2]==SR_KEMIP_STR
1169                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1170                                 ret = ((sr_kemi_fmssss_f)(ket->func))(env_L->msg,
1171                                                 &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s);
1172                                 return sr_kemi_lua_return_int(L, ket, ret);
1173                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1174                                         && ket->ptypes[1]==SR_KEMIP_STR
1175                                         && ket->ptypes[2]==SR_KEMIP_STR
1176                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1177                                 ret = ((sr_kemi_fmsssn_f)(ket->func))(env_L->msg,
1178                                                 &vps[0].s, &vps[1].s, &vps[2].s, vps[3].n);
1179                                 return sr_kemi_lua_return_int(L, ket, ret);
1180                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1181                                         && ket->ptypes[1]==SR_KEMIP_STR
1182                                         && ket->ptypes[2]==SR_KEMIP_INT
1183                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1184                                 ret = ((sr_kemi_fmssns_f)(ket->func))(env_L->msg,
1185                                                 &vps[0].s, &vps[1].s, vps[2].n, &vps[3].s);
1186                                 return sr_kemi_lua_return_int(L, ket, ret);
1187                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1188                                         && ket->ptypes[1]==SR_KEMIP_STR
1189                                         && ket->ptypes[2]==SR_KEMIP_INT
1190                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1191                                 ret = ((sr_kemi_fmssnn_f)(ket->func))(env_L->msg,
1192                                                 &vps[0].s, &vps[1].s, vps[2].n, vps[3].n);
1193                                 return sr_kemi_lua_return_int(L, ket, ret);
1194                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1195                                         && ket->ptypes[1]==SR_KEMIP_INT
1196                                         && ket->ptypes[2]==SR_KEMIP_STR
1197                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1198                                 ret = ((sr_kemi_fmsnss_f)(ket->func))(env_L->msg,
1199                                                 &vps[0].s, vps[1].n, &vps[2].s, &vps[3].s);
1200                                 return sr_kemi_lua_return_int(L, ket, ret);
1201                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1202                                         && ket->ptypes[1]==SR_KEMIP_INT
1203                                         && ket->ptypes[2]==SR_KEMIP_STR
1204                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1205                                 ret = ((sr_kemi_fmsnsn_f)(ket->func))(env_L->msg,
1206                                                 &vps[0].s, vps[1].n, &vps[2].s, vps[3].n);
1207                                 return sr_kemi_lua_return_int(L, ket, ret);
1208                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1209                                         && ket->ptypes[1]==SR_KEMIP_INT
1210                                         && ket->ptypes[2]==SR_KEMIP_INT
1211                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1212                                 ret = ((sr_kemi_fmsnns_f)(ket->func))(env_L->msg,
1213                                                 &vps[0].s, vps[1].n, vps[2].n, &vps[3].s);
1214                                 return sr_kemi_lua_return_int(L, ket, ret);
1215                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1216                                         && ket->ptypes[1]==SR_KEMIP_INT
1217                                         && ket->ptypes[2]==SR_KEMIP_INT
1218                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1219                                 ret = ((sr_kemi_fmsnnn_f)(ket->func))(env_L->msg,
1220                                                 &vps[0].s, vps[1].n, vps[2].n, vps[3].n);
1221                                 return sr_kemi_lua_return_int(L, ket, ret);
1222                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1223                                         && ket->ptypes[1]==SR_KEMIP_STR
1224                                         && ket->ptypes[2]==SR_KEMIP_STR
1225                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1226                                 ret = ((sr_kemi_fmnsss_f)(ket->func))(env_L->msg,
1227                                                 vps[0].n, &vps[1].s, &vps[2].s, &vps[3].s);
1228                                 return sr_kemi_lua_return_int(L, ket, ret);
1229                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1230                                         && ket->ptypes[1]==SR_KEMIP_STR
1231                                         && ket->ptypes[2]==SR_KEMIP_STR
1232                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1233                                 ret = ((sr_kemi_fmnssn_f)(ket->func))(env_L->msg,
1234                                                 vps[0].n, &vps[1].s, &vps[2].s, vps[3].n);
1235                                 return sr_kemi_lua_return_int(L, ket, ret);
1236                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1237                                         && ket->ptypes[1]==SR_KEMIP_STR
1238                                         && ket->ptypes[2]==SR_KEMIP_INT
1239                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1240                                 ret = ((sr_kemi_fmnsns_f)(ket->func))(env_L->msg,
1241                                                 vps[0].n, &vps[1].s, vps[2].n, &vps[3].s);
1242                                 return sr_kemi_lua_return_int(L, ket, ret);
1243                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1244                                         && ket->ptypes[1]==SR_KEMIP_STR
1245                                         && ket->ptypes[2]==SR_KEMIP_INT
1246                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1247                                 ret = ((sr_kemi_fmnsnn_f)(ket->func))(env_L->msg,
1248                                                 vps[0].n, &vps[1].s, vps[2].n, vps[3].n);
1249                                 return sr_kemi_lua_return_int(L, ket, ret);
1250                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1251                                         && ket->ptypes[1]==SR_KEMIP_INT
1252                                         && ket->ptypes[2]==SR_KEMIP_STR
1253                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1254                                 ret = ((sr_kemi_fmnnss_f)(ket->func))(env_L->msg,
1255                                                 vps[0].n, vps[1].n, &vps[2].s, &vps[3].s);
1256                                 return sr_kemi_lua_return_int(L, ket, ret);
1257                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1258                                         && ket->ptypes[1]==SR_KEMIP_INT
1259                                         && ket->ptypes[2]==SR_KEMIP_STR
1260                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1261                                 ret = ((sr_kemi_fmnnsn_f)(ket->func))(env_L->msg,
1262                                                 vps[0].n, vps[1].n, &vps[2].s, vps[3].n);
1263                                 return sr_kemi_lua_return_int(L, ket, ret);
1264                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1265                                         && ket->ptypes[1]==SR_KEMIP_INT
1266                                         && ket->ptypes[2]==SR_KEMIP_INT
1267                                         && ket->ptypes[3]==SR_KEMIP_STR) {
1268                                 ret = ((sr_kemi_fmnnns_f)(ket->func))(env_L->msg,
1269                                                 vps[0].n, vps[1].n, vps[2].n, &vps[3].s);
1270                                 return sr_kemi_lua_return_int(L, ket, ret);
1271                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1272                                         && ket->ptypes[1]==SR_KEMIP_INT
1273                                         && ket->ptypes[2]==SR_KEMIP_INT
1274                                         && ket->ptypes[3]==SR_KEMIP_INT) {
1275                                 ret = ((sr_kemi_fmnnnn_f)(ket->func))(env_L->msg,
1276                                                 vps[0].n, vps[1].n, vps[2].n, vps[3].n);
1277                                 return sr_kemi_lua_return_int(L, ket, ret);
1278                         } else {
1279                                 LM_ERR("invalid parameters for: %.*s\n", fname->len, fname->s);
1280                                 return app_lua_return_false(L);
1281                         }
1282                 break;
1283                 case 5:
1284                         if(ket->ptypes[0]==SR_KEMIP_STR
1285                                         && ket->ptypes[1]==SR_KEMIP_STR
1286                                         && ket->ptypes[2]==SR_KEMIP_STR
1287                                         && ket->ptypes[3]==SR_KEMIP_STR
1288                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1289                                 ret = ((sr_kemi_fmsssss_f)(ket->func))(env_L->msg,
1290                                                 &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s, &vps[4].s);
1291                                 return sr_kemi_lua_return_int(L, ket, ret);
1292                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1293                                         && ket->ptypes[1]==SR_KEMIP_STR
1294                                         && ket->ptypes[2]==SR_KEMIP_STR
1295                                         && ket->ptypes[3]==SR_KEMIP_STR
1296                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1297                                 ret = ((sr_kemi_fmssssn_f)(ket->func))(env_L->msg,
1298                                                 &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s, vps[4].n);
1299                                 return sr_kemi_lua_return_int(L, ket, ret);
1300                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1301                                         && ket->ptypes[1]==SR_KEMIP_STR
1302                                         && ket->ptypes[2]==SR_KEMIP_STR
1303                                         && ket->ptypes[3]==SR_KEMIP_INT
1304                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1305                                 ret = ((sr_kemi_fmsssns_f)(ket->func))(env_L->msg,
1306                                                 &vps[0].s, &vps[1].s, &vps[2].s, vps[3].n, &vps[4].s);
1307                                 return sr_kemi_lua_return_int(L, ket, ret);
1308                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1309                                         && ket->ptypes[1]==SR_KEMIP_STR
1310                                         && ket->ptypes[2]==SR_KEMIP_STR
1311                                         && ket->ptypes[3]==SR_KEMIP_INT
1312                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1313                                 ret = ((sr_kemi_fmsssnn_f)(ket->func))(env_L->msg,
1314                                                 &vps[0].s, &vps[1].s, &vps[2].s, vps[3].n, vps[4].n);
1315                                 return sr_kemi_lua_return_int(L, ket, ret);
1316                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1317                                         && ket->ptypes[1]==SR_KEMIP_STR
1318                                         && ket->ptypes[2]==SR_KEMIP_INT
1319                                         && ket->ptypes[3]==SR_KEMIP_STR
1320                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1321                                 ret = ((sr_kemi_fmssnss_f)(ket->func))(env_L->msg,
1322                                                 &vps[0].s, &vps[1].s, vps[2].n, &vps[3].s, &vps[4].s);
1323                                 return sr_kemi_lua_return_int(L, ket, ret);
1324                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1325                                         && ket->ptypes[1]==SR_KEMIP_STR
1326                                         && ket->ptypes[2]==SR_KEMIP_INT
1327                                         && ket->ptypes[3]==SR_KEMIP_STR
1328                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1329                                 ret = ((sr_kemi_fmssnsn_f)(ket->func))(env_L->msg,
1330                                                 &vps[0].s, &vps[1].s, vps[2].n, &vps[3].s, vps[4].n);
1331                                 return sr_kemi_lua_return_int(L, ket, ret);
1332                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1333                                         && ket->ptypes[1]==SR_KEMIP_STR
1334                                         && ket->ptypes[2]==SR_KEMIP_INT
1335                                         && ket->ptypes[3]==SR_KEMIP_INT
1336                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1337                                 ret = ((sr_kemi_fmssnns_f)(ket->func))(env_L->msg,
1338                                                 &vps[0].s, &vps[1].s, vps[2].n, vps[3].n, &vps[4].s);
1339                                 return sr_kemi_lua_return_int(L, ket, ret);
1340                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1341                                         && ket->ptypes[1]==SR_KEMIP_STR
1342                                         && ket->ptypes[2]==SR_KEMIP_INT
1343                                         && ket->ptypes[3]==SR_KEMIP_INT
1344                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1345                                 ret = ((sr_kemi_fmssnnn_f)(ket->func))(env_L->msg,
1346                                                 &vps[0].s, &vps[1].s, vps[2].n, vps[3].n, vps[4].n);
1347                                 return sr_kemi_lua_return_int(L, ket, ret);
1348                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1349                                         && ket->ptypes[1]==SR_KEMIP_INT
1350                                         && ket->ptypes[2]==SR_KEMIP_STR
1351                                         && ket->ptypes[3]==SR_KEMIP_STR
1352                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1353                                 ret = ((sr_kemi_fmsnsss_f)(ket->func))(env_L->msg,
1354                                                 &vps[0].s, vps[1].n, &vps[2].s, &vps[3].s, &vps[4].s);
1355                                 return sr_kemi_lua_return_int(L, ket, ret);
1356                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1357                                         && ket->ptypes[1]==SR_KEMIP_INT
1358                                         && ket->ptypes[2]==SR_KEMIP_STR
1359                                         && ket->ptypes[3]==SR_KEMIP_STR
1360                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1361                                 ret = ((sr_kemi_fmsnssn_f)(ket->func))(env_L->msg,
1362                                                 &vps[0].s, vps[1].n, &vps[2].s, &vps[3].s, vps[4].n);
1363                                 return sr_kemi_lua_return_int(L, ket, ret);
1364                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1365                                         && ket->ptypes[1]==SR_KEMIP_INT
1366                                         && ket->ptypes[2]==SR_KEMIP_STR
1367                                         && ket->ptypes[3]==SR_KEMIP_INT
1368                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1369                                 ret = ((sr_kemi_fmsnsns_f)(ket->func))(env_L->msg,
1370                                                 &vps[0].s, vps[1].n, &vps[2].s, vps[3].n, &vps[4].s);
1371                                 return sr_kemi_lua_return_int(L, ket, ret);
1372                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1373                                         && ket->ptypes[1]==SR_KEMIP_INT
1374                                         && ket->ptypes[2]==SR_KEMIP_STR
1375                                         && ket->ptypes[3]==SR_KEMIP_INT
1376                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1377                                 ret = ((sr_kemi_fmsnsnn_f)(ket->func))(env_L->msg,
1378                                                 &vps[0].s, vps[1].n, &vps[2].s, vps[3].n, vps[4].n);
1379                                 return sr_kemi_lua_return_int(L, ket, ret);
1380                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1381                                         && ket->ptypes[1]==SR_KEMIP_INT
1382                                         && ket->ptypes[2]==SR_KEMIP_INT
1383                                         && ket->ptypes[3]==SR_KEMIP_STR
1384                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1385                                 ret = ((sr_kemi_fmsnnss_f)(ket->func))(env_L->msg,
1386                                                 &vps[0].s, vps[1].n, vps[2].n, &vps[3].s, &vps[4].s);
1387                                 return sr_kemi_lua_return_int(L, ket, ret);
1388                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1389                                         && ket->ptypes[1]==SR_KEMIP_INT
1390                                         && ket->ptypes[2]==SR_KEMIP_INT
1391                                         && ket->ptypes[3]==SR_KEMIP_STR
1392                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1393                                 ret = ((sr_kemi_fmsnnsn_f)(ket->func))(env_L->msg,
1394                                                 &vps[0].s, vps[1].n, vps[2].n, &vps[3].s, vps[4].n);
1395                                 return sr_kemi_lua_return_int(L, ket, ret);
1396                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1397                                         && ket->ptypes[1]==SR_KEMIP_INT
1398                                         && ket->ptypes[2]==SR_KEMIP_INT
1399                                         && ket->ptypes[3]==SR_KEMIP_INT
1400                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1401                                 ret = ((sr_kemi_fmsnnns_f)(ket->func))(env_L->msg,
1402                                                 &vps[0].s, vps[1].n, vps[2].n, vps[3].n, &vps[4].s);
1403                                 return sr_kemi_lua_return_int(L, ket, ret);
1404                         } else if(ket->ptypes[0]==SR_KEMIP_STR
1405                                         && ket->ptypes[1]==SR_KEMIP_INT
1406                                         && ket->ptypes[2]==SR_KEMIP_INT
1407                                         && ket->ptypes[3]==SR_KEMIP_INT
1408                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1409                                 ret = ((sr_kemi_fmsnnnn_f)(ket->func))(env_L->msg,
1410                                                 &vps[0].s, vps[1].n, vps[2].n, vps[3].n, vps[4].n);
1411                                 return sr_kemi_lua_return_int(L, ket, ret);
1412                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1413                                         && ket->ptypes[1]==SR_KEMIP_STR
1414                                         && ket->ptypes[2]==SR_KEMIP_STR
1415                                         && ket->ptypes[3]==SR_KEMIP_STR
1416                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1417                                 ret = ((sr_kemi_fmnssss_f)(ket->func))(env_L->msg,
1418                                                 vps[0].n, &vps[1].s, &vps[2].s, &vps[3].s, &vps[4].s);
1419                                 return sr_kemi_lua_return_int(L, ket, ret);
1420                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1421                                         && ket->ptypes[1]==SR_KEMIP_STR
1422                                         && ket->ptypes[2]==SR_KEMIP_STR
1423                                         && ket->ptypes[3]==SR_KEMIP_STR
1424                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1425                                 ret = ((sr_kemi_fmnsssn_f)(ket->func))(env_L->msg,
1426                                                 vps[0].n, &vps[1].s, &vps[2].s, &vps[3].s, vps[4].n);
1427                                 return sr_kemi_lua_return_int(L, ket, ret);
1428                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1429                                         && ket->ptypes[1]==SR_KEMIP_STR
1430                                         && ket->ptypes[2]==SR_KEMIP_STR
1431                                         && ket->ptypes[3]==SR_KEMIP_INT
1432                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1433                                 ret = ((sr_kemi_fmnssns_f)(ket->func))(env_L->msg,
1434                                                 vps[0].n, &vps[1].s, &vps[2].s, vps[3].n, &vps[4].s);
1435                                 return sr_kemi_lua_return_int(L, ket, ret);
1436                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1437                                         && ket->ptypes[1]==SR_KEMIP_STR
1438                                         && ket->ptypes[2]==SR_KEMIP_STR
1439                                         && ket->ptypes[3]==SR_KEMIP_INT
1440                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1441                                 ret = ((sr_kemi_fmnssnn_f)(ket->func))(env_L->msg,
1442                                                 vps[0].n, &vps[1].s, &vps[2].s, vps[3].n, vps[4].n);
1443                                 return sr_kemi_lua_return_int(L, ket, ret);
1444                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1445                                         && ket->ptypes[1]==SR_KEMIP_STR
1446                                         && ket->ptypes[2]==SR_KEMIP_INT
1447                                         && ket->ptypes[3]==SR_KEMIP_STR
1448                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1449                                 ret = ((sr_kemi_fmnsnss_f)(ket->func))(env_L->msg,
1450                                                 vps[0].n, &vps[1].s, vps[2].n, &vps[3].s, &vps[4].s);
1451                                 return sr_kemi_lua_return_int(L, ket, ret);
1452                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1453                                         && ket->ptypes[1]==SR_KEMIP_STR
1454                                         && ket->ptypes[2]==SR_KEMIP_INT
1455                                         && ket->ptypes[3]==SR_KEMIP_STR
1456                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1457                                 ret = ((sr_kemi_fmnsnsn_f)(ket->func))(env_L->msg,
1458                                                 vps[0].n, &vps[1].s, vps[2].n, &vps[3].s, vps[4].n);
1459                                 return sr_kemi_lua_return_int(L, ket, ret);
1460                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1461                                         && ket->ptypes[1]==SR_KEMIP_STR
1462                                         && ket->ptypes[2]==SR_KEMIP_INT
1463                                         && ket->ptypes[3]==SR_KEMIP_INT
1464                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1465                                 ret = ((sr_kemi_fmnsnns_f)(ket->func))(env_L->msg,
1466                                                 vps[0].n, &vps[1].s, vps[2].n, vps[3].n, &vps[4].s);
1467                                 return sr_kemi_lua_return_int(L, ket, ret);
1468                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1469                                         && ket->ptypes[1]==SR_KEMIP_STR
1470                                         && ket->ptypes[2]==SR_KEMIP_INT
1471                                         && ket->ptypes[3]==SR_KEMIP_INT
1472                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1473                                 ret = ((sr_kemi_fmnsnnn_f)(ket->func))(env_L->msg,
1474                                                 vps[0].n, &vps[1].s, vps[2].n, vps[3].n, vps[4].n);
1475                                 return sr_kemi_lua_return_int(L, ket, ret);
1476                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1477                                         && ket->ptypes[1]==SR_KEMIP_INT
1478                                         && ket->ptypes[2]==SR_KEMIP_STR
1479                                         && ket->ptypes[3]==SR_KEMIP_STR
1480                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1481                                 ret = ((sr_kemi_fmnnsss_f)(ket->func))(env_L->msg,
1482                                                 vps[0].n, vps[1].n, &vps[2].s, &vps[3].s, &vps[4].s);
1483                                 return sr_kemi_lua_return_int(L, ket, ret);
1484                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1485                                         && ket->ptypes[1]==SR_KEMIP_INT
1486                                         && ket->ptypes[2]==SR_KEMIP_STR
1487                                         && ket->ptypes[3]==SR_KEMIP_STR
1488                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1489                                 ret = ((sr_kemi_fmnnssn_f)(ket->func))(env_L->msg,
1490                                                 vps[0].n, vps[1].n, &vps[2].s, &vps[3].s, vps[4].n);
1491                                 return sr_kemi_lua_return_int(L, ket, ret);
1492                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1493                                         && ket->ptypes[1]==SR_KEMIP_INT
1494                                         && ket->ptypes[2]==SR_KEMIP_STR
1495                                         && ket->ptypes[3]==SR_KEMIP_INT
1496                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1497                                 ret = ((sr_kemi_fmnnsns_f)(ket->func))(env_L->msg,
1498                                                 vps[0].n, vps[1].n, &vps[2].s, vps[3].n, &vps[4].s);
1499                                 return sr_kemi_lua_return_int(L, ket, ret);
1500                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1501                                         && ket->ptypes[1]==SR_KEMIP_INT
1502                                         && ket->ptypes[2]==SR_KEMIP_STR
1503                                         && ket->ptypes[3]==SR_KEMIP_INT
1504                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1505                                 ret = ((sr_kemi_fmnnsnn_f)(ket->func))(env_L->msg,
1506                                                 vps[0].n, vps[1].n, &vps[2].s, vps[3].n, vps[4].n);
1507                                 return sr_kemi_lua_return_int(L, ket, ret);
1508                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1509                                         && ket->ptypes[1]==SR_KEMIP_INT
1510                                         && ket->ptypes[2]==SR_KEMIP_INT
1511                                         && ket->ptypes[3]==SR_KEMIP_STR
1512                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1513                                 ret = ((sr_kemi_fmnnnss_f)(ket->func))(env_L->msg,
1514                                                 vps[0].n, vps[1].n, vps[2].n, &vps[3].s, &vps[4].s);
1515                                 return sr_kemi_lua_return_int(L, ket, ret);
1516                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1517                                         && ket->ptypes[1]==SR_KEMIP_INT
1518                                         && ket->ptypes[2]==SR_KEMIP_INT
1519                                         && ket->ptypes[3]==SR_KEMIP_STR
1520                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1521                                 ret = ((sr_kemi_fmnnnsn_f)(ket->func))(env_L->msg,
1522                                                 vps[0].n, vps[1].n, vps[2].n, &vps[3].s, vps[4].n);
1523                                 return sr_kemi_lua_return_int(L, ket, ret);
1524                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1525                                         && ket->ptypes[1]==SR_KEMIP_INT
1526                                         && ket->ptypes[2]==SR_KEMIP_INT
1527                                         && ket->ptypes[3]==SR_KEMIP_INT
1528                                         && ket->ptypes[4]==SR_KEMIP_STR) {
1529                                 ret = ((sr_kemi_fmnnnns_f)(ket->func))(env_L->msg,
1530                                                 vps[0].n, vps[1].n, vps[2].n, vps[3].n, &vps[4].s);
1531                                 return sr_kemi_lua_return_int(L, ket, ret);
1532                         } else if(ket->ptypes[0]==SR_KEMIP_INT
1533                                         && ket->ptypes[1]==SR_KEMIP_INT
1534                                         && ket->ptypes[2]==SR_KEMIP_INT
1535                                         && ket->ptypes[3]==SR_KEMIP_INT
1536                                         && ket->ptypes[4]==SR_KEMIP_INT) {
1537                                 ret = ((sr_kemi_fmnnnnn_f)(ket->func))(env_L->msg,
1538                                                 vps[0].n, vps[1].n, vps[2].n, vps[3].n, vps[4].n);
1539                                 return sr_kemi_lua_return_int(L, ket, ret);
1540                         } else {
1541                                 LM_ERR("invalid parameters for: %.*s\n", fname->len, fname->s);
1542                                 return app_lua_return_false(L);
1543                         }
1544                 break;
1545                 case 6:
1546                         if(ket->ptypes[0]==SR_KEMIP_STR
1547                                         && ket->ptypes[1]==SR_KEMIP_STR
1548                                         && ket->ptypes[2]==SR_KEMIP_STR
1549                                         && ket->ptypes[3]==SR_KEMIP_STR
1550                                         && ket->ptypes[4]==SR_KEMIP_STR
1551                                         && ket->ptypes[5]==SR_KEMIP_STR) {
1552                                 ret = ((sr_kemi_fmssssss_f)(ket->func))(env_L->msg,
1553                                                 &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s,
1554                                                 &vps[4].s, &vps[5].s);
1555                                 return sr_kemi_lua_return_int(L, ket, ret);
1556                         } else {
1557                                 LM_ERR("invalid parameters for: %.*s\n",
1558                                                 fname->len, fname->s);
1559                                 return app_lua_return_false(L);
1560                         }
1561                 break;
1562                 default:
1563                         LM_ERR("invalid parameters for: %.*s\n",
1564                                         fname->len, fname->s);
1565                         return app_lua_return_false(L);
1566         }
1567 }
1568
1569 /**
1570  *
1571  */
1572 int sr_kemi_exec_func(lua_State* L, str *mname, int midx, str *fname)
1573 {
1574         int pdelta;
1575         sr_kemi_t *ket = NULL;
1576         sr_lua_env_t *env_L;
1577
1578         env_L = sr_lua_env_get();
1579
1580         if(env_L==NULL || env_L->msg==NULL) {
1581                 LM_ERR("invalid Lua environment attributes\n");
1582                 return app_lua_return_false(L);
1583         }
1584
1585         ket = sr_kemi_lookup(mname, midx, fname);
1586         if(ket==NULL) {
1587                 LM_ERR("cannot find function (%d): %.*s.%.*s\n", midx,
1588                                 (mname && mname->len>0)?mname->len:0,
1589                                 (mname && mname->len>0)?mname->s:"",
1590                                 fname->len, fname->s);
1591                 return app_lua_return_false(L);
1592         }
1593         if(mname->len<=0) {
1594                 pdelta = 1;
1595         } else {
1596                 pdelta = 3;
1597         }
1598         return sr_kemi_lua_exec_func_ex(L, ket, pdelta);
1599 }
1600
1601 /**
1602  *
1603  */
1604 int sr_kemi_lua_exec_func(lua_State* L, int eidx)
1605 {
1606         sr_kemi_t *ket;
1607         int ret;
1608         struct timeval tvb = {0}, tve = {0};
1609         struct timezone tz;
1610         unsigned int tdiff;
1611         lua_Debug dinfo;
1612
1613         ket = sr_kemi_lua_export_get(eidx);
1614         if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)
1615                         && is_printable(cfg_get(core, core_cfg, latency_log))) {
1616                 gettimeofday(&tvb, &tz);
1617         }
1618
1619         ret = sr_kemi_lua_exec_func_ex(L, ket, 0);
1620
1621         if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)
1622                         && is_printable(cfg_get(core, core_cfg, latency_log))) {
1623                 gettimeofday(&tve, &tz);
1624                 tdiff = (tve.tv_sec - tvb.tv_sec) * 1000000
1625                                    + (tve.tv_usec - tvb.tv_usec);
1626                 if(tdiff >= cfg_get(core, core_cfg, latency_limit_action)) {
1627                         memset(&dinfo, 0, sizeof(lua_Debug));
1628                         if(lua_getstack(L, 1, &dinfo)>0
1629                                                 && lua_getinfo(L, "nSl", &dinfo)>0) {
1630                                 LOG(cfg_get(core, core_cfg, latency_log),
1631                                                 "alert - action KSR.%s%s%s(...)"
1632                                                 " took too long [%u us] (%s:%d - %s [%s])\n",
1633                                                 (ket->mname.len>0)?ket->mname.s:"",
1634                                                 (ket->mname.len>0)?".":"", ket->fname.s,
1635                                                 tdiff,
1636                                                 (dinfo.short_src[0])?dinfo.short_src:"<unknown>",
1637                                                 dinfo.currentline,
1638                                                 (dinfo.name)?dinfo.name:"<unknown>",
1639                                                 (dinfo.what)?dinfo.what:"<unknown>");
1640                         } else {
1641                                 LOG(cfg_get(core, core_cfg, latency_log),
1642                                                 "alert - action KSR.%s%s%s(...)"
1643                                                 " took too long [%u us]\n",
1644                                                 (ket->mname.len>0)?ket->mname.s:"",
1645                                                 (ket->mname.len>0)?".":"", ket->fname.s,
1646                                                 tdiff);
1647                         }
1648                 }
1649         }
1650
1651         return ret;
1652 }
1653
1654 /**
1655  *
1656  */
1657 static int sr_kemi_lua_modf (lua_State *L)
1658 {
1659         int ret;
1660         char *luav[MAX_ACTIONS];
1661         char *argv[MAX_ACTIONS];
1662         int argc;
1663         int i;
1664         int mod_type;
1665         struct run_act_ctx ra_ctx;
1666         struct action *act;
1667         ksr_cmd_export_t* expf;
1668         sr_lua_env_t *env_L;
1669
1670         ret = 1;
1671         act = NULL;
1672         argc = 0;
1673         memset(luav, 0, MAX_ACTIONS*sizeof(char*));
1674         memset(argv, 0, MAX_ACTIONS*sizeof(char*));
1675         env_L = sr_lua_env_get();
1676         if(env_L->msg==NULL)
1677                 goto error;
1678
1679 #if 0
1680         app_lua_dump_stack(L);
1681 #endif
1682         argc = lua_gettop(L);
1683         if(argc==0)
1684         {
1685                 LM_ERR("name of module function not provided\n");
1686                 goto error;
1687         }
1688         if(argc>=MAX_ACTIONS)
1689         {
1690                 LM_ERR("too many parameters\n");
1691                 goto error;
1692         }
1693         /* first is function name, then parameters */
1694         for(i=1; i<=argc; i++)
1695         {
1696                 if (!lua_isstring(L, i))
1697                 {
1698                         LM_ERR("invalid parameter type (%d)\n", i);
1699                         goto error;
1700                 }
1701                 luav[i-1] = (char*)lua_tostring(L, i);
1702         }
1703         /* pkg copy only parameters */
1704         for(i=1; i<MAX_ACTIONS; i++)
1705         {
1706                 if(luav[i]!=NULL)
1707                 {
1708                         argv[i] = (char*)pkg_malloc(strlen(luav[i])+1);
1709                         if(argv[i]==NULL)
1710                         {
1711                                 PKG_MEM_ERROR;
1712                                 goto error;
1713                         }
1714                         strcpy(argv[i], luav[i]);
1715                 }
1716         }
1717
1718         expf = find_export_record(luav[0], argc-1, 0);
1719         if (expf==NULL) {
1720                 LM_ERR("function '%s' is not available\n", luav[0]);
1721                 goto error;
1722         }
1723         /* check fixups */
1724         if (expf->fixup!=NULL && expf->free_fixup==NULL) {
1725                 LM_ERR("function '%s' has fixup - cannot be used\n", luav[0]);
1726                 goto error;
1727         }
1728         switch(expf->param_no) {
1729                 case 0:
1730                         mod_type = MODULE0_T;
1731                         break;
1732                 case 1:
1733                         mod_type = MODULE1_T;
1734                         break;
1735                 case 2:
1736                         mod_type = MODULE2_T;
1737                         break;
1738                 case 3:
1739                         mod_type = MODULE3_T;
1740                         break;
1741                 case 4:
1742                         mod_type = MODULE4_T;
1743                         break;
1744                 case 5:
1745                         mod_type = MODULE5_T;
1746                         break;
1747                 case 6:
1748                         mod_type = MODULE6_T;
1749                         break;
1750                 case VAR_PARAM_NO:
1751                         mod_type = MODULEX_T;
1752                         break;
1753                 default:
1754                         LM_ERR("unknown/bad definition for function '%s' (%d params)\n",
1755                                         luav[0], expf->param_no);
1756                         goto error;
1757         }
1758
1759         act = mk_action(mod_type,  argc+1   /* number of (type, value) pairs */,
1760                                         MODEXP_ST, expf,    /* function */
1761                                         NUMBER_ST, argc-1,  /* parameter number */
1762                                         STRING_ST, argv[1], /* param. 1 */
1763                                         STRING_ST, argv[2], /* param. 2 */
1764                                         STRING_ST, argv[3], /* param. 3 */
1765                                         STRING_ST, argv[4], /* param. 4 */
1766                                         STRING_ST, argv[5], /* param. 5 */
1767                                         STRING_ST, argv[6]  /* param. 6 */
1768                         );
1769
1770         if (act==NULL) {
1771                 LM_ERR("action structure could not be created for '%s'\n", luav[0]);
1772                 goto error;
1773         }
1774
1775         /* handle fixups */
1776         if (expf->fixup) {
1777                 if(argc==1)
1778                 { /* no parameters */
1779                         if(expf->fixup(0, 0)<0)
1780                         {
1781                                 LM_ERR("Error in fixup (0) for '%s'\n", luav[0]);
1782                                 goto error;
1783                         }
1784                 } else {
1785                         for(i=1; i<argc; i++)
1786                         {
1787                                 if(expf->fixup(&(act->val[i+1].u.data), i)<0)
1788                                 {
1789                                         LM_ERR("Error in fixup (%d) for '%s'\n", i, luav[0]);
1790                                         goto error;
1791                                 }
1792                                 act->val[i+1].type = MODFIXUP_ST;
1793                         }
1794                 }
1795         }
1796         init_run_actions_ctx(&ra_ctx);
1797         ret = do_action(&ra_ctx, act, env_L->msg);
1798
1799         /* free fixups */
1800         if (expf->fixup) {
1801                 for(i=1; i<argc; i++)
1802                 {
1803                         if ((act->val[i+1].type == MODFIXUP_ST) && (act->val[i+1].u.data))
1804                         {
1805                                 expf->free_fixup(&(act->val[i+1].u.data), i);
1806                         }
1807                 }
1808         }
1809         pkg_free(act);
1810         for(i=0; i<MAX_ACTIONS; i++)
1811         {
1812                 if(argv[i]!=NULL) pkg_free(argv[i]);
1813                 argv[i] = 0;
1814         }
1815         lua_pushinteger(L, ret);
1816         return 1;
1817
1818 error:
1819         if(act!=NULL)
1820                 pkg_free(act);
1821         for(i=0; i<MAX_ACTIONS; i++)
1822         {
1823                 if(argv[i]!=NULL) pkg_free(argv[i]);
1824                 argv[i] = 0;
1825         }
1826         lua_pushinteger(L, -1);
1827         return 1;
1828 }
1829
1830 /**
1831  *
1832  */
1833 static int sr_kemi_lua_exit (lua_State *L)
1834 {
1835         str *s;
1836
1837         LM_DBG("script exit call\n");
1838         s = sr_kemi_lua_exit_string_get();
1839         lua_getglobal(L, "error");
1840         lua_pushstring(L, s->s);
1841         lua_call(L, 1, 0);
1842         return 0;
1843 }
1844
1845 /**
1846  *
1847  */
1848 static int sr_kemi_lua_drop (lua_State *L)
1849 {
1850         str *s;
1851
1852         LM_DBG("script drop call\n");
1853         sr_kemi_core_set_drop(NULL);
1854         s = sr_kemi_lua_exit_string_get();
1855         lua_getglobal(L, "error");
1856         lua_pushstring(L, s->s);
1857         lua_call(L, 1, 0);
1858         return 0;
1859 }
1860
1861 /**
1862  *
1863  */
1864 static int sr_kemi_lua_probe (lua_State *L)
1865 {
1866         LM_DBG("someone probing from lua\n");
1867         return 0;
1868 }
1869
1870 /**
1871  *
1872  */
1873 static const luaL_Reg _sr_kemi_x_Map [] = {
1874         {"modf",      sr_kemi_lua_modf},
1875         {"exit",      sr_kemi_lua_exit},
1876         {"drop",      sr_kemi_lua_drop},
1877         {"probe",     sr_kemi_lua_probe},
1878         {NULL, NULL}
1879 };
1880
1881
1882 /**
1883  *
1884  */
1885 luaL_Reg *_sr_KSRMethods = NULL;
1886
1887 #define SR_LUA_KSR_MODULES_SIZE 256
1888 #define SR_LUA_KSR_METHODS_SIZE (SR_KEMI_LUA_EXPORT_SIZE + SR_LUA_KSR_MODULES_SIZE)
1889
1890 /**
1891  *
1892  */
1893 void lua_sr_kemi_register_libs(lua_State *L)
1894 {
1895         luaL_Reg *_sr_crt_KSRMethods = NULL;
1896         sr_kemi_module_t *emods = NULL;
1897         int emods_size = 0;
1898         int i;
1899         int k;
1900         int n;
1901         char mname[128];
1902
1903 #if 0
1904         /* dynamic lookup on function name */
1905         lua_sr_kemi_register_core(L);
1906         lua_sr_kemi_register_modules(L);
1907 #endif
1908
1909         _sr_KSRMethods = malloc(SR_LUA_KSR_METHODS_SIZE * sizeof(luaL_Reg));
1910         if(_sr_KSRMethods==NULL) {
1911                 LM_ERR("no more pkg memory\n");
1912                 return;
1913         }
1914         memset(_sr_KSRMethods, 0, SR_LUA_KSR_METHODS_SIZE * sizeof(luaL_Reg));
1915
1916         emods_size = sr_kemi_modules_size_get();
1917         emods = sr_kemi_modules_get();
1918
1919         n = 0;
1920         _sr_crt_KSRMethods = _sr_KSRMethods;
1921         if(emods_size==0 || emods[0].kexp==NULL) {
1922                 LM_ERR("no kemi exports registered\n");
1923                 return;
1924         }
1925
1926         for(i=0; emods[0].kexp[i].func!=NULL; i++) {
1927                 if(_ksr_app_lua_log_mode & KSR_APP_LUA_LOG_EXPORTS) {
1928                         LM_DBG("exporting KSR.%s(...)\n", emods[0].kexp[i].fname.s);
1929                 }
1930                 _sr_crt_KSRMethods[i].name = emods[0].kexp[i].fname.s;
1931                 _sr_crt_KSRMethods[i].func =
1932                         sr_kemi_lua_export_associate(&emods[0].kexp[i]);
1933                 if(_sr_crt_KSRMethods[i].func == NULL) {
1934                         LM_ERR("failed to associate kemi function with lua export\n");
1935                         free(_sr_KSRMethods);
1936                         _sr_KSRMethods = NULL;
1937                         return;
1938                 }
1939                 n++;
1940         }
1941
1942         luaL_openlib(L, "KSR", _sr_crt_KSRMethods, 0);
1943
1944         luaL_openlib(L, "KSR.x",  _sr_kemi_x_Map, 0);
1945
1946         /* registered kemi modules */
1947         if(emods_size>1) {
1948                 for(k=1; k<emods_size; k++) {
1949                         n++;
1950                         _sr_crt_KSRMethods = _sr_KSRMethods + n;
1951                         snprintf(mname, 128, "KSR.%s", emods[k].kexp[0].mname.s);
1952                         for(i=0; emods[k].kexp[i].func!=NULL; i++) {
1953                                 if(_ksr_app_lua_log_mode & KSR_APP_LUA_LOG_EXPORTS) {
1954                                         LM_DBG("exporting %s.%s(...)\n", mname,
1955                                                         emods[k].kexp[i].fname.s);
1956                                 }
1957                                 _sr_crt_KSRMethods[i].name = emods[k].kexp[i].fname.s;
1958                                 _sr_crt_KSRMethods[i].func =
1959                                         sr_kemi_lua_export_associate(&emods[k].kexp[i]);
1960                                 if(_sr_crt_KSRMethods[i].func == NULL) {
1961                                         LM_ERR("failed to associate kemi function with func export\n");
1962                                         free(_sr_KSRMethods);
1963                                         _sr_KSRMethods = NULL;
1964                                         return;
1965                                 }
1966                                 n++;
1967                         }
1968                         if(!lua_checkstack(L, i+8)) {
1969                                 LM_ERR("not enough Lua stack capacity\n");
1970                                 exit(-1);
1971                         }
1972                         luaL_openlib(L, mname, _sr_crt_KSRMethods, 0);
1973                         if(_ksr_app_lua_log_mode & KSR_APP_LUA_LOG_EXPORTS) {
1974                                 LM_DBG("initializing kemi sub-module: %s (%s) (%d/%d/%d)\n",
1975                                                 mname, emods[k].kexp[0].mname.s, i, k, n);
1976                         }
1977                 }
1978         }
1979         LM_DBG("module 'KSR' has been initialized (%d/%d)\n", emods_size, n);
1980 }
1981
1982 static const char* app_lua_rpc_api_list_doc[2] = {
1983         "list kemi exports to lua",
1984         0
1985 };
1986
1987 static void app_lua_rpc_api_list(rpc_t* rpc, void* ctx)
1988 {
1989         int i;
1990         int n;
1991         sr_kemi_t *ket;
1992         void* th;
1993         void* sh;
1994         void* ih;
1995
1996         if (rpc->add(ctx, "{", &th) < 0) {
1997                 rpc->fault(ctx, 500, "Internal error root reply");
1998                 return;
1999         }
2000
2001         /* count the number of exported functions */
2002         n = 0;
2003         for(i=0; i<SR_KEMI_LUA_EXPORT_SIZE; i++) {
2004                 ket = sr_kemi_lua_export_get(i);
2005                 if(ket==NULL) continue;
2006                 n++;
2007         }
2008
2009         if(rpc->struct_add(th, "d[",
2010                                 "msize", n,
2011                                 "methods",  &ih)<0)
2012         {
2013                 rpc->fault(ctx, 500, "Internal error array structure");
2014                 return;
2015         }
2016         for(i=0; i<SR_KEMI_LUA_EXPORT_SIZE; i++) {
2017                 ket = sr_kemi_lua_export_get(i);
2018                 if(ket==NULL) continue;
2019                 if(rpc->struct_add(ih, "{", "func", &sh)<0) {
2020                         rpc->fault(ctx, 500, "Internal error internal structure");
2021                         return;
2022                 }
2023                 if(rpc->struct_add(sh, "SSSS",
2024                                 "ret", sr_kemi_param_map_get_name(ket->rtype),
2025                                 "module", &ket->mname,
2026                                 "name", &ket->fname,
2027                                 "params", sr_kemi_param_map_get_params(ket->ptypes))<0) {
2028                         LM_ERR("failed to add the structure with attributes (%d)\n", i);
2029                         rpc->fault(ctx, 500, "Internal error creating dest struct");
2030                         return;
2031                 }
2032         }
2033 }
2034
2035 /*** RPC implementation ***/
2036
2037 static const char* app_lua_rpc_reload_doc[2] = {
2038         "Reload lua script",
2039         0
2040 };
2041
2042 static const char* app_lua_rpc_list_doc[2] = {
2043         "list lua scripts",
2044         0
2045 };
2046
2047 static void app_lua_rpc_reload(rpc_t* rpc, void* ctx)
2048 {
2049         int pos = -1;
2050
2051         rpc->scan(ctx, "*d", &pos);
2052         LM_DBG("selected index: %d\n", pos);
2053         if(lua_sr_reload_script(pos)<0)
2054                 rpc->fault(ctx, 500, "Reload Failed");
2055         return;
2056 }
2057
2058 static void app_lua_rpc_list(rpc_t* rpc, void* ctx)
2059 {
2060         int i;
2061         sr_lua_load_t *list = NULL, *li;
2062         if(lua_sr_list_script(&list)<0)
2063         {
2064                 LM_ERR("Can't get loaded scripts\n");
2065                 return;
2066         }
2067         if(list)
2068         {
2069                 li = list;
2070                 i = 0;
2071                 while(li)
2072                 {
2073                         rpc->rpl_printf(ctx, "%d: [%s]", i, li->script);
2074                         li = li->next;
2075                         i += 1;
2076                 }
2077         }
2078         else {
2079                 rpc->rpl_printf(ctx,"No scripts loaded");
2080         }
2081         return;
2082 }
2083
2084 rpc_export_t app_lua_rpc_cmds[] = {
2085         {"app_lua.reload", app_lua_rpc_reload,
2086                 app_lua_rpc_reload_doc, 0},
2087         {"app_lua.list", app_lua_rpc_list,
2088                 app_lua_rpc_list_doc, 0},
2089         {"app_lua.api_list", app_lua_rpc_api_list,
2090                 app_lua_rpc_api_list_doc, 0},
2091         {0, 0, 0, 0}
2092 };
2093
2094 /**
2095  * register RPC commands
2096  */
2097 int app_lua_init_rpc(void)
2098 {
2099         if (rpc_register_array(app_lua_rpc_cmds)!=0)
2100         {
2101                 LM_ERR("failed to register RPC commands\n");
2102                 return -1;
2103         }
2104         return 0;
2105 }
2106
2107 /**
2108  *
2109  */
2110 int bind_app_lua(app_lua_api_t* api)
2111 {
2112         if (!api) {
2113                 ERR("Invalid parameter value\n");
2114                 return -1;
2115         }
2116         api->env_get_f = sr_lua_env_get;
2117         api->openlibs_register_f = app_lua_openlibs_register;
2118         return 0;
2119 }