36cb4a0f0353722e9e94040ed10f497d51ed8b5f
[sip-router] / src / modules / pv / pv.c
1 /*
2  * Copyright (C) 2008 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 <string.h>
23 #include <stdlib.h>
24
25 #include "../../core/sr_module.h"
26 #include "../../core/pvar.h"
27 #include "../../core/pvapi.h"
28 #include "../../core/lvalue.h"
29 #include "../../core/mod_fix.h"
30 #include "../../core/xavp.h"
31 #include "../../core/kemi.h"
32 #include "../../core/rpc.h"
33 #include "../../core/rpc_lookup.h"
34
35
36 #include "pv_branch.h"
37 #include "pv_core.h"
38 #include "pv_stats.h"
39 #include "pv_shv.h"
40 #include "pv_time.h"
41 #include "pv_trans.h"
42 #include "pv_select.h"
43 #include "pv_xavp.h"
44 #include "pv_api.h"
45
46 MODULE_VERSION
47
48 static tr_export_t mod_trans[] = {
49         { {"s", sizeof("s")-1}, /* string class */
50                 tr_parse_string },
51         { {"nameaddr", sizeof("nameaddr")-1}, /* nameaddr class */
52                 tr_parse_nameaddr },
53         { {"uri", sizeof("uri")-1}, /* uri class */
54                 tr_parse_uri },
55         { {"param", sizeof("param")-1}, /* param class */
56                 tr_parse_paramlist },
57         { {"tobody", sizeof("tobody")-1}, /* param class */
58                 tr_parse_tobody },
59         { {"line", sizeof("line")-1}, /* line class */
60                 tr_parse_line },
61
62         { { 0, 0 }, 0 }
63 };
64
65 static pv_export_t mod_pvs[] = {
66         { {"_s", (sizeof("_s")-1)}, PVT_OTHER, pv_get__s, 0,
67                 pv_parse__s_name, 0, 0, 0 },
68         { {"af", (sizeof("af")-1)}, PVT_OTHER, pv_get_af, 0,
69                 pv_parse_af_name, 0, 0, 0 },
70         { {"branch", sizeof("branch")-1}, /* branch attributes */
71                 PVT_CONTEXT, pv_get_branchx, pv_set_branchx,
72                 pv_parse_branchx_name, pv_parse_index, 0, 0 },
73         { {"sbranch", sizeof("sbranch")-1}, /* static branch attributes */
74                 PVT_CONTEXT, pv_get_sbranch, pv_set_sbranch,
75                 pv_parse_branchx_name, 0, 0, 0 },
76         { {"mi", (sizeof("mi")-1)}, /* message id */
77                 PVT_OTHER, pv_get_msgid, 0,
78                 0, 0, 0, 0},
79         { {"stat", sizeof("stat")-1}, /* statistics */
80                 PVT_OTHER, pv_get_stat, 0,
81                 pv_parse_stat_name, 0, 0, 0 },
82         { {"sel", sizeof("sel")-1}, /* select */
83                 PVT_OTHER, pv_get_select, 0,
84                 pv_parse_select_name, 0, 0, 0 },
85         { {"snd", (sizeof("snd")-1)}, PVT_OTHER, pv_get_sndto, 0,
86                 pv_parse_snd_name, 0, 0, 0 },
87         { {"sndto", (sizeof("sndto")-1)}, PVT_OTHER, pv_get_sndto, 0,
88                 pv_parse_snd_name, 0, 0, 0 },
89         { {"sndfrom", (sizeof("sndfrom")-1)}, PVT_OTHER, pv_get_sndfrom, 0,
90                 pv_parse_snd_name, 0, 0, 0 },
91         { {"rcv", (sizeof("rcv")-1)}, PVT_OTHER, pv_get_rcv, 0,
92                 pv_parse_rcv_name, 0, 0, 0 },
93         { {"xavp", sizeof("xavp")-1}, /* xavp */
94                 PVT_XAVP, pv_get_xavp, pv_set_xavp,
95                 pv_parse_xavp_name, 0, 0, 0 },
96         { {"xavu", sizeof("xavu")-1}, /* xavu */
97                 PVT_XAVU, pv_get_xavu, pv_set_xavu,
98                 pv_parse_xavp_name, 0, 0, 0 },
99         {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp,
100                 pv_parse_avp_name, pv_parse_index, 0, 0},
101         {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name,
102                 pv_parse_index, 0, 0},
103         {{"hdrc", (sizeof("hdrc")-1)}, PVT_HDRC, pv_get_hdrc, 0, pv_parse_hdr_name,
104                 0, 0, 0},
105         {{"var", (sizeof("var")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
106                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
107         {{"vz", (sizeof("vz")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
108                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
109         {{"vn", (sizeof("vn")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
110                 pv_set_scriptvar, pv_parse_scriptvarnull_name, 0, 0, 0},
111         {{"ai", (sizeof("ai")-1)}, /* */
112                 PVT_OTHER, pv_get_pai, 0,
113                 0, pv_parse_index, 0, 0},
114         {{"adu", (sizeof("adu")-1)}, /* auth digest uri */
115                 PVT_OTHER, pv_get_authattr, 0,
116                 0, 0, pv_init_iname, 3},
117         {{"ar", (sizeof("ar")-1)}, /* auth realm */
118                 PVT_OTHER, pv_get_authattr, 0,
119                 0, 0, pv_init_iname, 2},
120         {{"au", (sizeof("au")-1)}, /* */
121                 PVT_OTHER, pv_get_authattr, 0,
122                 0, 0, pv_init_iname, 1},
123         {{"ad", (sizeof("ad")-1)}, /* */
124                 PVT_OTHER, pv_get_authattr, 0,
125                 0, 0, pv_init_iname, 4},
126         {{"aU", (sizeof("aU")-1)}, /* */
127                 PVT_OTHER, pv_get_authattr, 0,
128                 0, 0, pv_init_iname, 5},
129         {{"aa", (sizeof("aa")-1)}, /* auth algorithm */
130                 PVT_OTHER, pv_get_authattr, 0,
131                 0, 0, pv_init_iname, 6},
132         {{"adn", (sizeof("adn")-1)}, /* auth nonce */
133                 PVT_OTHER, pv_get_authattr, 0,
134                 0, 0, pv_init_iname, 7},
135         {{"adc", (sizeof("adc")-1)}, /* auth cnonce */
136                 PVT_OTHER, pv_get_authattr, 0,
137                 0, 0, pv_init_iname, 8},
138         {{"adr", (sizeof("adr")-1)}, /* auth response */
139                 PVT_OTHER, pv_get_authattr, 0,
140                 0, 0, pv_init_iname, 9},
141         {{"ado", (sizeof("ado")-1)}, /* auth opaque */
142                 PVT_OTHER, pv_get_authattr, 0,
143                 0, 0, pv_init_iname, 10},
144         {{"Au", (sizeof("Au")-1)}, /* */
145                 PVT_OTHER, pv_get_acc_username, 0,
146                 0, 0, pv_init_iname, 1},
147         {{"AU", (sizeof("AU")-1)}, /* */
148                 PVT_OTHER, pv_get_acc_user, 0,
149                 0, 0, pv_init_iname, 1},
150         {{"bf", (sizeof("bf")-1)}, /* */
151                 PVT_CONTEXT, pv_get_bflags, pv_set_bflags,
152                 0, 0, 0, 0},
153         {{"bF", (sizeof("bF")-1)}, /* */
154                 PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags,
155                 0, 0, 0, 0},
156         {{"Bf", (sizeof("Bf")-1)}, /* */
157                 PVT_CONTEXT, pv_get_bflag, pv_set_bflag,
158                 pv_parse_flag_param, 0, 0, 0},
159         {{"br", (sizeof("br")-1)}, /* */
160                 PVT_BRANCH, pv_get_branch, pv_set_branch,
161                 0, 0, 0, 0},
162         {{"bR", (sizeof("bR")-1)}, /* */
163                 PVT_CONTEXT, pv_get_branches, 0,
164                 0, 0, 0, 0},
165         {{"bs", (sizeof("bs")-1)}, /* */
166                 PVT_OTHER, pv_get_body_size, 0,
167                 0, 0, 0, 0},
168         {{"ci", (sizeof("ci")-1)}, /* */
169                 PVT_OTHER, pv_get_callid, 0,
170                 0, 0, 0, 0},
171         {{"cl", (sizeof("cl")-1)}, /* */
172                 PVT_OTHER, pv_get_content_length, 0,
173                 0, 0, 0, 0},
174         {{"cnt", sizeof("cnt")-1},
175                 PVT_OTHER, pv_get_cnt, 0,
176                 pv_parse_cnt_name, 0, 0, 0 },
177         {{"conid", (sizeof("conid")-1)}, /* */
178                 PVT_OTHER, pv_get_tcpconn_id, 0,
179                 0, 0, 0, 0},
180         {{"cs", (sizeof("cs")-1)}, /* */
181                 PVT_OTHER, pv_get_cseq, 0,
182                 0, 0, 0, 0},
183         {{"csb", (sizeof("csb")-1)}, /* */
184                 PVT_OTHER, pv_get_cseq_body, 0,
185                 0, 0, 0, 0},
186         {{"ct", (sizeof("ct")-1)}, /* */
187                 PVT_OTHER, pv_get_contact, 0,
188                 0, 0, 0, 0},
189         {{"cT", (sizeof("cT")-1)}, /* */
190                 PVT_OTHER, pv_get_content_type, 0,
191                 0, 0, 0, 0},
192         {{"dd", (sizeof("dd")-1)}, /* */
193                 PVT_OTHER, pv_get_dsturi_attr, 0,
194                 0, 0, pv_init_iname, 1},
195         {{"def", (sizeof("env")-1)}, PVT_OTHER, pv_get_def, 0,
196                 pv_parse_def_name, 0, 0, 0},
197         {{"di", (sizeof("di")-1)}, /* */
198                 PVT_OTHER, pv_get_diversion, 0,
199                 0, 0, pv_init_iname, 1},
200         {{"dir", (sizeof("dir")-1)}, /* */
201                 PVT_OTHER, pv_get_diversion, 0,
202                 0, 0, pv_init_iname, 2},
203         {{"dip", (sizeof("dis")-1)}, /* */
204                 PVT_OTHER, pv_get_diversion, 0,
205                 0, 0, pv_init_iname, 3},
206         {{"dic", (sizeof("dic")-1)}, /* */
207                 PVT_OTHER, pv_get_diversion, 0,
208                 0, 0, pv_init_iname, 4},
209         {{"dp", (sizeof("dp")-1)}, /* */
210                 PVT_OTHER, pv_get_dsturi_attr, 0,
211                 0, 0, pv_init_iname, 2},
212         {{"dP", (sizeof("dP")-1)}, /* */
213                 PVT_OTHER, pv_get_dsturi_attr, 0,
214                 0, 0, pv_init_iname, 3},
215         {{"ds", (sizeof("ds")-1)}, /* */
216                 PVT_CONTEXT, pv_get_dset, 0,
217                 0, 0, 0, 0},
218         {{"du", (sizeof("du")-1)}, /* */
219                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
220                 0, 0, 0, 0},
221         {{"duri", (sizeof("duri")-1)}, /* */
222                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
223                 0, 0, 0, 0},
224         {{"env", (sizeof("env")-1)}, PVT_OTHER, pv_get_env, 0,
225                 pv_parse_env_name, 0, 0, 0},
226         {{"err.class", (sizeof("err.class")-1)}, /* */
227                 PVT_OTHER, pv_get_errinfo_attr, 0,
228                 0, 0, 0, 0},
229         {{"err.level", (sizeof("err.level")-1)}, /* */
230                 PVT_OTHER, pv_get_errinfo_attr, 0,
231                 0, 0, pv_init_iname, 1},
232         {{"err.info", (sizeof("err.info")-1)}, /* */
233                 PVT_OTHER, pv_get_errinfo_attr, 0,
234                 0, 0, pv_init_iname, 2},
235         {{"err.rcode", (sizeof("err.rcode")-1)}, /* */
236                 PVT_OTHER, pv_get_errinfo_attr, 0,
237                 0, 0, pv_init_iname, 3},
238         {{"err.rreason", (sizeof("err.rreason")-1)}, /* */
239                 PVT_OTHER, pv_get_errinfo_attr, 0,
240                 0, 0, pv_init_iname, 4},
241         {{"fd", (sizeof("fd")-1)}, /* */
242                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
243                 0, 0, pv_init_iname, 3},
244         {{"from.domain", (sizeof("from.domain")-1)}, /* */
245                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
246                 0, 0, pv_init_iname, 3},
247         {{"fn", (sizeof("fn")-1)}, /* */
248                 PVT_OTHER, pv_get_from_attr, pv_set_from_display,
249                 0, 0, pv_init_iname, 5},
250         {{"fs", (sizeof("fs")-1)}, /* */
251                 PVT_OTHER, pv_get_force_sock, pv_set_force_sock,
252                 0, 0, 0, 0},
253         {{"fsn", (sizeof("fsn")-1)}, /* */
254                 PVT_OTHER, pv_get_force_sock_name, pv_set_force_sock_name,
255                 0, 0, 0, 0},
256         {{"ft", (sizeof("ft")-1)}, /* */
257                 PVT_OTHER, pv_get_from_attr, 0,
258                 0, 0, pv_init_iname, 4},
259         {{"fu", (sizeof("fu")-1)}, /* */
260                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
261                 0, 0, pv_init_iname, 1},
262         {{"from", (sizeof("from")-1)}, /* */
263                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
264                 0, 0, pv_init_iname, 1},
265         {{"fU", (sizeof("fU")-1)}, /* */
266                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
267                 0, 0, pv_init_iname, 2},
268         {{"from.user", (sizeof("from.user")-1)}, /* */
269                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
270                 0, 0, pv_init_iname, 2},
271         {{"mb", (sizeof("mb")-1)}, /* */
272                 PVT_OTHER, pv_get_msg_buf, 0,
273                 0, 0, 0, 0},
274         {{"mbu", (sizeof("mbu")-1)}, /* */
275                 PVT_OTHER, pv_get_msg_buf_updated, 0,
276                 0, 0, 0, 0},
277         {{"mf", (sizeof("mf")-1)}, /* */
278                 PVT_OTHER, pv_get_flags, pv_set_mflags,
279                 0, 0, 0, 0},
280         {{"mF", (sizeof("mF")-1)}, /* */
281                 PVT_OTHER, pv_get_hexflags, pv_set_mflags,
282                 0, 0, 0, 0},
283         {{"Mf", (sizeof("mf")-1)}, /* */
284                 PVT_OTHER, pv_get_flag, pv_set_mflag,
285                 pv_parse_flag_param, 0, 0, 0},
286         {{"ml", (sizeof("ml")-1)}, /* */
287                 PVT_OTHER, pv_get_msg_len, 0,
288                 0, 0, 0, 0},
289         {{"mt", (sizeof("mt")-1)}, /* */
290                 PVT_OTHER, pv_get_msgtype, 0,
291                 0, 0, 0, 0},
292         {{"od", (sizeof("od")-1)}, /* */
293                 PVT_OTHER, pv_get_ouri_attr, 0,
294                 0, 0, pv_init_iname, 2},
295         {{"op", (sizeof("op")-1)}, /* */
296                 PVT_OTHER, pv_get_ouri_attr, 0,
297                 0, 0, pv_init_iname, 3},
298         {{"oP", (sizeof("oP")-1)}, /* */
299                 PVT_OTHER, pv_get_ouri_attr, 0,
300                 0, 0, pv_init_iname, 4},
301         {{"ou", (sizeof("ou")-1)}, /* */
302                 PVT_OURI, pv_get_ouri, 0,
303                 0, 0, 0, 0},
304         {{"ouri", (sizeof("ouri")-1)}, /* */
305                 PVT_OURI, pv_get_ouri, 0,
306                 0, 0, 0, 0},
307         {{"oU", (sizeof("oU")-1)}, /* */
308                 PVT_OTHER, pv_get_ouri_attr, 0,
309                 0, 0, pv_init_iname, 1},
310         {{"pd", (sizeof("pd")-1)}, /* */
311                 PVT_OTHER, pv_get_ppi_attr, 0,
312                 0, pv_parse_index, pv_init_iname, 3},
313         {{"pn", (sizeof("pn")-1)}, /* */
314                 PVT_OTHER, pv_get_ppi_attr, 0,
315                 0, pv_parse_index, pv_init_iname, 4},
316         {{"pp", (sizeof("pp")-1)}, /* */
317                 PVT_OTHER, pv_get_pid, 0,
318                 0, 0, 0, 0},
319         {{"pr", (sizeof("pr")-1)}, /* */
320                 PVT_OTHER, pv_get_proto, 0,
321                 0, 0, 0, 0},
322         {{"prid", (sizeof("prid")-1)}, /* */
323                 PVT_OTHER, pv_get_protoid, 0,
324                 0, 0, 0, 0},
325         {{"proto", (sizeof("proto")-1)}, /* */
326                 PVT_OTHER, pv_get_proto, 0,
327                 0, 0, 0, 0},
328         {{"pu", (sizeof("pu")-1)}, /* */
329                 PVT_OTHER, pv_get_ppi_attr, 0,
330                 0, pv_parse_index, pv_init_iname, 1},
331         {{"pU", (sizeof("pU")-1)}, /* */
332                 PVT_OTHER, pv_get_ppi_attr, 0,
333                 0, pv_parse_index, pv_init_iname, 2},
334         {{"rb", (sizeof("rb")-1)}, /* */
335                 PVT_MSG_BODY, pv_get_msg_body, 0,
336                 0, 0, 0, 0},
337         /* {{"rc", (sizeof("rc")-1)},
338                 PVT_OTHER, pv_get_return_code, 0,
339                 0, 0, 0, 0},
340         {{"retcode", (sizeof("retcode")-1)},
341                 PVT_OTHER, pv_get_return_code, 0,
342                 0, 0, 0, 0}, */
343         {{"rd", (sizeof("rd")-1)}, /* */
344                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
345                 0, 0, pv_init_iname, 2},
346         {{"ruri.domain", (sizeof("ruri.domain")-1)}, /* */
347                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
348                 0, 0, pv_init_iname, 2},
349         {{"re", (sizeof("re")-1)}, /* */
350                 PVT_OTHER, pv_get_rpid, 0,
351                 0, 0, 0, 0},
352         {{"rm", (sizeof("rm")-1)}, /* */
353                 PVT_OTHER, pv_get_method, 0,
354                 0, 0, 0, 0},
355         {{"rmid", (sizeof("rmid")-1)}, /* */
356                 PVT_OTHER, pv_get_methodid, 0,
357                 0, 0, 0, 0},
358         {{"rp", (sizeof("rp")-1)}, /* */
359                 PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port,
360                 0, 0, pv_init_iname, 3},
361         {{"rP", (sizeof("rP")-1)}, /* */
362                 PVT_OTHER, pv_get_ruri_attr, 0,
363                 0, 0, pv_init_iname, 4},
364         {{"rr", (sizeof("rr")-1)}, /* */
365                 PVT_OTHER, pv_get_reason, 0,
366                 0, 0, 0, 0},
367         {{"rs", (sizeof("rs")-1)}, /* */
368                 PVT_OTHER, pv_get_status, 0,
369                 0, 0, 0, 0},
370         {{"rt", (sizeof("rt")-1)}, /* */
371                 PVT_OTHER, pv_get_refer_to, 0,
372                 0, 0, 0, 0},
373         {{"ru", (sizeof("ru")-1)}, /* */
374                 PVT_RURI, pv_get_ruri, pv_set_ruri,
375                 0, 0, 0, 0},
376         {{"ruri", (sizeof("ruri")-1)}, /* */
377                 PVT_RURI, pv_get_ruri, pv_set_ruri,
378                 0, 0, 0, 0},
379         {{"rU", (sizeof("rU")-1)}, /* */
380                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
381                 0, 0, pv_init_iname, 1},
382         {{"ruri.user", (sizeof("ruri.user")-1)}, /* */
383                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
384                 0, 0, pv_init_iname, 1},
385         {{"rv", (sizeof("rv")-1)}, /* */
386                 PVT_OTHER, pv_get_version, 0,
387                 0, 0, 0, 0},
388         {{"rz", (sizeof("rz")-1)}, /* */
389                 PVT_OTHER, pv_get_ruri_attr, 0,
390                 0, 0, pv_init_iname, 5},
391         {{"Ri", (sizeof("Ri")-1)}, /* */
392                 PVT_OTHER, pv_get_rcvip, 0,
393                 0, 0, 0, 0},
394         {{"Rp", (sizeof("Rp")-1)}, /* */
395                 PVT_OTHER, pv_get_rcvport, 0,
396                 0, 0, 0, 0},
397         {{"Ru", (sizeof("Ru")-1)}, /* */
398                 PVT_OTHER, pv_get_rcvaddr_uri, 0,
399                 0, 0, 0, 0},
400         {{"Rut", (sizeof("Rut")-1)}, /* */
401                 PVT_OTHER, pv_get_rcvaddr_uri_full, 0,
402                 0, 0, 0, 0},
403         {{"RAi", (sizeof("RAi")-1)}, /* */
404                 PVT_OTHER, pv_get_rcv_advertised_ip, 0,
405                 0, 0, 0, 0},
406         {{"RAp", (sizeof("RAp")-1)}, /* */
407                 PVT_OTHER, pv_get_rcv_advertised_port, 0,
408                 0, 0, 0, 0},
409         {{"RAu", (sizeof("RAu")-1)}, /* */
410                 PVT_OTHER, pv_get_rcvadv_uri, 0,
411                 0, 0, 0, 0},
412         {{"RAut", (sizeof("RAut")-1)}, /* */
413                 PVT_OTHER, pv_get_rcvadv_uri_full, 0,
414                 0, 0, 0, 0},
415         {{"sas", (sizeof("sas")-1)}, /* */
416                 PVT_OTHER, pv_get_srcaddr_socket, 0,
417                 0, 0, 0, 0},
418         {{"sf", (sizeof("sf")-1)}, /* */
419                 PVT_OTHER, pv_get_sflags, pv_set_sflags,
420                 0, 0, 0, 0},
421         {{"sF", (sizeof("sF")-1)}, /* */
422                 PVT_OTHER, pv_get_hexsflags, pv_set_sflags,
423                 0, 0, 0, 0},
424         {{"Sf", (sizeof("sf")-1)}, /* */
425                 PVT_OTHER, pv_get_sflag, pv_set_sflag,
426                 pv_parse_flag_param, 0, 0, 0},
427         {{"src_ip", (sizeof("src_ip")-1)}, /* */
428                 PVT_OTHER, pv_get_srcip, 0,
429                 0, 0, 0, 0},
430         {{"si", (sizeof("si")-1)}, /* */
431                 PVT_OTHER, pv_get_srcip, 0,
432                 0, 0, 0, 0},
433         {{"siz", (sizeof("siz")-1)}, /* */
434                 PVT_OTHER, pv_get_srcipz, 0,
435                 0, 0, 0, 0},
436         { {"sid", (sizeof("sid")-1)}, /* server id */
437                 PVT_OTHER, pv_get_server_id, 0,
438                 0, 0, 0, 0},
439         {{"sp", (sizeof("sp")-1)}, /* */
440                 PVT_OTHER, pv_get_srcport, 0,
441                 0, 0, 0, 0},
442         {{"su", (sizeof("su")-1)}, /* */
443                 PVT_OTHER, pv_get_srcaddr_uri, 0,
444                 0, 0, 0, 0},
445         {{"sut", (sizeof("sut")-1)}, /* */
446                 PVT_OTHER, pv_get_srcaddr_uri_full, 0,
447                 0, 0, 0, 0},
448         {{"td", (sizeof("td")-1)}, /* */
449                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
450                 0, 0, pv_init_iname, 3},
451         {{"to.domain", (sizeof("to.domain")-1)}, /* */
452                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
453                 0, 0, pv_init_iname, 3},
454         {{"tn", (sizeof("tn")-1)}, /* */
455                 PVT_OTHER, pv_get_to_attr, pv_set_to_display,
456                 0, 0, pv_init_iname, 5},
457         {{"tt", (sizeof("tt")-1)}, /* */
458                 PVT_OTHER, pv_get_to_attr, 0,
459                 0, 0, pv_init_iname, 4},
460         {{"tu", (sizeof("tu")-1)}, /* */
461                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
462                 0, 0, pv_init_iname, 1},
463         {{"to", (sizeof("to")-1)}, /* */
464                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
465                 0, 0, pv_init_iname, 1},
466         {{"tU", (sizeof("tU")-1)}, /* */
467                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
468                 0, 0, pv_init_iname, 2},
469         {{"to.user", (sizeof("to.user")-1)}, /* */
470                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
471                 0, 0, pv_init_iname, 2},
472         {{"true", (sizeof("true")-1)}, /* */
473                 PVT_OTHER, pv_get_true, 0,
474                 0, 0, 0, 0},
475         {{"Tb", (sizeof("Tb")-1)}, /* */
476                 PVT_OTHER, pv_get_timeb, 0,
477                 0, 0, 0, 0},
478         {{"Tf", (sizeof("Tf")-1)}, /* */
479                 PVT_CONTEXT, pv_get_timef, 0,
480                 0, 0, 0, 0},
481         {{"TF", (sizeof("TF")-1)}, /* */
482                 PVT_OTHER, pv_get_timenowf, 0,
483                 0, 0, 0, 0},
484         {{"Ts", (sizeof("Ts")-1)}, /* */
485                 PVT_CONTEXT, pv_get_times, 0,
486                 0, 0, 0, 0},
487         {{"TS", (sizeof("TS")-1)}, /* */
488                 PVT_OTHER, pv_get_timenows, 0,
489                 0, 0, 0, 0},
490         {{"ua", (sizeof("ua")-1)}, /* */
491                 PVT_OTHER, pv_get_useragent, 0,
492                 0, 0, 0, 0},
493         {{"ruid", (sizeof("ruid")-1)}, /* */
494                 PVT_OTHER, pv_get_ruid, 0,
495                 0, 0, 0, 0},
496         {{"location_ua", (sizeof("location_ua")-1)}, /* */
497                 PVT_OTHER, pv_get_location_ua, 0,
498                 0, 0, 0, 0},
499
500         { {"shv", (sizeof("shv")-1)}, PVT_OTHER, pv_get_shvar,
501                 pv_set_shvar, pv_parse_shvar_name, 0, 0, 0},
502         { {"time", (sizeof("time")-1)}, PVT_CONTEXT, pv_get_local_time,
503                 0, pv_parse_time_name, 0, 0, 0},
504         { {"timef", (sizeof("timef")-1)}, PVT_CONTEXT, pv_get_local_strftime,
505                 0, pv_parse_strftime_name, 0, 0, 0},
506         { {"utime", (sizeof("utime")-1)}, PVT_CONTEXT, pv_get_utc_time,
507                 0, pv_parse_time_name, 0, 0, 0},
508         { {"utimef", (sizeof("utimef")-1)}, PVT_CONTEXT, pv_get_utc_strftime,
509                 0, pv_parse_strftime_name, 0, 0, 0},
510         { {"TV", (sizeof("TV")-1)}, PVT_OTHER, pv_get_timeval,
511                 0, pv_parse_timeval_name, 0, 0, 0},
512         { {"nh", (sizeof("nh")-1)}, PVT_OTHER, pv_get_nh,
513                 0, pv_parse_nh_name, 0, 0, 0},
514         { {"version", (sizeof("version")-1)}, PVT_OTHER, pv_get_sr_version,
515                 0, pv_parse_sr_version_name, 0, 0, 0},
516         { {"K", (sizeof("K")-1)}, PVT_OTHER, pv_get_K, 0,
517                 pv_parse_K_name, 0, 0, 0 },
518         { {"expires", (sizeof("expires")-1)}, PVT_OTHER, pv_get_expires, 0,
519                 pv_parse_expires_name, 0, 0, 0 },
520         { {"msg", (sizeof("msg")-1)}, PVT_OTHER, pv_get_msg_attrs, 0,
521                 pv_parse_msg_attrs_name, 0, 0, 0 },
522         { {"ksr", (sizeof("ksr")-1)}, PVT_OTHER, pv_get_ksr_attrs, 0,
523                 pv_parse_ksr_attrs_name, 0, 0, 0 },
524
525         { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
526 };
527
528 static int add_avp_aliases(modparam_t type, void* val);
529
530 static param_export_t params[]={
531         {"shvset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_shvar },
532         {"varset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_var },
533         {"avp_aliases",         PARAM_STRING|USE_FUNC_PARAM, (void*)add_avp_aliases },
534         {0,0,0}
535 };
536
537 static int mod_init(void);
538 static void mod_destroy(void);
539 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo);
540 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
541 static int is_int(struct sip_msg* msg, char* pvar, char* s2);
542 static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
543 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
544 static int w_xavp_copy(sip_msg_t *msg, char *src_name, char *src_idx, char *dst_name);
545 static int w_xavp_copy_dst(sip_msg_t *msg, char *src_name, char *src_idx,
546                 char *dst_name, char *dst_idx);
547 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname);
548 static int w_xavp_params_implode(sip_msg_t *msg, char *pxname, char *pvname);
549 static int w_xavp_child_seti(sip_msg_t *msg, char *prname, char *pcname,
550                 char *pval);
551 static int w_xavp_child_sets(sip_msg_t *msg, char *prname, char *pcname,
552                 char *pval);
553 static int w_xavp_rm(sip_msg_t *msg, char *prname, char *p2);
554 static int w_xavp_child_rm(sip_msg_t *msg, char *prname, char *pcname);
555 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2);
556 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2);
557 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2);
558 static int w_var_to_xavp(sip_msg_t *msg, char *p1, char *p2);
559 static int w_xavp_to_var(sip_msg_t *msg, char *p1);
560
561 int pv_xavp_copy_fixup(void** param, int param_no);
562 int pv_evalx_fixup(void** param, int param_no);
563 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt);
564
565 static int fixup_xavp_child_seti(void** param, int param_no);
566 static int fixup_free_xavp_child_seti(void** param, int param_no);
567
568 static int pv_init_rpc(void);
569 int pv_register_api(pv_api_t*);
570
571 static cmd_export_t cmds[]={
572         {"pv_isset",  (cmd_function)pv_isset,  1, fixup_pvar_null, 0,
573                 ANY_ROUTE },
574         {"pv_unset",  (cmd_function)pv_unset,  1, fixup_pvar_null, 0,
575                 ANY_ROUTE },
576         {"pv_xavp_print",  (cmd_function)pv_xavp_print,  0, 0, 0,
577                 ANY_ROUTE },
578         {"pv_xavu_print",  (cmd_function)pv_xavu_print,  0, 0, 0,
579                 ANY_ROUTE },
580         {"pv_var_to_xavp",  (cmd_function)w_var_to_xavp, 2, fixup_spve_spve,
581                 fixup_free_spve_spve, ANY_ROUTE },
582         {"pv_xavp_to_var",  (cmd_function)w_xavp_to_var, 1, fixup_spve_null,
583                 fixup_free_spve_null, ANY_ROUTE },
584         {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, fixup_free_pvar_null,
585                 ANY_ROUTE},
586         {"typeof", (cmd_function)pv_typeof,       2, fixup_pvar_none,
587                 fixup_free_pvar_none,
588                 ANY_ROUTE},
589         {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null,
590                 fixup_free_pvar_null,
591                 ANY_ROUTE},
592         {"xavp_params_explode", (cmd_function)w_xavp_params_explode,
593                 2, fixup_spve_spve, fixup_free_spve_spve,
594                 ANY_ROUTE},
595         {"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0,
596                 ANY_ROUTE},
597         {"xavp_copy", (cmd_function)w_xavp_copy_dst, 4, pv_xavp_copy_fixup, 0,
598                 ANY_ROUTE},
599         {"xavp_params_implode", (cmd_function)w_xavp_params_implode,
600                 2, fixup_spve_str, fixup_free_spve_str,
601                 ANY_ROUTE},
602         {"xavp_child_seti", (cmd_function)w_xavp_child_seti,
603                 3, fixup_xavp_child_seti, fixup_free_xavp_child_seti,
604                 ANY_ROUTE},
605         {"xavp_child_sets", (cmd_function)w_xavp_child_sets,
606                 3, fixup_spve_all, fixup_free_spve_all,
607                 ANY_ROUTE},
608         {"xavp_rm", (cmd_function)w_xavp_rm,
609                 1, fixup_spve_null, fixup_free_spve_null,
610                 ANY_ROUTE},
611         {"xavp_child_rm", (cmd_function)w_xavp_child_rm,
612                 2, fixup_spve_spve, fixup_free_spve_spve,
613                 ANY_ROUTE},
614         {"sbranch_set_ruri",  (cmd_function)w_sbranch_set_ruri,  0, 0, 0,
615                 ANY_ROUTE },
616         {"sbranch_append",    (cmd_function)w_sbranch_append,    0, 0, 0,
617                 ANY_ROUTE },
618         {"sbranch_reset",     (cmd_function)w_sbranch_reset,     0, 0, 0,
619                 ANY_ROUTE },
620         {"pv_evalx",          (cmd_function)w_pv_evalx,    2, pv_evalx_fixup,
621                 0, ANY_ROUTE },
622         /* API exports */
623         {"pv_register_api",   (cmd_function)pv_register_api,     NO_SCRIPT, 0, 0},
624         {0,0,0,0,0,0}
625 };
626
627
628
629 /** module exports */
630 struct module_exports exports= {
631         "pv",            /* module name */
632         DEFAULT_DLFLAGS, /* dlopen flags */
633         cmds,            /* cmd (cfg function) exports */
634         params,          /* param exports */
635         0,               /* RPC method exports */
636         mod_pvs,         /* pv exports */
637         0,               /* response handling function */
638         mod_init,        /* module init function */
639         0,               /* per-child init function */
640         mod_destroy      /* module destroy function */
641 };
642
643 static int mod_init(void)
644 {
645         if(pv_init_rpc()!=0)
646         {
647                 LM_ERR("failed to register RPC commands\n");
648                 return -1;
649         }
650         pv_init_sbranch();
651
652         return 0;
653 }
654
655 static void mod_destroy(void)
656 {
657         shvar_destroy_locks();
658         destroy_shvars();
659 }
660
661 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo)
662 {
663         pv_spec_t *sp;
664         pv_value_t value;
665         int ret;
666
667         sp = (pv_spec_t*)pvid;
668         if(pv_get_spec_value(msg, sp, &value)!=0)
669                 return -1;
670         ret =1;
671         if(value.flags & (PV_VAL_EMPTY|PV_VAL_NULL))
672                 ret = -1;
673         pv_value_destroy(&value);
674         return ret;
675 }
676
677 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo)
678 {
679         pv_spec_t *sp;
680
681         sp = (pv_spec_t*)pvid;
682         if(pv_set_spec_value(msg, sp, 0, NULL)<0) {
683                 LM_ERR("faile to unset variable\n");
684                 return -1;
685         }
686
687         return 1;
688 }
689
690 static int add_avp_aliases(modparam_t type, void* val)
691 {
692         if (val!=0 && ((char*)val)[0]!=0)
693         {
694                 if ( add_avp_galias_str((char*)val)!=0 )
695                         return -1;
696         }
697
698         return 0;
699 }
700
701 /**
702  * match the type of the variable value
703  */
704 static int pv_typeof(sip_msg_t *msg, char *pv, char *t)
705 {
706         pv_value_t val;
707
708         if (pv==NULL || t==NULL)
709                 return -1;
710         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
711                 return -1;
712
713         switch(t[0]) {
714                 case 'i':
715                 case 'I':
716                         if(val.flags & PV_TYPE_INT)
717                                 return 1;
718                         return -1;
719                 case 'n':
720                 case 'N':
721                         if(val.flags & PV_VAL_NULL)
722                                 return 1;
723                         return -1;
724                 case 's':
725                 case 'S':
726                         if(!(val.flags & PV_VAL_STR))
727                                 return -1;
728                         if(val.flags & PV_TYPE_INT)
729                                 return -1;
730                         return 1;
731                 default:
732                         return -1;
733         }
734 }
735
736 /**
737  * return true if the type is string and value not empty
738  */
739 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2)
740 {
741         pv_value_t val;
742
743         if (pv==NULL)
744                 return -1;
745
746         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
747                 return -1;
748
749         if(!(val.flags & PV_VAL_STR))
750                 return -1;
751         if(val.flags & PV_TYPE_INT)
752                 return -1;
753
754         if(val.rs.len>0)
755                 return 1;
756
757         return -1;
758 }
759
760 /**
761  * Copyright (C) 2011 Juha Heinanen
762  *
763  * Checks if pvar argument contains int value
764  */
765 static int is_int(struct sip_msg* msg, char* pvar, char* s2)
766 {
767         pv_spec_t *pvar_sp;
768         pv_value_t pv_val;
769
770         pvar_sp = (pv_spec_t *)pvar;
771
772         if (pvar_sp && (pv_get_spec_value(msg, pvar_sp, &pv_val) == 0)) {
773                 return (pv_val.flags & PV_VAL_INT)?1:-1;
774         }
775
776         return -1;
777 }
778
779 /**
780  * script variable to xavp
781  */
782 static int w_var_to_xavp(sip_msg_t *msg, char *s1, char *s2)
783 {
784         str xname = STR_NULL;
785         str varname = STR_NULL;
786
787         if(fixup_get_svalue(msg, (gparam_t*)s1, &varname)<0) {
788                 LM_ERR("failed to get the var name\n");
789                 return -1;
790         }
791         if(fixup_get_svalue(msg, (gparam_t*)s2, &xname)<0) {
792                 LM_ERR("failed to get the xavp name\n");
793                 return -1;
794         }
795
796         return pv_var_to_xavp(&varname, &xname);
797 }
798
799 static int ki_var_to_xavp(sip_msg_t *msg, str *varname, str *xname)
800 {
801         return pv_var_to_xavp(varname, xname);
802 }
803
804 /**
805  * xavp to script variable
806  */
807 static int w_xavp_to_var(sip_msg_t *msg, char *s1)
808 {
809         str xname = STR_NULL;
810
811         if(fixup_get_svalue(msg, (gparam_t*)s1, &xname)<0) {
812                 LM_ERR("failed to get the xavp name\n");
813                 return -1;
814         }
815
816         return pv_xavp_to_var(&xname);
817 }
818
819 static int ki_xavp_to_var(sip_msg_t *msg, str *xname)
820 {
821         return pv_xavp_to_var(xname);
822 }
823
824 static int ki_xavp_print(sip_msg_t* msg)
825 {
826         xavp_print_list(NULL);
827         return 1;
828 }
829
830 static int ki_xavu_print(sip_msg_t* msg)
831 {
832         xavu_print_list(NULL);
833         return 1;
834 }
835
836 /**
837  *
838  */
839 static int ki_xavp_copy_dst_mode(str *src_name, int src_idx, str *dst_name,
840                 int dst_idx, int dimode)
841 {
842         sr_xavp_t *src_xavp = NULL;
843         sr_xavp_t *dst_xavp = NULL;
844         sr_xavp_t *new_xavp = NULL;
845         sr_xavp_t *prev_xavp = NULL;
846
847         src_xavp = xavp_get_by_index(src_name, src_idx, NULL);
848         if(!src_xavp) {
849                 LM_ERR("missing can not find source xavp [%.*s]\n",
850                                 src_name->len, src_name->s);
851                 return -1;
852         }
853
854         LM_DBG("dst_name xavp [%.*s]\n", dst_name->len, dst_name->s);
855         new_xavp = xavp_clone_level_nodata_with_new_name(src_xavp, dst_name);
856         if (!new_xavp) {
857                 LM_ERR("error cloning xavp\n");
858                 return -1;
859         }
860
861         if (dimode) {
862                 dst_xavp = xavp_get_by_index(dst_name, dst_idx, NULL);
863                 if(!dst_xavp) {
864                         LM_ERR("xavp_copy: missing can not find destination xavp [%.*s]\n",
865                                         dst_name->len, dst_name->s);
866                         xavp_destroy_list(&new_xavp);
867                         return -1;
868                 }
869
870                 LM_DBG("xavp_copy(replace): $xavp(%.*s[%d]) >> $xavp(%.*s[%d])\n",
871                                 src_name->len, src_name->s, src_idx,
872                                 dst_name->len, dst_name->s, dst_idx);
873                 if(dst_idx == 0) {
874                         if(xavp_add(new_xavp, NULL)<0) {
875                                 LM_ERR("error adding new xavp\n");
876                                 xavp_destroy_list(&new_xavp);
877                                 return -1;
878                         }
879                 } else {
880                         prev_xavp = xavp_get_by_index(dst_name, dst_idx-1, NULL);
881                         if(!prev_xavp) {
882                                 LM_ERR("error inserting xavp, parent not found $xavp(%.*s[%d])\n",
883                                                 dst_name->len, dst_name->s, dst_idx);
884                                 xavp_destroy_list(&new_xavp);
885                                 return -1;
886                         }
887                         xavp_add_after(new_xavp, prev_xavp);
888                 }
889                 if(xavp_rm(dst_xavp, NULL)<0) {
890                         LM_ERR("can not remove the exiting index $xavp(%.*s[%d])\n",
891                                         dst_name->len, dst_name->s, dst_idx);
892                         return -1;
893                 }
894         } else {
895                 /* check if destination exists,
896                  * if it does we will append, similar to XAVP assigment */
897                 dst_xavp = xavp_get(dst_name, NULL);
898                 if (!dst_xavp) {
899                         LM_DBG("xavp_copy(new): $xavp(%.*s[%d]) >> $xavp(%.*s)\n",
900                                         src_name->len, src_name->s, src_idx, dst_name->len,
901                                         dst_name->s);
902                         if(xavp_add(new_xavp, NULL)<0) {
903                                 LM_ERR("error adding new xavp\n");
904                                 xavp_destroy_list(&dst_xavp);
905                                 return -1;
906                         }
907                 } else {
908                         LM_DBG("xavp_copy(append): $xavp(%.*s[%d]) >> $xavp(%.*s)\n",
909                                         src_name->len, src_name->s, src_idx,
910                                         dst_name->len, dst_name->s);
911                         if(xavp_add_last(new_xavp, &dst_xavp)<0) {
912                                 LM_ERR("error appending new xavp\n");
913                                 xavp_destroy_list(&dst_xavp);
914                                 return -1;
915                         }
916                 }
917         }
918         return 1;
919 }
920
921 /**
922  *
923  */
924 static int ki_xavp_copy(sip_msg_t *msg, str *src_name, int src_idx, str *dst_name)
925 {
926         return ki_xavp_copy_dst_mode(src_name, src_idx, dst_name, 0, 0);
927 }
928
929 /**
930  *
931  */
932 static int ki_xavp_copy_dst(sip_msg_t *msg, str *src_name, int src_idx,
933                 str *dst_name, int dst_idx)
934 {
935         return ki_xavp_copy_dst_mode(src_name, src_idx, dst_name, dst_idx, 0);
936 }
937
938 /**
939  *
940  */
941 static int w_xavp_copy(sip_msg_t *msg, char *_src_name, char *_src_idx, char *_dst_name)
942 {
943         return w_xavp_copy_dst(msg, _src_name, _src_idx, _dst_name, NULL);
944 }
945
946 /**
947  *
948  */
949 static int w_xavp_copy_dst(sip_msg_t *msg, char *_src_name, char *_src_idx,
950                 char *_dst_name, char *_dst_idx)
951 {
952         str src_name;
953         int src_idx;
954         str dst_name;
955         int dst_idx;
956         int dimode;
957
958         if(get_str_fparam(&src_name, msg, (gparam_p)_src_name) != 0) {
959                 LM_ERR("xavp_copy: missing source\n");
960                 return -1;
961         }
962         if(get_str_fparam(&dst_name, msg, (gparam_p)_dst_name) != 0) {
963                 LM_ERR("xavp_copy: missing destination\n");
964                 return -1;
965         }
966         if(get_int_fparam(&src_idx, msg, (gparam_t*)_src_idx)<0) {
967                 LM_ERR("failed to get the src_idx value\n");
968                 return -1;
969         }
970         dst_idx = 0;
971         if (_dst_idx) {
972                 if(get_int_fparam(&dst_idx, msg, (gparam_t*)_dst_idx)<0) {
973                         LM_ERR("failed to get the dst_idx value\n");
974                         return -1;
975                 }
976                 dimode = 1;
977         } else {
978                 dimode = 0;
979         }
980         return ki_xavp_copy_dst_mode(&src_name, src_idx, &dst_name, dst_idx, dimode);
981 }
982
983 /**
984  *
985  */
986 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname)
987 {
988         str sparams;
989         str sxname;
990
991         if(fixup_get_svalue(msg, (gparam_t*)pparams, &sparams)!=0) {
992                 LM_ERR("cannot get the params\n");
993                 return -1;
994         }
995         if(fixup_get_svalue(msg, (gparam_t*)pxname, &sxname)!=0) {
996                 LM_ERR("cannot get the xavp name\n");
997                 return -1;
998         }
999
1000         if(xavp_params_explode(&sparams, &sxname)<0)
1001                 return -1;
1002
1003         return 1;
1004 }
1005
1006 /**
1007  *
1008  */
1009 static int ki_xavp_params_explode(sip_msg_t *msg, str *sparams, str *sxname)
1010 {
1011         if(xavp_params_explode(sparams, sxname)<0)
1012                 return -1;
1013
1014         return 1;
1015 }
1016
1017 /**
1018  *
1019  */
1020 static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname)
1021 {
1022         pv_spec_t *vspec=NULL;
1023         pv_value_t val;
1024
1025         if(sxname==NULL || sxname->s==NULL || sxname->len<=0) {
1026                 LM_ERR("invalid xavp name\n");
1027                 return -1;
1028         }
1029         if(svname==NULL || svname->s==NULL || svname->len<=0) {
1030                 LM_ERR("invalid output var name\n");
1031                 return -1;
1032         }
1033
1034         vspec = pv_cache_get(svname);
1035         if(vspec==NULL) {
1036                 LM_ERR("cannot get pv spec for [%.*s]\n", svname->len, svname->s);
1037                 return -1;
1038         }
1039         if(vspec->setf==NULL) {
1040                 LM_ERR("read only output variable [%.*s]\n", svname->len, svname->s);
1041                 return -1;
1042         }
1043
1044         val.rs.s = pv_get_buffer();
1045         val.rs.len = xavp_serialize_fields(sxname, val.rs.s, pv_get_buffer_size());
1046         if(val.rs.len<=0) {
1047                 return -1;
1048         }
1049
1050         val.flags = PV_VAL_STR;
1051         if(vspec->setf(msg, &vspec->pvp, EQ_T, &val)<0) {
1052                 LM_ERR("setting PV failed [%.*s]\n", svname->len, svname->s);
1053                 return -1;
1054         }
1055
1056         return 1;
1057 }
1058
1059 /**
1060  *
1061  */
1062 static int w_xavp_params_implode(sip_msg_t *msg, char *pxname, char *pvname)
1063 {
1064         str sxname;
1065
1066         if(fixup_get_svalue(msg, (gparam_t*)pxname, &sxname)!=0) {
1067                 LM_ERR("cannot get the xavp name\n");
1068                 return -1;
1069         }
1070
1071         return ki_xavp_params_implode(msg, &sxname, (str*)pvname);
1072 }
1073
1074 /**
1075  *
1076  */
1077 static int ki_xavp_seti(sip_msg_t *msg, str *rname, int ival)
1078 {
1079         sr_xavp_t *xavp = NULL;
1080         sr_xval_t xval;
1081
1082         memset(&xval, 0, sizeof(sr_xval_t));
1083         xval.type = SR_XTYPE_INT;
1084         xval.v.i = ival;
1085
1086         xavp = xavp_add_value(rname, &xval, NULL);
1087
1088         return (xavp!=NULL)?1:-1;
1089 }
1090
1091 /**
1092  *
1093  */
1094 static int ki_xavp_sets(sip_msg_t *msg, str *rname, str *sval)
1095 {
1096         sr_xavp_t *xavp = NULL;
1097         sr_xval_t xval;
1098
1099         memset(&xval, 0, sizeof(sr_xval_t));
1100         xval.type = SR_XTYPE_STR;
1101         xval.v.s = *sval;
1102
1103         xavp = xavp_add_value(rname, &xval, NULL);
1104
1105         return (xavp!=NULL)?1:-1;
1106 }
1107
1108 /**
1109  *
1110  */
1111 static int ki_xavp_child_seti(sip_msg_t *msg, str *rname, str *cname,
1112                 int ival)
1113 {
1114         int ret;
1115
1116         ret = xavp_set_child_ival(rname, cname, ival);
1117
1118         return (ret<0)?ret:1;
1119 }
1120
1121 /**
1122  *
1123  */
1124 static int w_xavp_child_seti(sip_msg_t *msg, char *prname, char *pcname,
1125                 char *pval)
1126 {
1127         str rname = STR_NULL;
1128         str cname = STR_NULL;
1129         int ival = 0;
1130
1131         if(fixup_get_svalue(msg, (gparam_t*)prname, &rname)<0) {
1132                 LM_ERR("failed to get root xavp name\n");
1133                 return -1;
1134         }
1135         if(fixup_get_svalue(msg, (gparam_t*)pcname, &cname)<0) {
1136                 LM_ERR("failed to get child xavp name\n");
1137                 return -1;
1138         }
1139         if(fixup_get_ivalue(msg, (gparam_t*)pval, &ival)<0) {
1140                 LM_ERR("failed to get the value\n");
1141                 return -1;
1142         }
1143
1144         return ki_xavp_child_seti(msg, &rname, &cname, ival);
1145 }
1146
1147 /**
1148  *
1149  */
1150 static int ki_xavp_child_sets(sip_msg_t *msg, str *rname, str *cname,
1151                 str *sval)
1152 {
1153         int ret;
1154
1155         ret = xavp_set_child_sval(rname, cname, sval);
1156
1157         return (ret<0)?ret:1;
1158 }
1159
1160 /**
1161  *
1162  */
1163 static int w_xavp_child_sets(sip_msg_t *msg, char *prname, char *pcname,
1164                 char *pval)
1165 {
1166         str rname;
1167         str cname;
1168         str sval;
1169
1170         if(fixup_get_svalue(msg, (gparam_t*)prname, &rname)<0) {
1171                 LM_ERR("failed to get root xavp name\n");
1172                 return -1;
1173         }
1174         if(fixup_get_svalue(msg, (gparam_t*)pcname, &cname)<0) {
1175                 LM_ERR("failed to get child xavp name\n");
1176                 return -1;
1177         }
1178         if(fixup_get_svalue(msg, (gparam_t*)pval, &sval)<0) {
1179                 LM_ERR("failed to get the value\n");
1180                 return -1;
1181         }
1182
1183         return ki_xavp_child_sets(msg, &rname, &cname, &sval);
1184 }
1185
1186 /**
1187  *
1188  */
1189 static int fixup_xavp_child_seti(void** param, int param_no)
1190 {
1191         if(param_no==1 || param_no==2)
1192                 return fixup_spve_all(param, param_no);
1193         if(param_no==3)
1194                 return fixup_igp_all(param, param_no);
1195         return 0;
1196 }
1197
1198 /**
1199  *
1200  */
1201 static int fixup_free_xavp_child_seti(void** param, int param_no)
1202 {
1203         if(param_no==1 || param_no==2)
1204                 return fixup_free_spve_all(param, param_no);
1205         if(param_no==3)
1206                 return fixup_free_igp_all(param, param_no);
1207
1208         return 0;
1209 }
1210
1211 /**
1212  *
1213  */
1214 static int ki_xavp_rm(sip_msg_t *msg, str *rname)
1215 {
1216         int ret;
1217
1218         ret = xavp_rm_by_index(rname, 0, NULL);
1219
1220         return (ret==0)?1:ret;
1221 }
1222
1223 /**
1224  *
1225  */
1226 static int w_xavp_rm(sip_msg_t *msg, char *prname, char *p2)
1227 {
1228         str rname;
1229
1230         if(fixup_get_svalue(msg, (gparam_t*)prname, &rname)<0) {
1231                 LM_ERR("failed to get root xavp name\n");
1232                 return -1;
1233         }
1234
1235         return ki_xavp_rm(msg, &rname);
1236 }
1237
1238 /**
1239  *
1240  */
1241 static int ki_xavp_child_rm(sip_msg_t *msg, str *rname, str *cname)
1242 {
1243         int ret;
1244
1245         ret = xavp_rm_child_by_index(rname, cname, 0);
1246
1247         return (ret==0)?1:ret;
1248 }
1249
1250 /**
1251  *
1252  */
1253 static int w_xavp_child_rm(sip_msg_t *msg, char *prname, char *pcname)
1254 {
1255         str rname;
1256         str cname;
1257
1258         if(fixup_get_svalue(msg, (gparam_t*)prname, &rname)<0) {
1259                 LM_ERR("failed to get root xavp name\n");
1260                 return -1;
1261         }
1262         if(fixup_get_svalue(msg, (gparam_t*)pcname, &cname)<0) {
1263                 LM_ERR("failed to get child xavp name\n");
1264                 return -1;
1265         }
1266
1267         return ki_xavp_child_rm(msg, &rname, &cname);
1268 }
1269
1270 /**
1271  *
1272  */
1273 static int ki_xavp_is_null(sip_msg_t *msg, str *rname)
1274 {
1275         sr_xavp_t *xavp=NULL;
1276
1277         xavp = xavp_get_by_index(rname, 0, NULL);
1278         if(xavp==NULL) {
1279                 return 1;
1280         }
1281         if(xavp->val.type == SR_XTYPE_NULL) {
1282                 return 1;
1283         }
1284         return -1;
1285 }
1286
1287 /**
1288  *
1289  */
1290 static sr_kemi_xval_t _sr_kemi_pv_xval = {0};
1291
1292 /**
1293  *
1294  */
1295 static sr_kemi_xval_t* ki_xavp_get_xval(sr_xavp_t *xavp, int rmode)
1296 {
1297         static char _pv_ki_xavp_buf[128];
1298
1299         switch(xavp->val.type) {
1300                 case SR_XTYPE_NULL:
1301                         sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1302                         return &_sr_kemi_pv_xval;
1303                 break;
1304                 case SR_XTYPE_INT:
1305                         _sr_kemi_pv_xval.vtype = SR_KEMIP_INT;
1306                         _sr_kemi_pv_xval.v.n = xavp->val.v.i;
1307                         return &_sr_kemi_pv_xval;
1308                 break;
1309                 case SR_XTYPE_STR:
1310                         _sr_kemi_pv_xval.vtype = SR_KEMIP_STR;
1311                         _sr_kemi_pv_xval.v.s = xavp->val.v.s;
1312                         return &_sr_kemi_pv_xval;
1313                 break;
1314                 case SR_XTYPE_TIME:
1315                         if(snprintf(_pv_ki_xavp_buf, 128, "%lu", (long unsigned)xavp->val.v.t)<0) {
1316                                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1317                                 return &_sr_kemi_pv_xval;
1318                         }
1319                 break;
1320                 case SR_XTYPE_LONG:
1321                         if(snprintf(_pv_ki_xavp_buf, 128, "%ld", (long unsigned)xavp->val.v.l)<0) {
1322                                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1323                                 return &_sr_kemi_pv_xval;
1324                         }
1325                 break;
1326                 case SR_XTYPE_LLONG:
1327                         if(snprintf(_pv_ki_xavp_buf, 128, "%lld", xavp->val.v.ll)<0) {
1328                                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1329                                 return &_sr_kemi_pv_xval;
1330                         }
1331                 break;
1332                 case SR_XTYPE_XAVP:
1333                         if(snprintf(_pv_ki_xavp_buf, 128, "<<xavp:%p>>", xavp->val.v.xavp)<0) {
1334                                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1335                                 return &_sr_kemi_pv_xval;
1336                         }
1337                 break;
1338                 case SR_XTYPE_DATA:
1339                         if(snprintf(_pv_ki_xavp_buf, 128, "<<data:%p>>", xavp->val.v.data)<0) {
1340                                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1341                                 return &_sr_kemi_pv_xval;
1342                         }
1343                 break;
1344                 default:
1345                         sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1346                         return &_sr_kemi_pv_xval;
1347         }
1348
1349         _sr_kemi_pv_xval.vtype = SR_KEMIP_STR;
1350         _sr_kemi_pv_xval.v.s.s = _pv_ki_xavp_buf;
1351         _sr_kemi_pv_xval.v.s.len = strlen(_pv_ki_xavp_buf);
1352         return &_sr_kemi_pv_xval;
1353 }
1354
1355 /**
1356  *
1357  */
1358 static sr_kemi_xval_t* ki_xavp_get_mode(sip_msg_t *msg, str *rname, int rmode)
1359 {
1360         sr_xavp_t *xavp=NULL;
1361
1362         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1363
1364         xavp = xavp_get_by_index(rname, 0, NULL);
1365         if(xavp==NULL) {
1366                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1367                 return &_sr_kemi_pv_xval;
1368         }
1369
1370         return ki_xavp_get_xval(xavp, rmode);
1371 }
1372
1373 /**
1374  *
1375  */
1376 static sr_kemi_xval_t* ki_xavp_get(sip_msg_t *msg, str *rname)
1377 {
1378         return ki_xavp_get_mode(msg, rname, SR_KEMI_XVAL_NULL_NONE);
1379 }
1380
1381 /**
1382  *
1383  */
1384 static sr_kemi_xval_t* ki_xavp_gete(sip_msg_t *msg, str *rname)
1385 {
1386         return ki_xavp_get_mode(msg, rname, SR_KEMI_XVAL_NULL_EMPTY);
1387 }
1388
1389 /**
1390  *
1391  */
1392 static sr_kemi_xval_t* ki_xavp_getw(sip_msg_t *msg, str *rname)
1393 {
1394         return ki_xavp_get_mode(msg, rname, SR_KEMI_XVAL_NULL_PRINT);
1395 }
1396
1397 sr_kemi_dict_item_t* ki_xavp_dict(sr_xavp_t *xavp);
1398 /**
1399  * SR_KEMIP_ARRAY with values of xavp=>name
1400  */
1401 sr_kemi_dict_item_t* ki_xavp_dict_name(sr_xavp_t *xavp, str name)
1402 {
1403         sr_kemi_dict_item_t *ini = NULL;
1404         sr_kemi_dict_item_t *val;
1405         sr_kemi_dict_item_t *last = NULL;
1406         sr_xavp_t *avp = xavp;
1407
1408         ini = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1409         if(ini==NULL) {
1410                 PKG_MEM_ERROR;
1411                 return NULL;
1412         }
1413         memset(ini, 0, sizeof(sr_kemi_xval_t));
1414         ini->vtype = SR_KEMIP_ARRAY;
1415         while(avp!=NULL&&!STR_EQ(avp->name,name))
1416         {
1417                 avp = avp->next;
1418         }
1419
1420         while(avp!=NULL){
1421                 switch(avp->val.type) {
1422                         case SR_XTYPE_XAVP:
1423                         break;
1424                         default:
1425                                 val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1426                                 if(val==NULL) {
1427                                         PKG_MEM_ERROR;
1428                                         goto error;
1429                                 }
1430                                 memset(val, 0, sizeof(sr_kemi_xval_t));
1431                         break;
1432                 }
1433                 switch(avp->val.type) {
1434                         case SR_XTYPE_NULL:
1435                                 val->vtype = SR_KEMIP_NULL;
1436                         break;
1437                         case SR_XTYPE_INT:
1438                                 val->vtype = SR_KEMIP_INT;
1439                                 val->v.n = avp->val.v.i;
1440                         break;
1441                         case SR_XTYPE_STR:
1442                                 val->vtype = SR_KEMIP_STR;
1443                                 val->v.s.s = avp->val.v.s.s;
1444                                 val->v.s.len = avp->val.v.s.len;
1445                         break;
1446                         case SR_XTYPE_TIME:
1447                         case SR_XTYPE_LONG:
1448                         case SR_XTYPE_LLONG:
1449                         case SR_XTYPE_DATA:
1450                                 val->vtype = SR_KEMIP_NULL;
1451                                 LM_WARN("XAVP type:%d value not supported\n", avp->val.type);
1452                         break;
1453                         case SR_XTYPE_XAVP:
1454                                 val = ki_xavp_dict(avp->val.v.xavp);
1455                         break;
1456                         default:
1457                                 val->vtype = SR_KEMIP_NULL;
1458                                 LM_ERR("xavp:%.*s unknown type: %d\n",
1459                                         avp->name.len, avp->name.s, avp->val.type);
1460                         break;
1461                 }
1462                 if(last) {
1463                         last->next = val;
1464                 } else {
1465                         ini->v.dict = val;
1466                         last = val;
1467                 }
1468                 avp = xavp_get_next(avp);
1469         }
1470         return ini;
1471 error:
1472         while(ini) {
1473                 last = ini;
1474                 ini = ini->next;
1475                 pkg_free(last);
1476         }
1477         return NULL;
1478 }
1479
1480 /**
1481  * SR_KEMIP_DICT of xavp
1482  */
1483 sr_kemi_dict_item_t* ki_xavp_dict(sr_xavp_t *xavp) {
1484         sr_xavp_t *avp = NULL;
1485         struct str_list *keys;
1486         struct str_list *k;
1487         sr_kemi_dict_item_t *val;
1488         sr_kemi_dict_item_t *ini = NULL;
1489         sr_kemi_dict_item_t *last = NULL;
1490
1491         if(xavp->val.type!=SR_XTYPE_XAVP) {
1492                 LM_ERR("%s not xavp?\n", xavp->name.s);
1493                 return NULL;
1494         }
1495         avp = xavp->val.v.xavp;
1496         if((keys = xavp_get_list_key_names(xavp)) != NULL) {
1497                 do {
1498                         val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1499                         if(val==NULL) {
1500                                 PKG_MEM_ERROR;
1501                                 goto error;
1502                         }
1503                         memset(val, 0, sizeof(sr_kemi_xval_t));
1504                         val->vtype = SR_KEMIP_DICT;
1505                         val->name.s = keys->s.s;
1506                         val->name.len = keys->s.len;
1507                         val->v.dict = ki_xavp_dict_name(avp, keys->s);
1508                         if(last) {
1509                                 last->next = val;
1510                         } else {
1511                                 ini = val;
1512                                 last = ini;
1513                         }
1514                         k = keys;
1515                         keys = keys->next;
1516                         pkg_free(k);
1517                 } while(keys!=NULL);
1518         }
1519         return ini;
1520 error:
1521         while(keys!=NULL) {
1522                 k = keys;
1523                 keys = keys->next;
1524                 pkg_free(k);
1525         }
1526         while(ini) {
1527                 val = ini;
1528                 ini = ini->next;
1529                 pkg_free(val);
1530         }
1531         return NULL;
1532 }
1533
1534 /**
1535  *
1536  */
1537 static sr_kemi_xval_t*
1538 ki_xavp_getd_helper(sip_msg_t *msg, str *rname, int *_indx)
1539 {
1540         sr_xavp_t *xavp=NULL;
1541         int xavp_size = 0;
1542         int indx = 0;
1543         sr_kemi_dict_item_t *val;
1544         sr_kemi_dict_item_t *last = NULL;
1545
1546         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1547         if(_indx) {
1548                 indx = *_indx;
1549                 /* we're going to retrive just one */
1550                 _sr_kemi_pv_xval.vtype = SR_KEMIP_DICT;
1551         } else {
1552                 /* we're going to retrive all */
1553                 _sr_kemi_pv_xval.vtype = SR_KEMIP_ARRAY;
1554         }
1555         xavp_size = xavp_count(rname, NULL);
1556         if(indx<0)
1557         {
1558                 if((indx*-1)>xavp_size)
1559                 {
1560                         sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1561                         return &_sr_kemi_pv_xval;
1562                 }
1563                 indx = xavp_size + indx;
1564         }
1565
1566         xavp = xavp_get_by_index(rname, indx, NULL);
1567         if(xavp==NULL) {
1568                 sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1569                 return &_sr_kemi_pv_xval;
1570         }
1571         do {
1572                 val = ki_xavp_dict(xavp);
1573                 if(last) {
1574                         last->next = val;
1575                 } else {
1576                         _sr_kemi_pv_xval.v.dict = val;
1577                 }
1578                 if(val) last = val;
1579                 if(_indx) {
1580                         xavp = NULL;
1581                 } else {
1582                         indx = indx + 1;
1583                         xavp = xavp_get_by_index(rname, indx, NULL);
1584                 }
1585         } while(xavp!=NULL);
1586         return &_sr_kemi_pv_xval;
1587 }
1588
1589 /**
1590  *
1591  */
1592 static sr_kemi_xval_t*
1593 ki_xavp_getd(sip_msg_t *msg, str *rname)
1594 {
1595         return ki_xavp_getd_helper(msg, rname, NULL);
1596 }
1597
1598 /**
1599  *
1600  */
1601 static sr_kemi_xval_t*
1602 ki_xavp_getd_p1(sip_msg_t *msg, str *rname, int indx)
1603 {
1604         return ki_xavp_getd_helper(msg, rname, &indx);
1605 }
1606
1607 /**
1608  *
1609  */
1610 static sr_kemi_xval_t*
1611 ki_xavp_get_keys(sip_msg_t *msg, str *rname, int indx) {
1612         sr_xavp_t *xavp=NULL;
1613         struct str_list *keys, *k;
1614         sr_kemi_dict_item_t *val;
1615         sr_kemi_dict_item_t *last = NULL;
1616
1617         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1618
1619         xavp = xavp_get_by_index(rname, indx, NULL);
1620         if(xavp==NULL) {
1621                 sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1622                 return &_sr_kemi_pv_xval;
1623         }
1624         keys = xavp_get_list_key_names(xavp);
1625         _sr_kemi_pv_xval.vtype = SR_KEMIP_ARRAY;
1626         while(keys!=NULL){
1627                 k = keys;
1628                 val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1629                 if(val==NULL) {
1630                         PKG_MEM_ERROR;
1631                         goto error;
1632                 }
1633                 memset(val, 0, sizeof(sr_kemi_xval_t));
1634                 val->vtype = SR_KEMIP_STR;
1635                 val->v.s.len = k->s.len;
1636                 val->v.s.s = k->s.s;
1637                 keys = k->next;
1638                 pkg_free(k);
1639                 if(last) {
1640                         last->next = val;
1641                 } else {
1642                         _sr_kemi_pv_xval.v.dict = val;
1643                 }
1644                 last = val;
1645         }
1646         return &_sr_kemi_pv_xval;
1647 error:
1648         while(keys!=NULL) {
1649                 k = keys;
1650                 keys = keys->next;
1651                 pkg_free(k);
1652         }
1653         last = _sr_kemi_pv_xval.v.dict;
1654         while(last) {
1655                 val = last;
1656                 last = last->next;
1657                 pkg_free(val);
1658         }
1659         sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1660         return &_sr_kemi_pv_xval;
1661 }
1662
1663 /**
1664  *
1665  */
1666 static int ki_xavp_child_is_null(sip_msg_t *msg, str *rname, str *cname)
1667 {
1668         sr_xavp_t *xavp=NULL;
1669
1670         xavp = xavp_get_by_index(rname, 0, NULL);
1671         if(xavp==NULL) {
1672                 return 1;
1673         }
1674         if(xavp->val.type != SR_XTYPE_XAVP) {
1675                 return 1;
1676         }
1677         xavp = xavp_get_by_index(cname, 0, &xavp->val.v.xavp);
1678         if(xavp==NULL) {
1679                 return 1;
1680         }
1681         if(xavp->val.type == SR_XTYPE_NULL) {
1682                 return 1;
1683         }
1684         return -1;
1685 }
1686
1687 /**
1688  *
1689  */
1690 static sr_kemi_xval_t* ki_xavp_child_get_mode(sip_msg_t *msg, str *rname,
1691                 str *cname, int rmode)
1692 {
1693         sr_xavp_t *xavp=NULL;
1694
1695         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1696
1697         xavp = xavp_get_by_index(rname, 0, NULL);
1698         if(xavp==NULL) {
1699                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1700                 return &_sr_kemi_pv_xval;
1701         }
1702
1703         if(xavp->val.type != SR_XTYPE_XAVP) {
1704                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1705                 return &_sr_kemi_pv_xval;
1706         }
1707
1708         xavp = xavp_get_by_index(cname, 0, &xavp->val.v.xavp);
1709         if(xavp==NULL) {
1710                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1711                 return &_sr_kemi_pv_xval;
1712         }
1713
1714         return ki_xavp_get_xval(xavp, rmode);
1715 }
1716
1717 /**
1718  *
1719  */
1720 static sr_kemi_xval_t* ki_xavp_child_get(sip_msg_t *msg, str *rname, str *cname)
1721 {
1722         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_NONE);
1723 }
1724
1725
1726 /**
1727  *
1728  */
1729 static sr_kemi_xval_t* ki_xavp_child_gete(sip_msg_t *msg, str *rname, str *cname)
1730 {
1731         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_EMPTY);
1732 }
1733
1734
1735 /**
1736  *
1737  */
1738 static sr_kemi_xval_t* ki_xavp_child_getw(sip_msg_t *msg, str *rname, str *cname)
1739 {
1740         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_PRINT);
1741 }
1742
1743 /**
1744  *
1745  */
1746 static int ki_xavu_is_null(sip_msg_t *msg, str *rname)
1747 {
1748         sr_xavp_t *xavu=NULL;
1749
1750         xavu = xavu_lookup(rname, NULL);
1751         if(xavu==NULL) {
1752                 return 1;
1753         }
1754         if(xavu->val.type == SR_XTYPE_NULL) {
1755                 return 1;
1756         }
1757         return -1;
1758 }
1759
1760 /**
1761  *
1762  */
1763 static int ki_xavu_rm(sip_msg_t *msg, str *rname)
1764 {
1765         int ret;
1766
1767         ret = xavu_rm_by_name(rname, NULL);
1768
1769         return (ret==0)?1:ret;
1770 }
1771
1772 /**
1773  *
1774  */
1775 static int ki_xavu_child_rm(sip_msg_t *msg, str *rname, str *cname)
1776 {
1777         int ret;
1778
1779         ret = xavu_rm_child_by_name(rname, cname);
1780
1781         return (ret==0)?1:ret;
1782 }
1783
1784 /**
1785  *
1786  */
1787 static int ki_xavu_seti(sip_msg_t *msg, str *rname, int ival)
1788 {
1789         sr_xavp_t *xavp = NULL;
1790
1791         xavp = xavu_set_ival(rname, ival);
1792
1793         return (xavp!=NULL)?1:-1;
1794 }
1795
1796 /**
1797  *
1798  */
1799 static int ki_xavu_sets(sip_msg_t *msg, str *rname, str *sval)
1800 {
1801         sr_xavp_t *xavp = NULL;
1802
1803         xavp = xavu_set_sval(rname, sval);
1804
1805         return (xavp!=NULL)?1:-1;
1806 }
1807
1808 /**
1809  *
1810  */
1811 static int ki_xavu_child_seti(sip_msg_t *msg, str *rname, str *cname,
1812                 int ival)
1813 {
1814         sr_xavp_t *xavu = NULL;
1815
1816         xavu = xavu_set_child_ival(rname, cname, ival);
1817
1818         return (xavu!=NULL)?1:-1;
1819 }
1820
1821 /**
1822  *
1823  */
1824 static int ki_xavu_child_sets(sip_msg_t *msg, str *rname, str *cname,
1825                 str *sval)
1826 {
1827         sr_xavp_t *xavu = NULL;
1828
1829         xavu = xavu_set_child_sval(rname, cname, sval);
1830
1831         return (xavu!=NULL)?1:-1;
1832 }
1833
1834 /**
1835  *
1836  */
1837 static sr_kemi_xval_t* ki_xavu_get_mode(sip_msg_t *msg, str *rname, int rmode)
1838 {
1839         sr_xavp_t *xavu=NULL;
1840
1841         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1842
1843         xavu = xavu_lookup(rname, NULL);
1844         if(xavu==NULL) {
1845                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1846                 return &_sr_kemi_pv_xval;
1847         }
1848
1849         return ki_xavp_get_xval(xavu, rmode);
1850 }
1851
1852 /**
1853  *
1854  */
1855 static sr_kemi_xval_t* ki_xavu_get(sip_msg_t *msg, str *rname)
1856 {
1857         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_NONE);
1858 }
1859
1860 /**
1861  *
1862  */
1863 static sr_kemi_xval_t* ki_xavu_gete(sip_msg_t *msg, str *rname)
1864 {
1865         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_EMPTY);
1866 }
1867
1868 /**
1869  *
1870  */
1871 static sr_kemi_xval_t* ki_xavu_getw(sip_msg_t *msg, str *rname)
1872 {
1873         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_PRINT);
1874 }
1875
1876 /**
1877  *
1878  */
1879 static int ki_xavu_child_is_null(sip_msg_t *msg, str *rname, str *cname)
1880 {
1881         sr_xavp_t *xavu=NULL;
1882
1883         xavu = xavp_get_by_index(rname, 0, NULL);
1884         if(xavu==NULL) {
1885                 return 1;
1886         }
1887         if(xavu->val.type != SR_XTYPE_XAVP) {
1888                 return 1;
1889         }
1890         xavu = xavp_get_by_index(cname, 0, &xavu->val.v.xavp);
1891         if(xavu==NULL) {
1892                 return 1;
1893         }
1894         if(xavu->val.type == SR_XTYPE_NULL) {
1895                 return 1;
1896         }
1897         return -1;
1898 }
1899
1900 /**
1901  *
1902  */
1903 static sr_kemi_xval_t* ki_xavu_child_get_mode(sip_msg_t *msg, str *rname,
1904                 str *cname, int rmode)
1905 {
1906         sr_xavp_t *xavu=NULL;
1907
1908         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1909
1910         xavu = xavu_lookup(rname, NULL);
1911         if(xavu==NULL) {
1912                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1913                 return &_sr_kemi_pv_xval;
1914         }
1915
1916         if(xavu->val.type != SR_XTYPE_XAVP) {
1917                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1918                 return &_sr_kemi_pv_xval;
1919         }
1920
1921         xavu = xavp_get_by_index(cname, 0, &xavu->val.v.xavp);
1922         if(xavu==NULL) {
1923                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1924                 return &_sr_kemi_pv_xval;
1925         }
1926
1927         return ki_xavp_get_xval(xavu, rmode);
1928 }
1929
1930 /**
1931  *
1932  */
1933 static sr_kemi_xval_t* ki_xavu_child_get(sip_msg_t *msg, str *rname, str *cname)
1934 {
1935         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_NONE);
1936 }
1937
1938
1939 /**
1940  *
1941  */
1942 static sr_kemi_xval_t* ki_xavu_child_gete(sip_msg_t *msg, str *rname, str *cname)
1943 {
1944         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_EMPTY);
1945 }
1946
1947
1948 /**
1949  *
1950  */
1951 static sr_kemi_xval_t* ki_xavu_child_getw(sip_msg_t *msg, str *rname, str *cname)
1952 {
1953         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_PRINT);
1954 }
1955
1956 /**
1957  *
1958  */
1959 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2)
1960 {
1961         if(sbranch_set_ruri(msg)<0)
1962                 return -1;
1963         return 1;
1964 }
1965
1966 /**
1967  *
1968  */
1969 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2)
1970 {
1971         if(sbranch_append(msg)<0)
1972                 return -1;
1973         return 1;
1974 }
1975
1976 /**
1977  *
1978  */
1979 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2)
1980 {
1981         if(sbranch_reset()<0)
1982                 return -1;
1983         return 1;
1984 }
1985
1986 /**
1987  *
1988  */
1989 static int ki_sbranch_set_ruri(sip_msg_t *msg)
1990 {
1991         if(sbranch_set_ruri(msg)<0)
1992                 return -1;
1993         return 1;
1994 }
1995
1996 /**
1997  *
1998  */
1999 static int ki_sbranch_append(sip_msg_t *msg)
2000 {
2001         if(sbranch_append(msg)<0)
2002                 return -1;
2003         return 1;
2004 }
2005
2006 /**
2007  *
2008  */
2009 static int ki_sbranch_reset(sip_msg_t *msg)
2010 {
2011         if(sbranch_reset()<0)
2012                 return -1;
2013         return 1;
2014 }
2015
2016 int pv_xavp_copy_fixup(void **param, int param_no)
2017 {
2018         if(param_no == 1 || param_no == 3)
2019                 return fixup_var_str_12(param, param_no);
2020         if (param_no == 2 || param_no == 4)
2021                 return fixup_var_int_12(param, param_no);
2022         LM_ERR("invalid parameter count [%d]\n", param_no);
2023         return -1;
2024 }
2025
2026 int pv_evalx_fixup(void** param, int param_no)
2027 {
2028         pv_spec_t *spec=NULL;
2029         pv_elem_t *pvmodel=NULL;
2030         str tstr;
2031
2032         if(param_no==1) {
2033                 spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
2034                 if(spec==NULL) {
2035                         LM_ERR("out of pkg\n");
2036                         return -1;
2037                 }
2038                 memset(spec, 0, sizeof(pv_spec_t));
2039                 tstr.s = (char*)(*param);
2040                 tstr.len = strlen(tstr.s);
2041                 if(pv_parse_spec(&tstr, spec)==NULL) {
2042                         LM_ERR("unknown script variable in first parameter\n");
2043                         pkg_free(spec);
2044                         return -1;
2045                 }
2046                 if(!pv_is_w(spec)) {
2047                         LM_ERR("read-only script variable in first parameter\n");
2048                         pkg_free(spec);
2049                         return -1;
2050                 }
2051                 *param = spec;
2052         } else if(param_no==2) {
2053                 pvmodel = 0;
2054                 tstr.s = (char*)(*param);
2055                 tstr.len = strlen(tstr.s);
2056                 if(pv_parse_format(&tstr, &pvmodel)<0) {
2057                         LM_ERR("error in second parameter\n");
2058                         return -1;
2059                 }
2060                 *param = pvmodel;
2061         }
2062         return 0;
2063 }
2064
2065 /**
2066  *
2067  */
2068 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt)
2069 {
2070         pv_spec_t *ispec=NULL;
2071         pv_elem_t *imodel=NULL;
2072         str tstr = {0, 0};
2073         pv_value_t val;
2074
2075         ispec = (pv_spec_t*)dst;
2076
2077         imodel = (pv_elem_t*)fmt;
2078
2079         memset(&val, 0, sizeof(pv_value_t));
2080
2081         if(pv_printf_s(msg, imodel, &tstr)!=0) {
2082                 LM_ERR("cannot eval second parameter\n");
2083                 goto error;
2084         }
2085
2086         LM_DBG("preparing to evaluate: [%.*s]\n", tstr.len, tstr.s);
2087         if(pv_eval_str(msg, &val.rs, &tstr)<0){
2088                 LM_ERR("cannot eval reparsed value of second parameter\n");
2089                 return -1;
2090         }
2091
2092         val.flags = PV_VAL_STR;
2093         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
2094                 LM_ERR("setting PV failed\n");
2095                 goto error;
2096         }
2097
2098         return 1;
2099 error:
2100         return -1;
2101 }
2102
2103 /**
2104  *
2105  */
2106 int ki_pv_evalx(sip_msg_t *msg, str *dst, str *fmt)
2107 {
2108         pv_value_t val;
2109         pv_spec_t *ispec=NULL;
2110
2111         if(dst==NULL || dst->s==NULL || dst->len<=0) {
2112                 LM_ERR("invalid destination var name\n");
2113                 return -1;
2114         }
2115         ispec = pv_cache_get(dst);
2116         if(ispec==NULL) {
2117                 LM_ERR("cannot get pv spec for [%.*s]\n", dst->len, dst->s);
2118                 return -1;
2119         }
2120
2121         memset(&val, 0, sizeof(pv_value_t));
2122         if(pv_eval_str(msg, &val.rs, fmt)<0) {
2123                 LM_ERR("cannot eval reparsed value of second parameter\n");
2124                 return -1;
2125         }
2126
2127         val.flags = PV_VAL_STR;
2128         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
2129                 LM_ERR("setting PV failed\n");
2130                 goto error;
2131         }
2132
2133         return 1;
2134 error:
2135         return -1;
2136 }
2137
2138 /**
2139  *
2140  */
2141 static int ki_avp_seti(sip_msg_t *msg, str *xname, int vn)
2142 {
2143         unsigned short atype;
2144         int_str aname;
2145         int_str avalue;
2146
2147         memset(&aname, 0, sizeof(int_str));
2148
2149         atype = AVP_NAME_STR;
2150         aname.s = *xname;
2151
2152         avalue.n = vn;
2153
2154         if (add_avp(atype, aname, avalue)<0) {
2155                 LM_ERR("error - cannot add AVP\n");
2156                 return -1;
2157         }
2158
2159         return 1;
2160 }
2161
2162 /**
2163  *
2164  */
2165 static int ki_avp_sets(sip_msg_t *msg, str *xname, str *vs)
2166 {
2167         unsigned short atype;
2168         int_str aname;
2169         int_str avalue;
2170
2171         memset(&aname, 0, sizeof(int_str));
2172
2173         atype = AVP_NAME_STR;
2174         aname.s = *xname;
2175
2176         avalue.s = *vs;
2177         atype |= AVP_VAL_STR;
2178
2179         if (add_avp(atype, aname, avalue)<0) {
2180                 LM_ERR("error - cannot add AVP\n");
2181                 return -1;
2182         }
2183
2184         return 1;
2185 }
2186
2187 /**
2188  *
2189  */
2190 static int ki_avp_rm(sip_msg_t *msg, str *xname)
2191 {
2192         unsigned short atype;
2193         int_str aname;
2194
2195         memset(&aname, 0, sizeof(int_str));
2196
2197         atype = AVP_NAME_STR;
2198         aname.s = *xname;
2199
2200         destroy_avps(atype, aname, 0);
2201
2202         return 1;
2203 }
2204
2205 /**
2206  *
2207  */
2208 static int ki_avp_is_null(sip_msg_t *msg, str *xname)
2209 {
2210         unsigned short atype;
2211         int_str aname;
2212         int_str avalue;
2213         avp_search_state_t astate;
2214
2215         memset(&astate, 0, sizeof(avp_search_state_t));
2216         memset(&aname, 0, sizeof(int_str));
2217
2218         atype = AVP_NAME_STR;
2219         aname.s = *xname;
2220
2221         destroy_avps(atype, aname, 0);
2222
2223         if (search_first_avp(atype, aname, &avalue, &astate)==0) {
2224                 return 1;
2225         }
2226
2227         return -1;
2228 }
2229
2230 /**
2231  *
2232  */
2233 static sr_kemi_xval_t* ki_avp_get_mode(sip_msg_t *msg, str *xname, int rmode)
2234 {
2235         avp_t *avp = NULL;
2236         avp_search_state_t astate;
2237         unsigned short atype;
2238         int_str aname;
2239         int_str avalue;
2240
2241         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
2242         memset(&astate, 0, sizeof(avp_search_state_t));
2243         memset(&aname, 0, sizeof(int_str));
2244
2245         atype = AVP_NAME_STR;
2246         aname.s = *xname;
2247
2248         if ((avp=search_first_avp(atype, aname, &avalue, &astate))==0) {
2249                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
2250                 return &_sr_kemi_pv_xval;
2251         }
2252         if(avp->flags & AVP_VAL_STR) {
2253                 _sr_kemi_pv_xval.vtype = SR_KEMIP_STR;
2254                 _sr_kemi_pv_xval.v.s = avalue.s;
2255                 return &_sr_kemi_pv_xval;
2256         } else {
2257                 _sr_kemi_pv_xval.vtype = SR_KEMIP_INT;
2258                 _sr_kemi_pv_xval.v.n = avalue.n;
2259                 return &_sr_kemi_pv_xval;
2260         }
2261 }
2262
2263 /**
2264  *
2265  */
2266 static sr_kemi_xval_t* ki_avp_get(sip_msg_t *msg, str *xname)
2267 {
2268         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_NONE);
2269 }
2270
2271 /**
2272  *
2273  */
2274 static sr_kemi_xval_t* ki_avp_gete(sip_msg_t *msg, str *xname)
2275 {
2276         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_EMPTY);
2277 }
2278
2279 /**
2280  *
2281  */
2282 static sr_kemi_xval_t* ki_avp_getw(sip_msg_t *msg, str *xname)
2283 {
2284         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_PRINT);
2285 }
2286
2287 /**
2288  *
2289  */
2290 /* clang-format off */
2291 static sr_kemi_t sr_kemi_pvx_exports[] = {
2292         { str_init("pvx"), str_init("sbranch_set_ruri"),
2293                 SR_KEMIP_INT, ki_sbranch_set_ruri,
2294                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2295                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2296         },
2297         { str_init("pvx"), str_init("sbranch_append"),
2298                 SR_KEMIP_INT, ki_sbranch_append,
2299                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2300                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2301         },
2302         { str_init("pvx"), str_init("sbranch_reset"),
2303                 SR_KEMIP_INT, ki_sbranch_reset,
2304                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2305                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2306         },
2307         { str_init("pvx"), str_init("var_seti"),
2308                 SR_KEMIP_INT, ki_var_seti,
2309                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2310                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2311         },
2312         { str_init("pvx"), str_init("var_sets"),
2313                 SR_KEMIP_INT, ki_var_sets,
2314                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2315                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2316         },
2317         { str_init("pvx"), str_init("var_get"),
2318                 SR_KEMIP_XVAL, ki_var_get,
2319                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2320                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2321         },
2322         { str_init("pvx"), str_init("shv_seti"),
2323                 SR_KEMIP_INT, ki_shv_seti,
2324                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2325                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2326         },
2327         { str_init("pvx"), str_init("shv_sets"),
2328                 SR_KEMIP_INT, ki_shv_sets,
2329                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2330                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2331         },
2332         { str_init("pvx"), str_init("shv_get"),
2333                 SR_KEMIP_XVAL, ki_shv_get,
2334                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2335                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2336         },
2337         { str_init("pvx"), str_init("pv_var_to_xavp"),
2338                 SR_KEMIP_INT, ki_var_to_xavp,
2339                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2340                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2341         },
2342         { str_init("pvx"), str_init("pv_xavp_to_var"),
2343                 SR_KEMIP_INT, ki_xavp_to_var,
2344                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2345                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2346         },
2347         { str_init("pvx"), str_init("pv_xavp_print"),
2348                 SR_KEMIP_INT, ki_xavp_print,
2349                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2350                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2351         },
2352         { str_init("pvx"), str_init("pv_xavu_print"),
2353                 SR_KEMIP_INT, ki_xavu_print,
2354                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2355                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2356         },
2357         { str_init("pvx"), str_init("xavp_params_explode"),
2358                 SR_KEMIP_INT, ki_xavp_params_explode,
2359                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2360                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2361         },
2362         { str_init("pvx"), str_init("xavp_params_implode"),
2363                 SR_KEMIP_INT, ki_xavp_params_implode,
2364                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2365                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2366         },
2367         { str_init("pvx"), str_init("xavp_seti"),
2368                 SR_KEMIP_INT, ki_xavp_seti,
2369                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2370                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2371         },
2372         { str_init("pvx"), str_init("xavp_sets"),
2373                 SR_KEMIP_INT, ki_xavp_sets,
2374                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2375                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2376         },
2377         { str_init("pvx"), str_init("xavp_get"),
2378                 SR_KEMIP_XVAL, ki_xavp_get,
2379                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2380                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2381         },
2382         { str_init("pvx"), str_init("xavp_gete"),
2383                 SR_KEMIP_XVAL, ki_xavp_gete,
2384                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2385                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2386         },
2387         { str_init("pvx"), str_init("xavp_getw"),
2388                 SR_KEMIP_XVAL, ki_xavp_getw,
2389                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2390                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2391         },
2392         { str_init("pvx"), str_init("xavp_getd"),
2393                 SR_KEMIP_XVAL, ki_xavp_getd,
2394                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2395                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2396         },
2397         { str_init("pvx"), str_init("xavp_getd_p1"),
2398                 SR_KEMIP_XVAL, ki_xavp_getd_p1,
2399                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2400                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2401         },
2402         { str_init("pvx"), str_init("xavp_get_keys"),
2403                 SR_KEMIP_XVAL, ki_xavp_get_keys,
2404                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2405                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2406         },
2407         { str_init("pvx"), str_init("xavp_rm"),
2408                 SR_KEMIP_INT, ki_xavp_rm,
2409                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2410                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2411         },
2412         { str_init("pvx"), str_init("xavp_is_null"),
2413                 SR_KEMIP_INT, ki_xavp_is_null,
2414                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2415                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2416         },
2417         { str_init("pvx"), str_init("xavp_child_seti"),
2418                 SR_KEMIP_INT, ki_xavp_child_seti,
2419                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT,
2420                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2421         },
2422         { str_init("pvx"), str_init("xavp_child_sets"),
2423                 SR_KEMIP_INT, ki_xavp_child_sets,
2424                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2425                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2426         },
2427         { str_init("pvx"), str_init("xavp_child_rm"),
2428                 SR_KEMIP_INT, ki_xavp_child_rm,
2429                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2430                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2431         },
2432         { str_init("pvx"), str_init("xavp_child_is_null"),
2433                 SR_KEMIP_INT, ki_xavp_child_is_null,
2434                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2435                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2436         },
2437         { str_init("pvx"), str_init("xavp_child_get"),
2438                 SR_KEMIP_XVAL, ki_xavp_child_get,
2439                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2440                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2441         },
2442         { str_init("pvx"), str_init("xavp_child_gete"),
2443                 SR_KEMIP_XVAL, ki_xavp_child_gete,
2444                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2445                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2446         },
2447         { str_init("pvx"), str_init("xavp_child_getw"),
2448                 SR_KEMIP_XVAL, ki_xavp_child_getw,
2449                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2450                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2451         },
2452         { str_init("pvx"), str_init("xavu_seti"),
2453                 SR_KEMIP_INT, ki_xavu_seti,
2454                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2455                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2456         },
2457         { str_init("pvx"), str_init("xavu_sets"),
2458                 SR_KEMIP_INT, ki_xavu_sets,
2459                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2460                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2461         },
2462         { str_init("pvx"), str_init("xavu_get"),
2463                 SR_KEMIP_XVAL, ki_xavu_get,
2464                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2465                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2466         },
2467         { str_init("pvx"), str_init("xavu_gete"),
2468                 SR_KEMIP_XVAL, ki_xavu_gete,
2469                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2470                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2471         },
2472         { str_init("pvx"), str_init("xavu_getw"),
2473                 SR_KEMIP_XVAL, ki_xavu_getw,
2474                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2475                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2476         },
2477         { str_init("pvx"), str_init("xavu_rm"),
2478                 SR_KEMIP_INT, ki_xavu_rm,
2479                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2480                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2481         },
2482         { str_init("pvx"), str_init("xavu_is_null"),
2483                 SR_KEMIP_INT, ki_xavu_is_null,
2484                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2485                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2486         },
2487         { str_init("pvx"), str_init("xavu_child_seti"),
2488                 SR_KEMIP_INT, ki_xavu_child_seti,
2489                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT,
2490                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2491         },
2492         { str_init("pvx"), str_init("xavu_child_sets"),
2493                 SR_KEMIP_INT, ki_xavu_child_sets,
2494                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2495                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2496         },
2497         { str_init("pvx"), str_init("xavu_child_rm"),
2498                 SR_KEMIP_INT, ki_xavu_child_rm,
2499                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2500                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2501         },
2502         { str_init("pvx"), str_init("xavu_child_is_null"),
2503                 SR_KEMIP_INT, ki_xavu_child_is_null,
2504                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2505                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2506         },
2507         { str_init("pvx"), str_init("xavu_child_get"),
2508                 SR_KEMIP_XVAL, ki_xavu_child_get,
2509                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2510                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2511         },
2512         { str_init("pvx"), str_init("xavu_child_gete"),
2513                 SR_KEMIP_XVAL, ki_xavu_child_gete,
2514                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2515                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2516         },
2517         { str_init("pvx"), str_init("xavu_child_getw"),
2518                 SR_KEMIP_XVAL, ki_xavu_child_getw,
2519                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2520                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2521         },
2522         { str_init("pvx"), str_init("evalx"),
2523                 SR_KEMIP_INT, ki_pv_evalx,
2524                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2525                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2526         },
2527         { str_init("pvx"), str_init("avp_seti"),
2528                 SR_KEMIP_INT, ki_avp_seti,
2529                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2530                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2531         },
2532         { str_init("pvx"), str_init("avp_sets"),
2533                 SR_KEMIP_INT, ki_avp_sets,
2534                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2535                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2536         },
2537         { str_init("pvx"), str_init("avp_get"),
2538                 SR_KEMIP_XVAL, ki_avp_get,
2539                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2540                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2541         },
2542         { str_init("pvx"), str_init("avp_gete"),
2543                 SR_KEMIP_XVAL, ki_avp_gete,
2544                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2545                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2546         },
2547         { str_init("pvx"), str_init("avp_getw"),
2548                 SR_KEMIP_XVAL, ki_avp_getw,
2549                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2550                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2551         },
2552         { str_init("pvx"), str_init("avp_rm"),
2553                 SR_KEMIP_INT, ki_avp_rm,
2554                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2555                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2556         },
2557         { str_init("pvx"), str_init("avp_is_null"),
2558                 SR_KEMIP_INT, ki_avp_is_null,
2559                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2560                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2561         },
2562         { str_init("pvx"), str_init("xavp_copy"),
2563                 SR_KEMIP_INT, ki_xavp_copy,
2564                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR,
2565                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2566         },
2567         { str_init("pvx"), str_init("xavp_copy_dst"),
2568                 SR_KEMIP_INT, ki_xavp_copy_dst,
2569                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR,
2570                         SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE }
2571         },
2572
2573         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2574 };
2575 /* clang-format on */
2576
2577 /**
2578  *
2579  */
2580 static const char* rpc_shv_set_doc[2] = {
2581         "Set a shared variable (args: name type value)",
2582         0
2583 };
2584
2585 static const char* rpc_shv_get_doc[2] = {
2586         "Get the value of a shared variable. If no argument, dumps all",
2587         0
2588 };
2589
2590 rpc_export_t pv_rpc[] = {
2591         {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
2592         {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
2593         {0, 0, 0, 0}
2594 };
2595
2596 static int pv_init_rpc(void)
2597 {
2598         if (rpc_register_array(pv_rpc)!=0)
2599         {
2600                 LM_ERR("failed to register RPC commands\n");
2601                 return -1;
2602         }
2603         return 0;
2604 }
2605
2606 /**
2607  *
2608  */
2609 int mod_register(char *path, int *dlflags, void *p1, void *p2)
2610 {
2611         sr_kemi_modules_add(sr_kemi_pvx_exports);
2612         if(tr_init_buffers()<0)
2613         {
2614                 LM_ERR("failed to initialize transformations buffers\n");
2615                 return -1;
2616         }
2617         return register_trans_mod(path, mod_trans);
2618 }