- use same symbols names as app_python so these two modules cannot be used together
- use GIL for thread management
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,29 @@ |
1 |
+# |
|
2 |
+# WARNING: do not run this directly, it should be run by the master Makefile |
|
3 |
+ |
|
4 |
+include ../../Makefile.defs |
|
5 |
+auto_gen= |
|
6 |
+NAME=app_python3.so |
|
7 |
+ |
|
8 |
+# If you have multiple Python versions installed make sure to modify the |
|
9 |
+# the following to point to the correct instance. Module has been tested |
|
10 |
+# to work with 2.6 and 2.5. Python 2.4 has been only confirmed to compile, |
|
11 |
+# but no testing has been done with that. |
|
12 |
+PYTHON3?=python3 |
|
13 |
+ |
|
14 |
+PYTHON3_VERSION=${shell ${PYTHON3} -c "import distutils.sysconfig;print(distutils.sysconfig.get_config_var('VERSION'))"} |
|
15 |
+PYTHON3_LIBDIR=${shell ${PYTHON3} -c "import distutils.sysconfig;print(distutils.sysconfig.get_config_var('LIBDIR'))"} |
|
16 |
+PYTHON3_LDFLAGS=${shell ${PYTHON3} -c "import distutils.sysconfig;print(distutils.sysconfig.get_config_var('LINKFORSHARED'))"} |
|
17 |
+PYTHON3_INCDIR=${shell ${PYTHON3} -c "import distutils.sysconfig;print(distutils.sysconfig.get_python_inc())"} |
|
18 |
+ |
|
19 |
+LIBS=${shell ${PYTHON3}-config --libs} |
|
20 |
+ |
|
21 |
+ifeq ($(OS), freebsd) |
|
22 |
+LIBS+=-pthread |
|
23 |
+endif |
|
24 |
+ |
|
25 |
+DEFS+=-I${PYTHON3_INCDIR} |
|
26 |
+DEFS+=-DKAMAILIO_MOD_INTERFACE |
|
27 |
+ |
|
28 |
+include ../../Makefile.modules |
|
29 |
+ |
0 | 30 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,196 @@ |
1 |
+app_python Module |
|
2 |
+ |
|
3 |
+Maxim Sobolev |
|
4 |
+ |
|
5 |
+Edited by |
|
6 |
+ |
|
7 |
+Maxim Sobolev |
|
8 |
+ |
|
9 |
+ Copyright © 2010 Maxim Sobolev |
|
10 |
+ __________________________________________________________________ |
|
11 |
+ |
|
12 |
+ Table of Contents |
|
13 |
+ |
|
14 |
+ 1. Admin Guide |
|
15 |
+ |
|
16 |
+ 1. Overview |
|
17 |
+ 2. Dependencies |
|
18 |
+ |
|
19 |
+ 2.1. Kamailio Modules |
|
20 |
+ 2.2. External Libraries or Applications |
|
21 |
+ |
|
22 |
+ 3. Parameters |
|
23 |
+ |
|
24 |
+ 3.1. load (string) |
|
25 |
+ 3.2. script_name (string) |
|
26 |
+ 3.3. mod_init_function (string) |
|
27 |
+ 3.4. child_init_method (string) |
|
28 |
+ |
|
29 |
+ 4. Functions |
|
30 |
+ |
|
31 |
+ 4.1. python_exec(method [, args]) |
|
32 |
+ |
|
33 |
+ 5. RPC Commands |
|
34 |
+ |
|
35 |
+ 5.1. app_python.reload |
|
36 |
+ 5.2. app_python.api_list |
|
37 |
+ |
|
38 |
+ List of Examples |
|
39 |
+ |
|
40 |
+ 1.1. Set load parameter |
|
41 |
+ 1.2. Set mod_init_function parameter |
|
42 |
+ 1.3. Set child_init_method parameter |
|
43 |
+ 1.4. python_exec usage |
|
44 |
+ |
|
45 |
+Chapter 1. Admin Guide |
|
46 |
+ |
|
47 |
+ Table of Contents |
|
48 |
+ |
|
49 |
+ 1. Overview |
|
50 |
+ 2. Dependencies |
|
51 |
+ |
|
52 |
+ 2.1. Kamailio Modules |
|
53 |
+ 2.2. External Libraries or Applications |
|
54 |
+ |
|
55 |
+ 3. Parameters |
|
56 |
+ |
|
57 |
+ 3.1. load (string) |
|
58 |
+ 3.2. script_name (string) |
|
59 |
+ 3.3. mod_init_function (string) |
|
60 |
+ 3.4. child_init_method (string) |
|
61 |
+ |
|
62 |
+ 4. Functions |
|
63 |
+ |
|
64 |
+ 4.1. python_exec(method [, args]) |
|
65 |
+ |
|
66 |
+ 5. RPC Commands |
|
67 |
+ |
|
68 |
+ 5.1. app_python.reload |
|
69 |
+ 5.2. app_python.api_list |
|
70 |
+ |
|
71 |
+1. Overview |
|
72 |
+ |
|
73 |
+ This module allows executing Python scripts from config file, exporting |
|
74 |
+ functions to access the SIP message from Python. |
|
75 |
+ |
|
76 |
+ For some basic examples of Python scripts that can be used with this |
|
77 |
+ module, look at the files inside source tree located at |
|
78 |
+ 'modules/app_python/python_examples/'. |
|
79 |
+ |
|
80 |
+2. Dependencies |
|
81 |
+ |
|
82 |
+ 2.1. Kamailio Modules |
|
83 |
+ 2.2. External Libraries or Applications |
|
84 |
+ |
|
85 |
+2.1. Kamailio Modules |
|
86 |
+ |
|
87 |
+ The following modules must be loaded before this module: |
|
88 |
+ * none. |
|
89 |
+ |
|
90 |
+2.2. External Libraries or Applications |
|
91 |
+ |
|
92 |
+ The following libraries or applications must be installed before |
|
93 |
+ running Kamailio with this module loaded: |
|
94 |
+ * python-dev - Python devel library. |
|
95 |
+ |
|
96 |
+3. Parameters |
|
97 |
+ |
|
98 |
+ 3.1. load (string) |
|
99 |
+ 3.2. script_name (string) |
|
100 |
+ 3.3. mod_init_function (string) |
|
101 |
+ 3.4. child_init_method (string) |
|
102 |
+ |
|
103 |
+3.1. load (string) |
|
104 |
+ |
|
105 |
+ The path to the file with Python code to be executed from configuration |
|
106 |
+ file. |
|
107 |
+ |
|
108 |
+ Default value is “/usr/local/etc/kamailio/handler.py”. |
|
109 |
+ |
|
110 |
+ Example 1.1. Set load parameter |
|
111 |
+... |
|
112 |
+modparam("app_python", "load", "/usr/local/etc/kamailio/myscript.py") |
|
113 |
+... |
|
114 |
+ |
|
115 |
+3.2. script_name (string) |
|
116 |
+ |
|
117 |
+ This is same as "load" parameter, kept for backward compatibility with |
|
118 |
+ the older versions of the module. |
|
119 |
+ |
|
120 |
+3.3. mod_init_function (string) |
|
121 |
+ |
|
122 |
+ The Python function to be executed by this module when it is initialied |
|
123 |
+ by Kamailio. |
|
124 |
+ |
|
125 |
+ Default value is “mod_init”. |
|
126 |
+ |
|
127 |
+ Example 1.2. Set mod_init_function parameter |
|
128 |
+... |
|
129 |
+modparam("app_python", "mod_init_function", "my_mod_init") |
|
130 |
+... |
|
131 |
+ |
|
132 |
+3.4. child_init_method (string) |
|
133 |
+ |
|
134 |
+ The Python function to be executed by this module when a new worker |
|
135 |
+ process (child) is initialied by Kamailio. |
|
136 |
+ |
|
137 |
+ Default value is “child_init”. |
|
138 |
+ |
|
139 |
+ Example 1.3. Set child_init_method parameter |
|
140 |
+... |
|
141 |
+modparam("app_python", "child_init_method", "my_child_init") |
|
142 |
+... |
|
143 |
+ |
|
144 |
+4. Functions |
|
145 |
+ |
|
146 |
+ 4.1. python_exec(method [, args]) |
|
147 |
+ |
|
148 |
+4.1. python_exec(method [, args]) |
|
149 |
+ |
|
150 |
+ Execute the Python function with the name given by the parameter |
|
151 |
+ 'method'. Optionally can be provided a second string with parameters to |
|
152 |
+ be passed to the Python function. |
|
153 |
+ |
|
154 |
+ Both parameters can contain pseudo-variables. |
|
155 |
+ |
|
156 |
+ Example 1.4. python_exec usage |
|
157 |
+... |
|
158 |
+python_exec("my_python_function"); |
|
159 |
+python_exec("my_python_function", "my_params"); |
|
160 |
+python_exec("my_python_function", "$rU"); |
|
161 |
+... |
|
162 |
+ |
|
163 |
+5. RPC Commands |
|
164 |
+ |
|
165 |
+ 5.1. app_python.reload |
|
166 |
+ 5.2. app_python.api_list |
|
167 |
+ |
|
168 |
+5.1. app_python.reload |
|
169 |
+ |
|
170 |
+ IMPORTANT: not functional yet (can crash a running instance, use it |
|
171 |
+ only for testing). |
|
172 |
+ |
|
173 |
+ Marks the need to reload the js script. The actual reload is done by |
|
174 |
+ every working process when the next call to KEMI config is executed. |
|
175 |
+ |
|
176 |
+ Name: app_python.reload |
|
177 |
+ |
|
178 |
+ Parameters: none |
|
179 |
+ |
|
180 |
+ Example: |
|
181 |
+... |
|
182 |
+kamcmd app_python.reload |
|
183 |
+... |
|
184 |
+ |
|
185 |
+5.2. app_python.api_list |
|
186 |
+ |
|
187 |
+ List the functions available via Kemi framework. |
|
188 |
+ |
|
189 |
+ Name: app_python.api_list |
|
190 |
+ |
|
191 |
+ Parameters: none |
|
192 |
+ |
|
193 |
+ Example: |
|
194 |
+... |
|
195 |
+kamcmd app_python.api_list |
|
196 |
+... |
0 | 197 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+ |
|
2 |
+Example of using loggers in Python: |
|
3 |
+ |
|
4 |
+loadmodule "app_python.so" |
|
5 |
+modparam("app_python", "script_name", "/path/to/Loggers.py") |
|
6 |
+modparam("app_python", "mod_init_function", "mod_init") |
|
7 |
+modparam("app_python", "child_init_method", "child_init") |
|
8 |
+ |
|
9 |
+... |
|
10 |
+ |
|
11 |
+route |
|
12 |
+{ |
|
13 |
+ python_exec("TestLoggers", "Test Message\n"); |
|
14 |
+ ... |
|
15 |
+} |
|
16 |
+ |
0 | 17 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,544 @@ |
1 |
+/* |
|
2 |
+ * Copyright (C) 2009 Sippy Software, Inc., http://www.sippysoft.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 <Python.h> |
|
23 |
+#include <libgen.h> |
|
24 |
+ |
|
25 |
+#include "../../core/str.h" |
|
26 |
+#include "../../core/sr_module.h" |
|
27 |
+#include "../../core/mod_fix.h" |
|
28 |
+#include "../../core/kemi.h" |
|
29 |
+ |
|
30 |
+#include "python_exec.h" |
|
31 |
+#include "python_iface.h" |
|
32 |
+#include "python_msgobj.h" |
|
33 |
+#include "python_support.h" |
|
34 |
+#include "app_python_mod.h" |
|
35 |
+ |
|
36 |
+#include "mod_Router.h" |
|
37 |
+#include "mod_Core.h" |
|
38 |
+#include "mod_Ranks.h" |
|
39 |
+#include "mod_Logger.h" |
|
40 |
+ |
|
41 |
+#include "apy_kemi.h" |
|
42 |
+ |
|
43 |
+MODULE_VERSION |
|
44 |
+ |
|
45 |
+ |
|
46 |
+str _sr_python_load_file = str_init("/usr/local/etc/" NAME "/handler.py"); |
|
47 |
+static str mod_init_fname = str_init("mod_init"); |
|
48 |
+static str child_init_mname = str_init("child_init"); |
|
49 |
+ |
|
50 |
+static int mod_init(void); |
|
51 |
+static int child_init(int rank); |
|
52 |
+static void mod_destroy(void); |
|
53 |
+ |
|
54 |
+PyObject *_sr_apy_handler_obj; |
|
55 |
+ |
|
56 |
+char *dname = NULL, *bname = NULL; |
|
57 |
+ |
|
58 |
+int _apy_process_rank = 0; |
|
59 |
+ |
|
60 |
+PyThreadState *myThreadState; |
|
61 |
+ |
|
62 |
+/** module parameters */ |
|
63 |
+static param_export_t params[]={ |
|
64 |
+ {"script_name", PARAM_STR, &_sr_python_load_file }, |
|
65 |
+ {"load", PARAM_STR, &_sr_python_load_file }, |
|
66 |
+ {"mod_init_function", PARAM_STR, &mod_init_fname }, |
|
67 |
+ {"child_init_method", PARAM_STR, &child_init_mname }, |
|
68 |
+ {0,0,0} |
|
69 |
+}; |
|
70 |
+ |
|
71 |
+/* |
|
72 |
+ * Exported functions |
|
73 |
+ */ |
|
74 |
+static cmd_export_t cmds[] = { |
|
75 |
+ { "python_exec", (cmd_function)python_exec1, 1, fixup_spve_null, |
|
76 |
+ 0, ANY_ROUTE }, |
|
77 |
+ { "python_exec", (cmd_function)python_exec2, 2, fixup_spve_spve, |
|
78 |
+ 0, ANY_ROUTE }, |
|
79 |
+ { 0, 0, 0, 0, 0, 0 } |
|
80 |
+}; |
|
81 |
+ |
|
82 |
+/** module exports */ |
|
83 |
+struct module_exports exports = { |
|
84 |
+ "app_python3", /* module name */ |
|
85 |
+ RTLD_NOW | RTLD_GLOBAL, /* dlopen flags */ |
|
86 |
+ cmds, /* exported functions */ |
|
87 |
+ params, /* exported parameters */ |
|
88 |
+ 0, /* exported statistics */ |
|
89 |
+ 0, /* exported MI functions */ |
|
90 |
+ 0, /* exported pseudo-variables */ |
|
91 |
+ 0, /* extra processes */ |
|
92 |
+ mod_init, /* module initialization function */ |
|
93 |
+ (response_function) NULL, /* response handling function */ |
|
94 |
+ (destroy_function) mod_destroy, /* destroy function */ |
|
95 |
+ child_init /* per-child init function */ |
|
96 |
+}; |
|
97 |
+ |
|
98 |
+ |
|
99 |
+/** |
|
100 |
+ * |
|
101 |
+ */ |
|
102 |
+static int mod_init(void) |
|
103 |
+{ |
|
104 |
+ char *dname_src, *bname_src; |
|
105 |
+ int i; |
|
106 |
+ |
|
107 |
+ if(apy_sr_init_mod()<0) { |
|
108 |
+ LM_ERR("failed to init the sr mod\n"); |
|
109 |
+ return -1; |
|
110 |
+ } |
|
111 |
+ if(app_python_init_rpc()<0) { |
|
112 |
+ LM_ERR("failed to register RPC commands\n"); |
|
113 |
+ return -1; |
|
114 |
+ } |
|
115 |
+ |
|
116 |
+ dname_src = as_asciiz(&_sr_python_load_file); |
|
117 |
+ bname_src = as_asciiz(&_sr_python_load_file); |
|
118 |
+ |
|
119 |
+ if(dname_src==NULL || bname_src==NULL) |
|
120 |
+ { |
|
121 |
+ LM_ERR("no more pkg memory\n"); |
|
122 |
+ if(dname_src) pkg_free(dname_src); |
|
123 |
+ if(bname_src) pkg_free(bname_src); |
|
124 |
+ return -1; |
|
125 |
+ } |
|
126 |
+ |
|
127 |
+ dname = strdup(dirname(dname_src)); |
|
128 |
+ if(dname==NULL) { |
|
129 |
+ LM_ERR("no more system memory\n"); |
|
130 |
+ pkg_free(dname_src); |
|
131 |
+ pkg_free(bname_src); |
|
132 |
+ return -1; |
|
133 |
+ } |
|
134 |
+ if (strlen(dname) == 0) { |
|
135 |
+ free(dname); |
|
136 |
+ dname = malloc(2); |
|
137 |
+ if(dname==NULL) { |
|
138 |
+ LM_ERR("no more system memory\n"); |
|
139 |
+ pkg_free(dname_src); |
|
140 |
+ pkg_free(bname_src); |
|
141 |
+ return -1; |
|
142 |
+ } |
|
143 |
+ dname[0] = '.'; |
|
144 |
+ dname[1] = '\0'; |
|
145 |
+ } |
|
146 |
+ bname = strdup(basename(bname_src)); |
|
147 |
+ i = strlen(bname); |
|
148 |
+ if (bname[i - 1] == 'c' || bname[i - 1] == 'o') |
|
149 |
+ i -= 1; |
|
150 |
+ if (bname[i - 3] == '.' && bname[i - 2] == 'p' && bname[i - 1] == 'y') { |
|
151 |
+ bname[i - 3] = '\0'; |
|
152 |
+ } else { |
|
153 |
+ LM_ERR("%s: script_name doesn't look like a python script\n", |
|
154 |
+ _sr_python_load_file.s); |
|
155 |
+ pkg_free(dname_src); |
|
156 |
+ pkg_free(bname_src); |
|
157 |
+ return -1; |
|
158 |
+ } |
|
159 |
+ |
|
160 |
+ if(apy_load_script()<0) { |
|
161 |
+ pkg_free(dname_src); |
|
162 |
+ pkg_free(bname_src); |
|
163 |
+ LM_ERR("failed to load python script\n"); |
|
164 |
+ return -1; |
|
165 |
+ } |
|
166 |
+ |
|
167 |
+ pkg_free(dname_src); |
|
168 |
+ pkg_free(bname_src); |
|
169 |
+ return 0; |
|
170 |
+} |
|
171 |
+ |
|
172 |
+/** |
|
173 |
+ * |
|
174 |
+ */ |
|
175 |
+static int child_init(int rank) |
|
176 |
+{ |
|
177 |
+ _apy_process_rank = rank; |
|
178 |
+ return apy_init_script(rank); |
|
179 |
+} |
|
180 |
+ |
|
181 |
+/** |
|
182 |
+ * |
|
183 |
+ */ |
|
184 |
+static void mod_destroy(void) |
|
185 |
+{ |
|
186 |
+ if (dname) |
|
187 |
+ free(dname); // dname was strdup'ed |
|
188 |
+ if (bname) |
|
189 |
+ free(bname); // bname was strdup'ed |
|
190 |
+ |
|
191 |
+ destroy_mod_Core(); |
|
192 |
+ destroy_mod_Ranks(); |
|
193 |
+ destroy_mod_Logger(); |
|
194 |
+ destroy_mod_Router(); |
|
195 |
+} |
|
196 |
+ |
|
197 |
+ |
|
198 |
+#define PY_GIL_ENSURE gstate = PyGILState_Ensure(); |
|
199 |
+#define PY_GIL_RELEASE PyGILState_Release(gstate); |
|
200 |
+ |
|
201 |
+// #define PY_THREADSTATE_SWAP_IN PyThreadState_Swap(myThreadState); |
|
202 |
+// #define PY_THREADSTATE_SWAP_NULL PyThreadState_Swap(NULL); |
|
203 |
+#define PY_THREADSTATE_SWAP_IN |
|
204 |
+#define PY_THREADSTATE_SWAP_NULL |
|
205 |
+ |
|
206 |
+int apy_load_script(void) |
|
207 |
+{ |
|
208 |
+ PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs; |
|
209 |
+ PyThreadState *mainThreadState; |
|
210 |
+ PyGILState_STATE gstate; |
|
211 |
+ |
|
212 |
+ if (ap_init_modules() != 0) { |
|
213 |
+ return -1; |
|
214 |
+ } |
|
215 |
+ |
|
216 |
+ Py_Initialize(); |
|
217 |
+ PyEval_InitThreads(); |
|
218 |
+ myThreadState = PyThreadState_Get(); |
|
219 |
+ |
|
220 |
+ PY_GIL_ENSURE |
|
221 |
+ format_exc_obj = InitTracebackModule(); |
|
222 |
+ |
|
223 |
+ if (format_exc_obj == NULL || !PyCallable_Check(format_exc_obj)) |
|
224 |
+ { |
|
225 |
+ Py_XDECREF(format_exc_obj); |
|
226 |
+ PY_GIL_RELEASE |
|
227 |
+ return -1; |
|
228 |
+ } |
|
229 |
+ |
|
230 |
+ sys_path = PySys_GetObject("path"); |
|
231 |
+ /* PySys_GetObject doesn't pass reference! No need to DEREF */ |
|
232 |
+ if (sys_path == NULL) { |
|
233 |
+ if (!PyErr_Occurred()) |
|
234 |
+ PyErr_Format(PyExc_AttributeError, |
|
235 |
+ "'module' object 'sys' has no attribute 'path'"); |
|
236 |
+ python_handle_exception("mod_init"); |
|
237 |
+ Py_DECREF(format_exc_obj); |
|
238 |
+ PY_GIL_RELEASE |
|
239 |
+ return -1; |
|
240 |
+ } |
|
241 |
+ |
|
242 |
+ pDir = PyUnicode_FromString(dname); |
|
243 |
+ if (pDir == NULL) { |
|
244 |
+ if (!PyErr_Occurred()) |
|
245 |
+ PyErr_Format(PyExc_AttributeError, |
|
246 |
+ "PyUnicode_FromString() has failed"); |
|
247 |
+ python_handle_exception("mod_init"); |
|
248 |
+ Py_DECREF(format_exc_obj); |
|
249 |
+ PY_GIL_RELEASE |
|
250 |
+ return -1; |
|
251 |
+ } |
|
252 |
+ |
|
253 |
+ PyList_Insert(sys_path, 0, pDir); |
|
254 |
+ Py_DECREF(pDir); |
|
255 |
+ |
|
256 |
+ if (python_msgobj_init() != 0) { |
|
257 |
+ if (!PyErr_Occurred()) |
|
258 |
+ PyErr_SetString(PyExc_AttributeError, |
|
259 |
+ "python_msgobj_init() has failed"); |
|
260 |
+ python_handle_exception("mod_init"); |
|
261 |
+ Py_DECREF(format_exc_obj); |
|
262 |
+ PY_GIL_RELEASE |
|
263 |
+ return -1; |
|
264 |
+ } |
|
265 |
+ |
|
266 |
+ pModule = PyImport_ImportModule(bname); |
|
267 |
+ if (pModule == NULL) { |
|
268 |
+ PyErr_PrintEx(0); |
|
269 |
+ if (!PyErr_Occurred()) |
|
270 |
+ PyErr_Format(PyExc_ImportError, "No module named '%s'", bname); |
|
271 |
+ python_handle_exception("mod_init"); |
|
272 |
+ Py_DECREF(format_exc_obj); |
|
273 |
+ PY_GIL_RELEASE |
|
274 |
+ |
|
275 |
+ return -1; |
|
276 |
+ } |
|
277 |
+ |
|
278 |
+ pFunc = PyObject_GetAttrString(pModule, mod_init_fname.s); |
|
279 |
+ Py_DECREF(pModule); |
|
280 |
+ |
|
281 |
+ /* pFunc is a new reference */ |
|
282 |
+ |
|
283 |
+ if (pFunc == NULL) { |
|
284 |
+ if (!PyErr_Occurred()) |
|
285 |
+ PyErr_Format(PyExc_AttributeError, |
|
286 |
+ "'module' object '%s' has no attribute '%s'", |
|
287 |
+ bname, mod_init_fname.s); |
|
288 |
+ python_handle_exception("mod_init"); |
|
289 |
+ Py_DECREF(format_exc_obj); |
|
290 |
+ Py_XDECREF(pFunc); |
|
291 |
+ PY_GIL_RELEASE |
|
292 |
+ return -1; |
|
293 |
+ } |
|
294 |
+ |
|
295 |
+ if (!PyCallable_Check(pFunc)) { |
|
296 |
+ if (!PyErr_Occurred()) |
|
297 |
+ PyErr_Format(PyExc_AttributeError, |
|
298 |
+ "module object '%s' has is not callable attribute '%s'", |
|
299 |
+ bname, mod_init_fname.s); |
|
300 |
+ python_handle_exception("mod_init"); |
|
301 |
+ Py_DECREF(format_exc_obj); |
|
302 |
+ Py_XDECREF(pFunc); |
|
303 |
+ PY_GIL_RELEASE |
|
304 |
+ return -1; |
|
305 |
+ } |
|
306 |
+ |
|
307 |
+ |
|
308 |
+ pArgs = PyTuple_New(0); |
|
309 |
+ if (pArgs == NULL) { |
|
310 |
+ python_handle_exception("mod_init"); |
|
311 |
+ Py_DECREF(format_exc_obj); |
|
312 |
+ Py_DECREF(pFunc); |
|
313 |
+ PY_GIL_RELEASE |
|
314 |
+ return -1; |
|
315 |
+ } |
|
316 |
+ |
|
317 |
+ _sr_apy_handler_obj = PyObject_CallObject(pFunc, pArgs); |
|
318 |
+ |
|
319 |
+ Py_XDECREF(pFunc); |
|
320 |
+ Py_XDECREF(pArgs); |
|
321 |
+ |
|
322 |
+ if (_sr_apy_handler_obj == Py_None) { |
|
323 |
+ if (!PyErr_Occurred()) |
|
324 |
+ PyErr_Format(PyExc_TypeError, |
|
325 |
+ "Function '%s' of module '%s' has returned None." |
|
326 |
+ " Should be a class instance.", mod_init_fname.s, bname); |
|
327 |
+ python_handle_exception("mod_init"); |
|
328 |
+ Py_DECREF(format_exc_obj); |
|
329 |
+ PY_GIL_RELEASE |
|
330 |
+ return -1; |
|
331 |
+ } |
|
332 |
+ |
|
333 |
+ if (PyErr_Occurred()) { |
|
334 |
+ python_handle_exception("mod_init"); |
|
335 |
+ Py_XDECREF(_sr_apy_handler_obj); |
|
336 |
+ Py_DECREF(format_exc_obj); |
|
337 |
+ PY_GIL_RELEASE |
|
338 |
+ return -1; |
|
339 |
+ } |
|
340 |
+ |
|
341 |
+ if (_sr_apy_handler_obj == NULL) { |
|
342 |
+ LM_ERR("PyObject_CallObject() returned NULL but no exception!\n"); |
|
343 |
+ if (!PyErr_Occurred()) |
|
344 |
+ PyErr_Format(PyExc_TypeError, |
|
345 |
+ "Function '%s' of module '%s' has returned not returned" |
|
346 |
+ " object. Should be a class instance.", |
|
347 |
+ mod_init_fname.s, bname); |
|
348 |
+ python_handle_exception("mod_init"); |
|
349 |
+ Py_DECREF(format_exc_obj); |
|
350 |
+ PY_GIL_RELEASE |
|
351 |
+ return -1; |
|
352 |
+ } |
|
353 |
+ |
|
354 |
+ //myThreadState = PyThreadState_New(mainThreadState->interp); |
|
355 |
+ PY_GIL_RELEASE |
|
356 |
+ return 0; |
|
357 |
+} |
|
358 |
+ |
|
359 |
+int apy_init_script(int rank) |
|
360 |
+{ |
|
361 |
+ PyObject *pFunc, *pArgs, *pValue, *pResult; |
|
362 |
+ int rval; |
|
363 |
+ char *classname; |
|
364 |
+ PyGILState_STATE gstate; |
|
365 |
+ |
|
366 |
+ |
|
367 |
+ PY_GIL_ENSURE |
|
368 |
+ PY_THREADSTATE_SWAP_IN |
|
369 |
+ |
|
370 |
+ // get instance class name |
|
371 |
+ classname = get_instance_class_name(_sr_apy_handler_obj); |
|
372 |
+ if (classname == NULL) |
|
373 |
+ { |
|
374 |
+ if (!PyErr_Occurred()) |
|
375 |
+ PyErr_Format(PyExc_AttributeError, |
|
376 |
+ "'module' instance has no class name"); |
|
377 |
+ python_handle_exception("child_init"); |
|
378 |
+ Py_DECREF(format_exc_obj); |
|
379 |
+ PY_THREADSTATE_SWAP_NULL |
|
380 |
+ PY_GIL_RELEASE |
|
381 |
+ return -1; |
|
382 |
+ } |
|
383 |
+ |
|
384 |
+ pFunc = PyObject_GetAttrString(_sr_apy_handler_obj, child_init_mname.s); |
|
385 |
+ |
|
386 |
+ if (pFunc == NULL) { |
|
387 |
+ python_handle_exception("child_init"); |
|
388 |
+ Py_XDECREF(pFunc); |
|
389 |
+ Py_DECREF(format_exc_obj); |
|
390 |
+ PY_THREADSTATE_SWAP_NULL |
|
391 |
+ PY_GIL_RELEASE |
|
392 |
+ return -1; |
|
393 |
+ } |
|
394 |
+ |
|
395 |
+ if (!PyCallable_Check(pFunc)) { |
|
396 |
+ if (!PyErr_Occurred()) |
|
397 |
+ PyErr_Format(PyExc_AttributeError, |
|
398 |
+ "class object '%s' has is not callable attribute '%s'", |
|
399 |
+ classname, mod_init_fname.s); |
|
400 |
+ python_handle_exception("child_init"); |
|
401 |
+ Py_DECREF(format_exc_obj); |
|
402 |
+ Py_XDECREF(pFunc); |
|
403 |
+ PY_THREADSTATE_SWAP_NULL |
|
404 |
+ PY_GIL_RELEASE |
|
405 |
+ return -1; |
|
406 |
+ } |
|
407 |
+ |
|
408 |
+ pArgs = PyTuple_New(1); |
|
409 |
+ if (pArgs == NULL) { |
|
410 |
+ python_handle_exception("child_init"); |
|
411 |
+ Py_DECREF(format_exc_obj); |
|
412 |
+ Py_DECREF(pFunc); |
|
413 |
+ PY_THREADSTATE_SWAP_NULL |
|
414 |
+ PY_GIL_RELEASE |
|
415 |
+ return -1; |
|
416 |
+ } |
|
417 |
+ |
|
418 |
+ pValue = PyLong_FromLong((long)rank); |
|
419 |
+ if (pValue == NULL) { |
|
420 |
+ python_handle_exception("child_init"); |
|
421 |
+ Py_DECREF(format_exc_obj); |
|
422 |
+ Py_DECREF(pArgs); |
|
423 |
+ Py_DECREF(pFunc); |
|
424 |
+ PY_THREADSTATE_SWAP_NULL |
|
425 |
+ PY_GIL_RELEASE |
|
426 |
+ return -1; |
|
427 |
+ } |
|
428 |
+ PyTuple_SetItem(pArgs, 0, pValue); |
|
429 |
+ /* pValue has been stolen */ |
|
430 |
+ |
|
431 |
+ pResult = PyObject_CallObject(pFunc, pArgs); |
|
432 |
+ Py_DECREF(pFunc); |
|
433 |
+ Py_DECREF(pArgs); |
|
434 |
+ |
|
435 |
+ if (PyErr_Occurred()) { |
|
436 |
+ python_handle_exception("child_init"); |
|
437 |
+ Py_DECREF(format_exc_obj); |
|
438 |
+ Py_XDECREF(pResult); |
|
439 |
+ PY_THREADSTATE_SWAP_NULL |
|
440 |
+ PY_GIL_RELEASE |
|
441 |
+ return -1; |
|
442 |
+ } |
|
443 |
+ |
|
444 |
+ if (pResult == NULL) { |
|
445 |
+ LM_ERR("PyObject_CallObject() returned NULL but no exception!\n"); |
|
446 |
+ PY_THREADSTATE_SWAP_NULL |
|
447 |
+ PY_GIL_RELEASE |
|
448 |
+ return -1; |
|
449 |
+ } |
|
450 |
+ |
|
451 |
+ if (!PyLong_Check(pResult)) |
|
452 |
+ { |
|
453 |
+ if (!PyErr_Occurred()) |
|
454 |
+ PyErr_Format(PyExc_TypeError, |
|
455 |
+ "method '%s' of class '%s' should return 'int' type", |
|
456 |
+ child_init_mname.s, classname); |
|
457 |
+ python_handle_exception("child_init"); |
|
458 |
+ Py_DECREF(format_exc_obj); |
|
459 |
+ Py_XDECREF(pResult); |
|
460 |
+ PY_THREADSTATE_SWAP_NULL |
|
461 |
+ PY_GIL_RELEASE |
|
462 |
+ return -1; |
|
463 |
+ } |
|
464 |
+ |
|
465 |
+ rval = PyLong_AsLong(pResult); |
|
466 |
+ Py_DECREF(pResult); |
|
467 |
+ PY_THREADSTATE_SWAP_NULL |
|
468 |
+ PY_GIL_RELEASE |
|
469 |
+ |
|
470 |
+ return rval; |
|
471 |
+} |
|
472 |
+/** |
|
473 |
+ * |
|
474 |
+ */ |
|
475 |
+static int ki_app_python_exec(sip_msg_t *msg, str *method) |
|
476 |
+{ |
|
477 |
+ if(method==NULL || method->s==NULL || method->len<=0) { |
|
478 |
+ LM_ERR("invalid method name\n"); |
|
479 |
+ return -1; |
|
480 |
+ } |
|
481 |
+ if(method->s[method->len]!='\0') { |
|
482 |
+ LM_ERR("invalid terminated method name\n"); |
|
483 |
+ return -1; |
|
484 |
+ } |
|
485 |
+ return apy_exec(msg, method->s, NULL, 1); |
|
486 |
+} |
|
487 |
+ |
|
488 |
+/** |
|
489 |
+ * |
|
490 |
+ */ |
|
491 |
+static int ki_app_python_exec_p1(sip_msg_t *msg, str *method, str *p1) |
|
492 |
+{ |
|
493 |
+ if(method==NULL || method->s==NULL || method->len<=0) { |
|
494 |
+ LM_ERR("invalid method name\n"); |
|
495 |
+ return -1; |
|
496 |
+ } |
|
497 |
+ if(method->s[method->len]!='\0') { |
|
498 |
+ LM_ERR("invalid terminated method name\n"); |
|
499 |
+ return -1; |
|
500 |
+ } |
|
501 |
+ if(p1==NULL || p1->s==NULL || p1->len<0) { |
|
502 |
+ LM_ERR("invalid p1 value\n"); |
|
503 |
+ return -1; |
|
504 |
+ } |
|
505 |
+ if(p1->s[p1->len]!='\0') { |
|
506 |
+ LM_ERR("invalid terminated p1 value\n"); |
|
507 |
+ return -1; |
|
508 |
+ } |
|
509 |
+ |
|
510 |
+ return apy_exec(msg, method->s, p1->s, 1); |
|
511 |
+} |
|
512 |
+ |
|
513 |
+/** |
|
514 |
+ * |
|
515 |
+ */ |
|
516 |
+/* clang-format off */ |
|
517 |
+static sr_kemi_t sr_kemi_app_python_exports[] = { |
|
518 |
+ { str_init("app_python3"), str_init("exec"), |
|
519 |
+ SR_KEMIP_INT, ki_app_python_exec, |
|
520 |
+ { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, |
|
521 |
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } |
|
522 |
+ }, |
|
523 |
+ { str_init("app_python3"), str_init("exec_p1"), |
|
524 |
+ SR_KEMIP_INT, ki_app_python_exec_p1, |
|
525 |
+ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, |
|
526 |
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } |
|
527 |
+ }, |
|
528 |
+ |
|
529 |
+ { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } |
|
530 |
+}; |
|
531 |
+/* clang-format on */ |
|
532 |
+ |
|
533 |
+/** |
|
534 |
+ * |
|
535 |
+ */ |
|
536 |
+int mod_register(char *path, int *dlflags, void *p1, void *p2) |
|
537 |
+{ |
|
538 |
+ str ename = str_init("python"); |
|
539 |
+ |
|
540 |
+ sr_kemi_eng_register(&ename, sr_kemi_config_engine_python); |
|
541 |
+ sr_kemi_modules_add(sr_kemi_app_python_exports); |
|
542 |
+ |
|
543 |
+ return 0; |
|
544 |
+} |
0 | 545 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,31 @@ |
1 |
+/* |
|
2 |
+ * Copyright (C) 2009 Sippy Software, Inc., http://www.sippysoft.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 |
+#ifndef _PYTHON_MOD_H |
|
23 |
+#define _PYTHON_MOD_H |
|
24 |
+ |
|
25 |
+#include <Python.h> |
|
26 |
+ |
|
27 |
+extern PyObject *_sr_apy_handler_obj; |
|
28 |
+extern PyObject *format_exc_obj; |
|
29 |
+extern PyThreadState *myThreadState; |
|
30 |
+ |
|
31 |
+#endif |
0 | 32 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,1292 @@ |
1 |
+/** |
|
2 |
+ * Copyright (C) 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 |
+#include <stdio.h> |
|
22 |
+#include <unistd.h> |
|
23 |
+#include <stdlib.h> |
|
24 |
+ |
|
25 |
+#include <Python.h> |
|
26 |
+ |
|
27 |
+#include "../../core/dprint.h" |
|
28 |
+#include "../../core/route.h" |
|
29 |
+#include "../../core/fmsg.h" |
|
30 |
+#include "../../core/kemi.h" |
|
31 |
+#include "../../core/pvar.h" |
|
32 |
+#include "../../core/mem/pkg.h" |
|
33 |
+#include "../../core/mem/shm.h" |
|
34 |
+#include "../../core/rpc.h" |
|
35 |
+#include "../../core/rpc_lookup.h" |
|
36 |
+ |
|
37 |
+#include "msgobj_struct.h" |
|
38 |
+#include "python_exec.h" |
|
39 |
+#include "apy_kemi_export.h" |
|
40 |
+#include "apy_kemi.h" |
|
41 |
+ |
|
42 |
+static int *_sr_python_reload_version = NULL; |
|
43 |
+static int _sr_python_local_version = 0; |
|
44 |
+extern str _sr_python_load_file; |
|
45 |
+extern int _apy_process_rank; |
|
46 |
+ |
|
47 |
+/** |
|
48 |
+ * |
|
49 |
+ */ |
|
50 |
+ |
|
51 |
+int apy_reload_script(void) |
|
52 |
+{ |
|
53 |
+ if(_sr_python_reload_version == NULL) { |
|
54 |
+ return 0; |
|
55 |
+ } |
|
56 |
+ if(*_sr_python_reload_version == _sr_python_local_version) { |
|
57 |
+ return 0; |
|
58 |
+ } |
|
59 |
+ if(apy_load_script()<0) { |
|
60 |
+ LM_ERR("failed to load script file\n"); |
|
61 |
+ return -1; |
|
62 |
+ } |
|
63 |
+ if(apy_init_script(_apy_process_rank)<0) { |
|
64 |
+ LM_ERR("failed to init script\n"); |
|
65 |
+ return -1; |
|
66 |
+ } |
|
67 |
+ _sr_python_local_version = *_sr_python_reload_version; |
|
68 |
+ return 0; |
|
69 |
+} |
|
70 |
+/** |
|
71 |
+ * |
|
72 |
+ */ |
|
73 |
+int sr_kemi_config_engine_python(sip_msg_t *msg, int rtype, str *rname, |
|
74 |
+ str *rparam) |
|
75 |
+{ |
|
76 |
+ int ret; |
|
77 |
+ |
|
78 |
+ ret = -1; |
|
79 |
+ if(rtype==REQUEST_ROUTE) { |
|
80 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
81 |
+ ret = apy_exec(msg, rname->s, |
|
82 |
+ (rparam && rparam->s)?rparam->s:NULL, 0); |
|
83 |
+ } else { |
|
84 |
+ ret = apy_exec(msg, "ksr_request_route", NULL, 1); |
|
85 |
+ } |
|
86 |
+ } else if(rtype==CORE_ONREPLY_ROUTE) { |
|
87 |
+ ret = apy_exec(msg, "ksr_reply_route", NULL, 0); |
|
88 |
+ } else if(rtype==BRANCH_ROUTE) { |
|
89 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
90 |
+ ret = apy_exec(msg, rname->s, NULL, 0); |
|
91 |
+ } |
|
92 |
+ } else if(rtype==FAILURE_ROUTE) { |
|
93 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
94 |
+ ret = apy_exec(msg, rname->s, NULL, 0); |
|
95 |
+ } |
|
96 |
+ } else if(rtype==BRANCH_FAILURE_ROUTE) { |
|
97 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
98 |
+ ret = apy_exec(msg, rname->s, NULL, 0); |
|
99 |
+ } |
|
100 |
+ } else if(rtype==TM_ONREPLY_ROUTE) { |
|
101 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
102 |
+ ret = apy_exec(msg, rname->s, NULL, 0); |
|
103 |
+ } |
|
104 |
+ } else if(rtype==ONSEND_ROUTE) { |
|
105 |
+ ret = apy_exec(msg, "ksr_onsend_route", NULL, 0); |
|
106 |
+ } else if(rtype==EVENT_ROUTE) { |
|
107 |
+ if(rname!=NULL && rname->s!=NULL) { |
|
108 |
+ ret = apy_exec(msg, rname->s, |
|
109 |
+ (rparam && rparam->s)?rparam->s:NULL, 0); |
|
110 |
+ } |
|
111 |
+ } else { |
|
112 |
+ if(rname!=NULL) { |
|
113 |
+ LM_ERR("route type %d with name [%.*s] not implemented\n", |
|
114 |
+ rtype, rname->len, rname->s); |
|
115 |
+ } else { |
|
116 |
+ LM_ERR("route type %d with no name not implemented\n", |
|
117 |
+ rtype); |
|
118 |
+ } |
|
119 |
+ } |
|
120 |
+ |
|
121 |
+ if(rname!=NULL) { |
|
122 |
+ LM_DBG("execution of route type %d with name [%.*s] returned %d\n", |
|
123 |
+ rtype, rname->len, rname->s, ret); |
|
124 |
+ } else { |
|
125 |
+ LM_DBG("execution of route type %d with no name returned %d\n", |
|
126 |
+ rtype, ret); |
|
127 |
+ } |
|
128 |
+ |
|
129 |
+ return 1; |
|
130 |
+} |
|
131 |
+ |
|
132 |
+/** |
|
133 |
+ * |
|
134 |
+ */ |
|
135 |
+PyObject *sr_kemi_apy_return_true(void) |
|
136 |
+{ |
|
137 |
+ Py_INCREF(Py_True); |
|
138 |
+ return Py_True; |
|
139 |
+} |
|
140 |
+ |
|
141 |
+/** |
|
142 |
+ * |
|
143 |
+ */ |
|
144 |
+PyObject *sr_kemi_apy_return_false(void) |
|
145 |
+{ |
|
146 |
+ Py_INCREF(Py_False); |
|
147 |
+ return Py_False; |
|
148 |
+} |
|
149 |
+ |
|
150 |
+/** |
|
151 |
+ * |
|
152 |
+ */ |
|
153 |
+PyObject *sr_apy_kemi_return_none(void) |
|
154 |
+{ |
|
155 |
+ Py_INCREF(Py_None); |
|
156 |
+ return Py_None; |
|
157 |
+} |
|
158 |
+ |
|
159 |
+/** |
|
160 |
+ * |
|
161 |
+ */ |
|
162 |
+PyObject *sr_kemi_apy_return_int(sr_kemi_t *ket, int rval) |
|
163 |
+{ |
|
164 |
+ if(ket!=NULL && ket->rtype==SR_KEMIP_BOOL) { |
|
165 |
+ if(rval==SR_KEMI_TRUE) { |
|
166 |
+ return sr_kemi_apy_return_true(); |
|
167 |
+ } else { |
|
168 |
+ return sr_kemi_apy_return_false(); |
|
169 |
+ } |
|
170 |
+ } |
|
171 |
+ return PyLong_FromLong((long)rval); |
|
172 |
+} |
|
173 |
+ |
|
174 |
+/** |
|
175 |
+ * |
|
176 |
+ */ |
|
177 |
+PyObject *sr_apy_kemi_return_str(sr_kemi_t *ket, char *sval, int slen) |
|
178 |
+{ |
|
179 |
+ return PyUnicode_FromStringAndSize(sval, slen); |
|
180 |
+} |
|
181 |
+/** |
|
182 |
+ * |
|
183 |
+ */ |
|
184 |
+PyObject *sr_apy_kemi_exec_func(PyObject *self, PyObject *args, int idx) |
|
185 |
+{ |
|
186 |
+ str fname; |
|
187 |
+ int i; |
|
188 |
+ int ret; |
|
189 |
+ sr_kemi_t *ket = NULL; |
|
190 |
+ sr_kemi_val_t vps[SR_KEMI_PARAMS_MAX]; |
|
191 |
+ sr_apy_env_t *env_P; |
|
192 |
+ sip_msg_t *lmsg = NULL; |
|
193 |
+ |
|
194 |
+ env_P = sr_apy_env_get(); |
|
195 |
+ |
|
196 |
+ if(env_P==NULL) { |
|
197 |
+ LM_ERR("invalid Python environment attributes\n"); |
|
198 |
+ return sr_kemi_apy_return_false(); |
|
199 |
+ } |
|
200 |
+ if(env_P->msg==NULL) { |
|
201 |
+ lmsg = faked_msg_next(); |
|
202 |
+ } else { |
|
203 |
+ lmsg = env_P->msg; |
|
204 |
+ } |
|
205 |
+ |
|
206 |
+ ket = sr_apy_kemi_export_get(idx); |
|
207 |
+ if(ket==NULL) { |
|
208 |
+ return sr_kemi_apy_return_false(); |
|
209 |
+ } |
|
210 |
+ if(ket->mname.len>0) { |
|
211 |
+ LM_DBG("execution of method: %.*s\n", ket->fname.len, ket->fname.s); |
|
212 |
+ } else { |
|
213 |
+ LM_DBG("execution of method: %.*s.%.*s\n", |
|
214 |
+ ket->mname.len, ket->mname.s, |
|
215 |
+ ket->fname.len, ket->fname.s); |
|
216 |
+ } |
|
217 |
+ fname = ket->fname; |
|
218 |
+ |
|
219 |
+ if(ket->ptypes[0]==SR_KEMIP_NONE) { |
|
220 |
+ ret = ((sr_kemi_fm_f)(ket->func))(lmsg); |
|
221 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
222 |
+ } |
|
223 |
+ |
|
224 |
+ memset(vps, 0, SR_KEMI_PARAMS_MAX*sizeof(sr_kemi_val_t)); |
|
225 |
+ if(ket->ptypes[1]==SR_KEMIP_NONE) { |
|
226 |
+ i = 1; |
|
227 |
+ if(ket->ptypes[0]==SR_KEMIP_INT) { |
|
228 |
+ if(!PyArg_ParseTuple(args, "i:kemi-param-n", &vps[0].n)) { |
|
229 |
+ LM_ERR("unable to retrieve int param %d\n", 0); |
|
230 |
+ return sr_kemi_apy_return_false(); |
|
231 |
+ } |
|
232 |
+ LM_DBG("param[%d] for: %.*s is int: %d\n", i, |
|
233 |
+ fname.len, fname.s, vps[0].n); |
|
234 |
+ } else { |
|
235 |
+ if(!PyArg_ParseTuple(args, "s:kemi-param-s", &vps[0].s.s)) { |
|
236 |
+ LM_ERR("unable to retrieve str param %d\n", 0); |
|
237 |
+ return sr_kemi_apy_return_false(); |
|
238 |
+ } |
|
239 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
240 |
+ LM_DBG("param[%d] for: %.*s is str: %.*s\n", i, |
|
241 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s); |
|
242 |
+ } |
|
243 |
+ } else if(ket->ptypes[2]==SR_KEMIP_NONE) { |
|
244 |
+ i = 2; |
|
245 |
+ if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT) { |
|
246 |
+ if(!PyArg_ParseTuple(args, "ii:kemi-param-nn", &vps[0].n, &vps[1].n)) { |
|
247 |
+ LM_ERR("unable to retrieve int-int params %d\n", i); |
|
248 |
+ return sr_kemi_apy_return_false(); |
|
249 |
+ } |
|
250 |
+ LM_DBG("params[%d] for: %.*s are int-int: [%d] [%d]\n", i, |
|
251 |
+ fname.len, fname.s, vps[0].n, vps[1].n); |
|
252 |
+ } else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR) { |
|
253 |
+ if(!PyArg_ParseTuple(args, "is:kemi-param-ns", &vps[0].n, &vps[1].s.s)) { |
|
254 |
+ LM_ERR("unable to retrieve int-str params %d\n", i); |
|
255 |
+ return sr_kemi_apy_return_false(); |
|
256 |
+ } |
|
257 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
258 |
+ LM_DBG("params[%d] for: %.*s are int-str: [%d] [%.*s]\n", i, |
|
259 |
+ fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s); |
|
260 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT) { |
|
261 |
+ if(!PyArg_ParseTuple(args, "si:kemi-param-sn", &vps[0].s.s, &vps[1].n)) { |
|
262 |
+ LM_ERR("unable to retrieve str-int params %d\n", i); |
|
263 |
+ return sr_kemi_apy_return_false(); |
|
264 |
+ } |
|
265 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
266 |
+ LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d]\n", i, |
|
267 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n); |
|
268 |
+ } else { |
|
269 |
+ if(!PyArg_ParseTuple(args, "ss:kemi-param-ss", &vps[0].s.s, &vps[1].s.s)) { |
|
270 |
+ LM_ERR("unable to retrieve str-str param %d\n", i); |
|
271 |
+ return sr_kemi_apy_return_false(); |
|
272 |
+ } |
|
273 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
274 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
275 |
+ LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]\n", i, |
|
276 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, |
|
277 |
+ vps[1].s.len, vps[1].s.s); |
|
278 |
+ } |
|
279 |
+ |
|
280 |
+ } else if(ket->ptypes[3]==SR_KEMIP_NONE) { |
|
281 |
+ i = 3; |
|
282 |
+ if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT |
|
283 |
+ && ket->ptypes[2]==SR_KEMIP_INT) { |
|
284 |
+ if(!PyArg_ParseTuple(args, "iii:kemi-param-nnn", &vps[0].n, |
|
285 |
+ &vps[1].n, &vps[2].n)) { |
|
286 |
+ LM_ERR("unable to retrieve int-int-int params %d\n", i); |
|
287 |
+ return sr_kemi_apy_return_false(); |
|
288 |
+ } |
|
289 |
+ LM_DBG("params[%d] for: %.*s are int-int-int: [%d] [%d] [%d]\n", |
|
290 |
+ i, fname.len, fname.s, vps[0].n, vps[1].n, vps[2].n); |
|
291 |
+ } else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR |
|
292 |
+ && ket->ptypes[2]==SR_KEMIP_INT) { |
|
293 |
+ if(!PyArg_ParseTuple(args, "isi:kemi-param-nsn", &vps[0].n, |
|
294 |
+ &vps[1].s.s, &vps[2].n)) { |
|
295 |
+ LM_ERR("unable to retrieve int-str-int params %d\n", i); |
|
296 |
+ return sr_kemi_apy_return_false(); |
|
297 |
+ } |
|
298 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
299 |
+ LM_DBG("params[%d] for: %.*s are int-str-int: [%d] [%.*s] [%d]\n", i, |
|
300 |
+ fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].n); |
|
301 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT |
|
302 |
+ && ket->ptypes[2]==SR_KEMIP_INT) { |
|
303 |
+ if(!PyArg_ParseTuple(args, "sii:kemi-param-snn", &vps[0].s.s, |
|
304 |
+ &vps[1].n, &vps[2].n)) { |
|
305 |
+ LM_ERR("unable to retrieve str-int-int params %d\n", i); |
|
306 |
+ return sr_kemi_apy_return_false(); |
|
307 |
+ } |
|
308 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
309 |
+ LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d] [%d]\n", i, |
|
310 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n, |
|
311 |
+ vps[2].n); |
|
312 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR |
|
313 |
+ && ket->ptypes[2]==SR_KEMIP_INT) { |
|
314 |
+ if(!PyArg_ParseTuple(args, "ssi:kemi-param-ssn", &vps[0].s.s, |
|
315 |
+ &vps[1].s.s, &vps[2].n)) { |
|
316 |
+ LM_ERR("unable to retrieve str-str-int param %d\n", i); |
|
317 |
+ return sr_kemi_apy_return_false(); |
|
318 |
+ } |
|
319 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
320 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
321 |
+ LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%.*s]" |
|
322 |
+ " [%d]\n", i, fname.len, fname.s, |
|
323 |
+ vps[0].s.len, vps[0].s.s, |
|
324 |
+ vps[1].s.len, vps[1].s.s, vps[2].n); |
|
325 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR |
|
326 |
+ && ket->ptypes[2]==SR_KEMIP_STR) { |
|
327 |
+ if(!PyArg_ParseTuple(args, "sss:kemi-param-sss", &vps[0].s.s, |
|
328 |
+ &vps[1].s.s, &vps[2].s.s)) { |
|
329 |
+ LM_ERR("unable to retrieve str-str-str param %d\n", i); |
|
330 |
+ return sr_kemi_apy_return_false(); |
|
331 |
+ } |
|
332 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
333 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
334 |
+ vps[2].s.len = strlen(vps[2].s.s); |
|
335 |
+ LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%.*s]" |
|
336 |
+ " [%.*s]\n", i, fname.len, fname.s, |
|
337 |
+ vps[0].s.len, vps[0].s.s, |
|
338 |
+ vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s); |
|
339 |
+ } else { |
|
340 |
+ LM_ERR("not implemented yet\n"); |
|
341 |
+ return sr_kemi_apy_return_false(); |
|
342 |
+ } |
|
343 |
+ } else if(ket->ptypes[4]==SR_KEMIP_NONE) { |
|
344 |
+ i = 4; |
|
345 |
+ if(ket->ptypes[0]==SR_KEMIP_STR |
|
346 |
+ || ket->ptypes[1]==SR_KEMIP_STR |
|
347 |
+ || ket->ptypes[2]==SR_KEMIP_STR |
|
348 |
+ || ket->ptypes[3]==SR_KEMIP_STR) { |
|
349 |
+ if(!PyArg_ParseTuple(args, "ssss:kemi-param-ssss", |
|
350 |
+ &vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s)) { |
|
351 |
+ LM_ERR("unable to retrieve str-str-str-str params %d\n", i); |
|
352 |
+ return sr_kemi_apy_return_false(); |
|
353 |
+ } |
|
354 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
355 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
356 |
+ vps[2].s.len = strlen(vps[2].s.s); |
|
357 |
+ vps[3].s.len = strlen(vps[3].s.s); |
|
358 |
+ LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]" |
|
359 |
+ " [%.*s] [%.*s]\n", i, |
|
360 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, |
|
361 |
+ vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s, |
|
362 |
+ vps[3].s.len, vps[3].s.s); |
|
363 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR |
|
364 |
+ || ket->ptypes[1]==SR_KEMIP_STR |
|
365 |
+ || ket->ptypes[2]==SR_KEMIP_INT |
|
366 |
+ || ket->ptypes[3]==SR_KEMIP_INT) { |
|
367 |
+ if(!PyArg_ParseTuple(args, "ssii:kemi-param-ssnn", |
|
368 |
+ &vps[0].s.s, &vps[1].s.s, &vps[2].n, &vps[3].n)) { |
|
369 |
+ LM_ERR("unable to retrieve str-str-int-int params %d\n", i); |
|
370 |
+ return sr_kemi_apy_return_false(); |
|
371 |
+ } |
|
372 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
373 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
374 |
+ LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]" |
|
375 |
+ " [%d] [%d]\n", i, |
|
376 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, |
|
377 |
+ vps[1].s.len, vps[1].s.s, vps[2].n, vps[3].n); |
|
378 |
+ } else { |
|
379 |
+ LM_ERR("not implemented yet\n"); |
|
380 |
+ return sr_kemi_apy_return_false(); |
|
381 |
+ } |
|
382 |
+ } else if(ket->ptypes[5]==SR_KEMIP_NONE) { |
|
383 |
+ i = 5; |
|
384 |
+ if(ket->ptypes[0]==SR_KEMIP_STR |
|
385 |
+ || ket->ptypes[1]==SR_KEMIP_STR |
|
386 |
+ || ket->ptypes[2]==SR_KEMIP_STR |
|
387 |
+ || ket->ptypes[3]==SR_KEMIP_STR |
|
388 |
+ || ket->ptypes[4]==SR_KEMIP_STR) { |
|
389 |
+ if(!PyArg_ParseTuple(args, "sssss:kemi-param-sssss", |
|
390 |
+ &vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s, |
|
391 |
+ &vps[4].s.s)) { |
|
392 |
+ LM_ERR("unable to retrieve str-str-str-str params %d\n", i); |
|
393 |
+ return sr_kemi_apy_return_false(); |
|
394 |
+ } |
|
395 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
396 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
397 |
+ vps[2].s.len = strlen(vps[2].s.s); |
|
398 |
+ vps[3].s.len = strlen(vps[3].s.s); |
|
399 |
+ vps[4].s.len = strlen(vps[4].s.s); |
|
400 |
+ LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]" |
|
401 |
+ " [%.*s] [%.*s] [%.*s]\n", i, |
|
402 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, |
|
403 |
+ vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s, |
|
404 |
+ vps[3].s.len, vps[3].s.s, vps[4].s.len, vps[4].s.s); |
|
405 |
+ } else { |
|
406 |
+ LM_ERR("not implemented yet\n"); |
|
407 |
+ return sr_kemi_apy_return_false(); |
|
408 |
+ } |
|
409 |
+ } else { |
|
410 |
+ i = 6; |
|
411 |
+ if(ket->ptypes[0]==SR_KEMIP_STR |
|
412 |
+ || ket->ptypes[1]==SR_KEMIP_STR |
|
413 |
+ || ket->ptypes[2]==SR_KEMIP_STR |
|
414 |
+ || ket->ptypes[3]==SR_KEMIP_STR |
|
415 |
+ || ket->ptypes[4]==SR_KEMIP_STR |
|
416 |
+ || ket->ptypes[5]==SR_KEMIP_STR) { |
|
417 |
+ if(!PyArg_ParseTuple(args, "ssssss:kemi-param-ssssss", |
|
418 |
+ &vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s, |
|
419 |
+ &vps[4].s.s, &vps[5].s.s)) { |
|
420 |
+ LM_ERR("unable to retrieve str-str-str-str params %d\n", i); |
|
421 |
+ return sr_kemi_apy_return_false(); |
|
422 |
+ } |
|
423 |
+ vps[0].s.len = strlen(vps[0].s.s); |
|
424 |
+ vps[1].s.len = strlen(vps[1].s.s); |
|
425 |
+ vps[2].s.len = strlen(vps[2].s.s); |
|
426 |
+ vps[3].s.len = strlen(vps[3].s.s); |
|
427 |
+ vps[4].s.len = strlen(vps[4].s.s); |
|
428 |
+ vps[5].s.len = strlen(vps[5].s.s); |
|
429 |
+ LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]" |
|
430 |
+ " [%.*s] [%.*s] [%.*s] [%.*s]\n", i, |
|
431 |
+ fname.len, fname.s, vps[0].s.len, vps[0].s.s, |
|
432 |
+ vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s, |
|
433 |
+ vps[3].s.len, vps[3].s.s, vps[4].s.len, vps[4].s.s, |
|
434 |
+ vps[5].s.len, vps[5].s.s); |
|
435 |
+ } else { |
|
436 |
+ LM_ERR("not implemented yet\n"); |
|
437 |
+ return sr_kemi_apy_return_false(); |
|
438 |
+ } |
|
439 |
+ } |
|
440 |
+ |
|
441 |
+ switch(i) { |
|
442 |
+ case 1: |
|
443 |
+ if(ket->ptypes[0]==SR_KEMIP_INT) { |
|
444 |
+ ret = ((sr_kemi_fmn_f)(ket->func))(lmsg, vps[0].n); |
|
445 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
446 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR) { |
|
447 |
+ ret = ((sr_kemi_fms_f)(ket->func))(lmsg, &vps[0].s); |
|
448 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
449 |
+ } else { |
|
450 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
451 |
+ fname.len, fname.s); |
|
452 |
+ return sr_kemi_apy_return_false(); |
|
453 |
+ } |
|
454 |
+ break; |
|
455 |
+ case 2: |
|
456 |
+ if(ket->ptypes[0]==SR_KEMIP_INT) { |
|
457 |
+ if(ket->ptypes[1]==SR_KEMIP_INT) { |
|
458 |
+ ret = ((sr_kemi_fmnn_f)(ket->func))(lmsg, vps[0].n, vps[1].n); |
|
459 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
460 |
+ } else if(ket->ptypes[1]==SR_KEMIP_STR) { |
|
461 |
+ ret = ((sr_kemi_fmns_f)(ket->func))(lmsg, vps[0].n, &vps[1].s); |
|
462 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
463 |
+ } else { |
|
464 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
465 |
+ fname.len, fname.s); |
|
466 |
+ return sr_kemi_apy_return_false(); |
|
467 |
+ } |
|
468 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR) { |
|
469 |
+ if(ket->ptypes[1]==SR_KEMIP_INT) { |
|
470 |
+ ret = ((sr_kemi_fmsn_f)(ket->func))(lmsg, &vps[0].s, vps[1].n); |
|
471 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
472 |
+ } else if(ket->ptypes[1]==SR_KEMIP_STR) { |
|
473 |
+ ret = ((sr_kemi_fmss_f)(ket->func))(lmsg, &vps[0].s, &vps[1].s); |
|
474 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
475 |
+ } else { |
|
476 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
477 |
+ fname.len, fname.s); |
|
478 |
+ return sr_kemi_apy_return_false(); |
|
479 |
+ } |
|
480 |
+ } else { |
|
481 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
482 |
+ fname.len, fname.s); |
|
483 |
+ return sr_kemi_apy_return_false(); |
|
484 |
+ } |
|
485 |
+ break; |
|
486 |
+ case 3: |
|
487 |
+ if(ket->ptypes[0]==SR_KEMIP_INT) { |
|
488 |
+ if(ket->ptypes[1]==SR_KEMIP_INT) { |
|
489 |
+ if(ket->ptypes[2]==SR_KEMIP_INT) { |
|
490 |
+ /* nnn */ |
|
491 |
+ ret = ((sr_kemi_fmnnn_f)(ket->func))(lmsg, |
|
492 |
+ vps[0].n, vps[1].n, vps[2].n); |
|
493 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
494 |
+ } else if(ket->ptypes[2]==SR_KEMIP_STR) { |
|
495 |
+ /* nns */ |
|
496 |
+ ret = ((sr_kemi_fmnns_f)(ket->func))(lmsg, |
|
497 |
+ vps[0].n, vps[1].n, &vps[2].s); |
|
498 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
499 |
+ } else { |
|
500 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
501 |
+ fname.len, fname.s); |
|
502 |
+ return sr_kemi_apy_return_false(); |
|
503 |
+ } |
|
504 |
+ } else if(ket->ptypes[1]==SR_KEMIP_STR) { |
|
505 |
+ if(ket->ptypes[2]==SR_KEMIP_INT) { |
|
506 |
+ /* nsn */ |
|
507 |
+ ret = ((sr_kemi_fmnsn_f)(ket->func))(lmsg, |
|
508 |
+ vps[0].n, &vps[1].s, vps[2].n); |
|
509 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
510 |
+ } else if(ket->ptypes[2]==SR_KEMIP_STR) { |
|
511 |
+ /* nss */ |
|
512 |
+ ret = ((sr_kemi_fmnss_f)(ket->func))(lmsg, |
|
513 |
+ vps[0].n, &vps[1].s, &vps[2].s); |
|
514 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
515 |
+ } else { |
|
516 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
517 |
+ fname.len, fname.s); |
|
518 |
+ return sr_kemi_apy_return_false(); |
|
519 |
+ } |
|
520 |
+ } else { |
|
521 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
522 |
+ fname.len, fname.s); |
|
523 |
+ return sr_kemi_apy_return_false(); |
|
524 |
+ } |
|
525 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR) { |
|
526 |
+ if(ket->ptypes[1]==SR_KEMIP_INT) { |
|
527 |
+ if(ket->ptypes[2]==SR_KEMIP_INT) { |
|
528 |
+ /* snn */ |
|
529 |
+ ret = ((sr_kemi_fmsnn_f)(ket->func))(lmsg, |
|
530 |
+ &vps[0].s, vps[1].n, vps[2].n); |
|
531 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
532 |
+ } else if(ket->ptypes[2]==SR_KEMIP_STR) { |
|
533 |
+ /* sns */ |
|
534 |
+ ret = ((sr_kemi_fmsns_f)(ket->func))(lmsg, |
|
535 |
+ &vps[0].s, vps[1].n, &vps[2].s); |
|
536 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
537 |
+ } else { |
|
538 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
539 |
+ fname.len, fname.s); |
|
540 |
+ return sr_kemi_apy_return_false(); |
|
541 |
+ } |
|
542 |
+ } else if(ket->ptypes[1]==SR_KEMIP_STR) { |
|
543 |
+ if(ket->ptypes[2]==SR_KEMIP_INT) { |
|
544 |
+ /* ssn */ |
|
545 |
+ ret = ((sr_kemi_fmssn_f)(ket->func))(lmsg, |
|
546 |
+ &vps[0].s, &vps[1].s, vps[2].n); |
|
547 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
548 |
+ } else if(ket->ptypes[2]==SR_KEMIP_STR) { |
|
549 |
+ /* sss */ |
|
550 |
+ ret = ((sr_kemi_fmsss_f)(ket->func))(lmsg, |
|
551 |
+ &vps[0].s, &vps[1].s, &vps[2].s); |
|
552 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
553 |
+ } else { |
|
554 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
555 |
+ fname.len, fname.s); |
|
556 |
+ return sr_kemi_apy_return_false(); |
|
557 |
+ } |
|
558 |
+ } else { |
|
559 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
560 |
+ fname.len, fname.s); |
|
561 |
+ return sr_kemi_apy_return_false(); |
|
562 |
+ } |
|
563 |
+ } else { |
|
564 |
+ LM_ERR("invalid parameters for: %.*s\n", |
|
565 |
+ fname.len, fname.s); |
|
566 |
+ return sr_kemi_apy_return_false(); |
|
567 |
+ } |
|
568 |
+ break; |
|
569 |
+ case 4: |
|
570 |
+ if(ket->ptypes[0]==SR_KEMIP_STR |
|
571 |
+ || ket->ptypes[1]==SR_KEMIP_STR |
|
572 |
+ || ket->ptypes[2]==SR_KEMIP_STR |
|
573 |
+ || ket->ptypes[3]==SR_KEMIP_STR) { |
|
574 |
+ /* ssss */ |
|
575 |
+ ret = ((sr_kemi_fmssss_f)(ket->func))(lmsg, |
|
576 |
+ &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s); |
|
577 |
+ return sr_kemi_apy_return_int(ket, ret); |
|
578 |
+ } else if(ket->ptypes[0]==SR_KEMIP_STR |
|
579 |