i understood that module functions can now have an arbitrary number of string, int and pseudo var arguments, where string arguments can possibly also contain pseudo variables.
some time ago i asked an example on how this is done, but didn't get any reply. so i'll try again. for example, allow_trusted function is now defined like this:
{"allow_trusted", (cmd_function)allow_trusted_2, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, REQUEST_ROUTE | FAILURE_ROUTE},
how can i add a third argument to the function without needing to define yet another fixup_pvar_pvar_something?
-- juha
On Oct 09, 2010 at 17:25, Juha Heinanen jh@tutpro.com wrote:
i understood that module functions can now have an arbitrary number of string, int and pseudo var arguments, where string arguments can possibly also contain pseudo variables.
some time ago i asked an example on how this is done, but didn't get any reply. so i'll try again. for example, allow_trusted function is now defined like this:
{"allow_trusted", (cmd_function)allow_trusted_2, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, REQUEST_ROUTE | FAILURE_ROUTE},
how can i add a third argument to the function without needing to define yet another fixup_pvar_pvar_something?
You cannot use fixup_pvar_pvar for more then 2 parameters. A lot of the fixup functions check the number of parameters and return error for more then 2. However in the case of fixup_pvar_pvar(), you can replace it with fixup_pvar_all() (and fixup_free_pvar_all).
In your case replacing 2 with 3 and pvar_pvar with pvar_all should work, e.g.: {"allow_trusted3", (cmd_function)allow_trusted_2, 3, fixup_pvar_all, fixup_free_pvar_all, REQUEST_ROUTE | FAILURE_ROUTE},
You can use this way to define functions that accept up to 6 parameters.
If you don't care about pvar arguments in strings (which IMHO should be slowly obsoleted), then you can write a normal module function that accepts strings as parameters (uses directly the char* arguments, without any get_str_fparam(...)) and set the fixups to 0. The core will take care and convert the arguments to string before calling your function.
I you want variable number of parameters, the module function declaration should look like: {"foov", (cmd_function)foo_var, VAR_PARAM_NO, 0, 0, REQUEST_ROUTE}
static int foo_var(struct sip_msg* msg, int argc, action_u_t argv[]) { int i; for (i = 0; i < argc; i++) do_something(argv[i].u.string); return 1; }
If you want to use fixups and variable number of parameters, the fixups look the same way as normal fixups (fixup(void** param, int param_no)).
For more examples see modules_s/print/print.c (uses the ser modules interface without free_fixup, but that's the only difference).
Andrei
andrei,
thanks for your explanation regarding module function params. this looks to be the way to go when there is variable number of args and some of them are strings and some are pvars:
I you want variable number of parameters, the module function declaration should look like: {"foov", (cmd_function)foo_var, VAR_PARAM_NO, 0, 0, REQUEST_ROUTE}
static int foo_var(struct sip_msg* msg, int argc, action_u_t argv[]) { int i; for (i = 0; i < argc; i++) do_something(argv[i].u.string); return 1; }
since there is no way to specify max number of params, argc value needs to be tested in the function. also, if some params are integers, int values need to be obtained by converting them from digit strings.
-- juha
andrei,
one question regarding this:
static int foo_var(struct sip_msg* msg, int argc, action_u_t argv[]) { int i; for (i = 0; i < argc; i++) do_something(argv[i].u.string); return 1; }
what is value of argc if there is no params? why argc tells the number of params - 1 rather than the number of params?
-- juha
On Oct 11, 2010 at 15:19, Juha Heinanen jh@tutpro.com wrote:
Andrei Pelinescu-Onciul writes:
static int foo_var(struct sip_msg* msg, int argc, action_u_t argv[]) { int i; for (i = 0; i < argc; i++) do_something(argv[i].u.string); return 1; }
are both argv[i].u.string and argv[i].u.str set or only the first?
Both of them. argv[i].u.string == argv[i].u.str.s (union) argv[i].u.str.len is set if you don't use your own fixups (if you do, the value is undefined).
Andrei
2010/10/11 Andrei Pelinescu-Onciul andrei@iptel.org:
You cannot use fixup_pvar_pvar for more then 2 parameters. A lot of the fixup functions check the number of parameters and return error for more then 2. However in the case of fixup_pvar_pvar(), you can replace it with fixup_pvar_all() (and fixup_free_pvar_all).
Hi, just a suggestion: It would be great if there was a documentation about fixup functions. Always I need to use one of them I end inspecting other modules code.
Regards.
Andrei Pelinescu-Onciul writes:
I you want variable number of parameters, the module function declaration should look like: {"foov", (cmd_function)foo_var, VAR_PARAM_NO, 0, 0, REQUEST_ROUTE}
andrei,
when i compare the above example with modules_s/print example:
{"printv", (cmd_function)print_f_var, VAR_PARAM_NO, 0, REQUEST_ROUTE},
the difference is that in foov example there is one field more. i guess it has something to do with s vs. k module interface. when i look sr_module.h there is ifdefs KAMAILIO_MOD_INTERFACE. is it possible to match and match module interfaces on per module basis by including
#define SER_MOD_INTERFACE
or
#define KAMAILIO_MOD_INTERFACE
in the main source file of the module?
it would really be nice if there were a wiki page about this (including the fixup stuff).
-- juha
On Oct 13, 2010 at 16:14, Juha Heinanen jh@tutpro.com wrote:
Andrei Pelinescu-Onciul writes:
I you want variable number of parameters, the module function declaration should look like: {"foov", (cmd_function)foo_var, VAR_PARAM_NO, 0, 0, REQUEST_ROUTE}
andrei,
when i compare the above example with modules_s/print example:
{"printv", (cmd_function)print_f_var, VAR_PARAM_NO, 0, REQUEST_ROUTE},
the difference is that in foov example there is one field more. i guess it has something to do with s vs. k module interface.
Yes, k interface has an extra free_fixup function.
when i look sr_module.h there is ifdefs KAMAILIO_MOD_INTERFACE. is it possible to match and match module interfaces on per module basis by including
#define SER_MOD_INTERFACE
or
#define KAMAILIO_MOD_INTERFACE
in the main source file of the module?
You should add it to the Makefile, e.g.: include ../../Makefile.defs
auto_gen= NAME=foo.so LIBS= DEFS+= -DSER_MOD_INTERFACE
include ../../Makefile.modules
If neither ser or k MOD_INTERFACE is defined, I think you'll probably get some compilation error.
it would really be nice if there were a wiki page about this (including the fixup stuff).
It should change during 3.2. I'll probably add a SR3.2_MODE_INTERFACE which will combine ser & k (actually all that is missing is exposing it to the modules, internally ser & k interfaces are converted to a more generic sr interface).
Andrei
Andrei Pelinescu-Onciul writes:
It should change during 3.2. I'll probably add a SR3.2_MODE_INTERFACE which will combine ser & k (actually all that is missing is exposing it to the modules, internally ser & k interfaces are converted to a more generic sr interface).
ok. while you are at it, how about making the interface a bit more user friendly. now all args are converted automatically to strings. it would nice, if i could list, which are converted to string and which to ints. something like this:
static cmd_export_t cmds[]={ {"print3", (cmd_function)print_f3, 3, "dss", REQUEST_ROUTE}, {0, 0, 0, 0, 0} };
/* 3 parameters, no fixup version */ static int print_f3(struct sip_msg* msg, int i1, char* s2, char* s3) { printf("%d%s%s\n", i1, s2, s3); return 1; }
or if all args for some reason need to be strings:
/* 3 parameters, no fixup version */ static int print_f3(struct sip_msg* msg, char* s1, char* s2, char* s3) { printf("%d%s%s\n", (int)s1, s2, s3); return 1; }
-- juha
Andrei Pelinescu-Onciul writes:
You should add it to the Makefile, e.g.: include ../../Makefile.defs
auto_gen= NAME=foo.so LIBS= DEFS+= -DSER_MOD_INTERFACE
include ../../Makefile.modules
how does the above work, it KAMAILIO_MOD_INTERFACE is defined by default? should it be first somehow undefined, because it is tested first in sr_module.h?
-- juha
On Oct 13, 2010 at 17:47, Juha Heinanen jh@tutpro.com wrote:
Andrei Pelinescu-Onciul writes:
You should add it to the Makefile, e.g.: include ../../Makefile.defs
auto_gen= NAME=foo.so LIBS= DEFS+= -DSER_MOD_INTERFACE
include ../../Makefile.modules
how does the above work, it KAMAILIO_MOD_INTERFACE is defined by default? should it be first somehow undefined, because it is tested first in sr_module.h?
It's not defined by default. If you look at all the kamailio modules, they have DEFS+= -DKAMAILIO_MOD_INTERFACE (this is one of the things the porting scripts did automatically).
Andrei
andrei,
i have to ask one more question about function arguments. i have defined
{"from_any_gw", (cmd_function)from_any_gw_2, 2, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
and if i try to call that function like this:
if (!from_any_gw(192.98.102.1, 2)) {
i get syntax error, but if i enclose 192.98.102.1 in quotes:
if (!from_any_gw("192.98.102.1", 2)) {
i do not get syntax error.
the question is, why i do not need to quote the second argument (2), even when it too is delivered to the function as a string and not as int?
-- juha
Andrei Pelinescu-Onciul writes:
You cannot use fixup_pvar_pvar for more then 2 parameters. A lot of the fixup functions check the number of parameters and return error for more then 2. However in the case of fixup_pvar_pvar(), you can replace it with fixup_pvar_all() (and fixup_free_pvar_all).
In your case replacing 2 with 3 and pvar_pvar with pvar_all should work, e.g.: {"allow_trusted3", (cmd_function)allow_trusted_2, 3, fixup_pvar_all, fixup_free_pvar_all, REQUEST_ROUTE | FAILURE_ROUTE},
the problem is that fixup_pvar_all has only been defined in mod_fix.c, not in mod_fix.h. can i just go and add it in mod_fix.h?
-- juha