pv: format new xavp functions declaration lines to be matched by kemi docs tool
[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 /**
1398  *
1399  */
1400 sr_kemi_dict_item_t* ki_xavp_dict(sr_xavp_t *xavp);
1401
1402 /**
1403  * SR_KEMIP_ARRAY with values of xavp=>name
1404  */
1405 sr_kemi_dict_item_t* ki_xavp_dict_name(sr_xavp_t *xavp, str name)
1406 {
1407         sr_kemi_dict_item_t *ini = NULL;
1408         sr_kemi_dict_item_t *val;
1409         sr_kemi_dict_item_t *last = NULL;
1410         sr_xavp_t *avp = xavp;
1411
1412         ini = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1413         if(ini==NULL) {
1414                 PKG_MEM_ERROR;
1415                 return NULL;
1416         }
1417         memset(ini, 0, sizeof(sr_kemi_xval_t));
1418         ini->vtype = SR_KEMIP_ARRAY;
1419         while(avp!=NULL&&!STR_EQ(avp->name,name))
1420         {
1421                 avp = avp->next;
1422         }
1423
1424         while(avp!=NULL){
1425                 switch(avp->val.type) {
1426                         case SR_XTYPE_XAVP:
1427                         break;
1428                         default:
1429                                 val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1430                                 if(val==NULL) {
1431                                         PKG_MEM_ERROR;
1432                                         goto error;
1433                                 }
1434                                 memset(val, 0, sizeof(sr_kemi_xval_t));
1435                         break;
1436                 }
1437                 switch(avp->val.type) {
1438                         case SR_XTYPE_NULL:
1439                                 val->vtype = SR_KEMIP_NULL;
1440                         break;
1441                         case SR_XTYPE_INT:
1442                                 val->vtype = SR_KEMIP_INT;
1443                                 val->v.n = avp->val.v.i;
1444                         break;
1445                         case SR_XTYPE_STR:
1446                                 val->vtype = SR_KEMIP_STR;
1447                                 val->v.s.s = avp->val.v.s.s;
1448                                 val->v.s.len = avp->val.v.s.len;
1449                         break;
1450                         case SR_XTYPE_TIME:
1451                         case SR_XTYPE_LONG:
1452                         case SR_XTYPE_LLONG:
1453                         case SR_XTYPE_DATA:
1454                                 val->vtype = SR_KEMIP_NULL;
1455                                 LM_WARN("XAVP type:%d value not supported\n", avp->val.type);
1456                         break;
1457                         case SR_XTYPE_XAVP:
1458                                 val = ki_xavp_dict(avp->val.v.xavp);
1459                         break;
1460                         default:
1461                                 val->vtype = SR_KEMIP_NULL;
1462                                 LM_ERR("xavp:%.*s unknown type: %d\n",
1463                                         avp->name.len, avp->name.s, avp->val.type);
1464                         break;
1465                 }
1466                 if(last) {
1467                         last->next = val;
1468                 } else {
1469                         ini->v.dict = val;
1470                         last = val;
1471                 }
1472                 avp = xavp_get_next(avp);
1473         }
1474         return ini;
1475 error:
1476         while(ini) {
1477                 last = ini;
1478                 ini = ini->next;
1479                 pkg_free(last);
1480         }
1481         return NULL;
1482 }
1483
1484 /**
1485  * SR_KEMIP_DICT of xavp
1486  */
1487 sr_kemi_dict_item_t* ki_xavp_dict(sr_xavp_t *xavp)
1488 {
1489         sr_xavp_t *avp = NULL;
1490         struct str_list *keys;
1491         struct str_list *k;
1492         sr_kemi_dict_item_t *val;
1493         sr_kemi_dict_item_t *ini = NULL;
1494         sr_kemi_dict_item_t *last = NULL;
1495
1496         if(xavp->val.type!=SR_XTYPE_XAVP) {
1497                 LM_ERR("%s not xavp?\n", xavp->name.s);
1498                 return NULL;
1499         }
1500         avp = xavp->val.v.xavp;
1501         if((keys = xavp_get_list_key_names(xavp)) != NULL) {
1502                 do {
1503                         val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1504                         if(val==NULL) {
1505                                 PKG_MEM_ERROR;
1506                                 goto error;
1507                         }
1508                         memset(val, 0, sizeof(sr_kemi_xval_t));
1509                         val->vtype = SR_KEMIP_DICT;
1510                         val->name.s = keys->s.s;
1511                         val->name.len = keys->s.len;
1512                         val->v.dict = ki_xavp_dict_name(avp, keys->s);
1513                         if(last) {
1514                                 last->next = val;
1515                         } else {
1516                                 ini = val;
1517                                 last = ini;
1518                         }
1519                         k = keys;
1520                         keys = keys->next;
1521                         pkg_free(k);
1522                 } while(keys!=NULL);
1523         }
1524         return ini;
1525 error:
1526         while(keys!=NULL) {
1527                 k = keys;
1528                 keys = keys->next;
1529                 pkg_free(k);
1530         }
1531         while(ini) {
1532                 val = ini;
1533                 ini = ini->next;
1534                 pkg_free(val);
1535         }
1536         return NULL;
1537 }
1538
1539 /**
1540  *
1541  */
1542 static sr_kemi_xval_t* ki_xavp_getd_helper(sip_msg_t *msg, str *rname, int *_indx)
1543 {
1544         sr_xavp_t *xavp=NULL;
1545         int xavp_size = 0;
1546         int indx = 0;
1547         sr_kemi_dict_item_t *val;
1548         sr_kemi_dict_item_t *last = NULL;
1549
1550         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1551         if(_indx) {
1552                 indx = *_indx;
1553                 /* we're going to retrive just one */
1554                 _sr_kemi_pv_xval.vtype = SR_KEMIP_DICT;
1555         } else {
1556                 /* we're going to retrive all */
1557                 _sr_kemi_pv_xval.vtype = SR_KEMIP_ARRAY;
1558         }
1559         xavp_size = xavp_count(rname, NULL);
1560         if(indx<0)
1561         {
1562                 if((indx*-1)>xavp_size)
1563                 {
1564                         sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1565                         return &_sr_kemi_pv_xval;
1566                 }
1567                 indx = xavp_size + indx;
1568         }
1569
1570         xavp = xavp_get_by_index(rname, indx, NULL);
1571         if(xavp==NULL) {
1572                 sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1573                 return &_sr_kemi_pv_xval;
1574         }
1575         do {
1576                 val = ki_xavp_dict(xavp);
1577                 if(last) {
1578                         last->next = val;
1579                 } else {
1580                         _sr_kemi_pv_xval.v.dict = val;
1581                 }
1582                 if(val) last = val;
1583                 if(_indx) {
1584                         xavp = NULL;
1585                 } else {
1586                         indx = indx + 1;
1587                         xavp = xavp_get_by_index(rname, indx, NULL);
1588                 }
1589         } while(xavp!=NULL);
1590         return &_sr_kemi_pv_xval;
1591 }
1592
1593 /**
1594  *
1595  */
1596 static sr_kemi_xval_t* ki_xavp_getd(sip_msg_t *msg, str *rname)
1597 {
1598         return ki_xavp_getd_helper(msg, rname, NULL);
1599 }
1600
1601 /**
1602  *
1603  */
1604 static sr_kemi_xval_t* ki_xavp_getd_p1(sip_msg_t *msg, str *rname, int indx)
1605 {
1606         return ki_xavp_getd_helper(msg, rname, &indx);
1607 }
1608
1609 /**
1610  *
1611  */
1612 static sr_kemi_xval_t* ki_xavp_get_keys(sip_msg_t *msg, str *rname, int indx)
1613 {
1614         sr_xavp_t *xavp=NULL;
1615         struct str_list *keys, *k;
1616         sr_kemi_dict_item_t *val;
1617         sr_kemi_dict_item_t *last = NULL;
1618
1619         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1620
1621         xavp = xavp_get_by_index(rname, indx, NULL);
1622         if(xavp==NULL) {
1623                 sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1624                 return &_sr_kemi_pv_xval;
1625         }
1626         keys = xavp_get_list_key_names(xavp);
1627         _sr_kemi_pv_xval.vtype = SR_KEMIP_ARRAY;
1628         while(keys!=NULL){
1629                 k = keys;
1630                 val = (sr_kemi_dict_item_t*)pkg_malloc(sizeof(sr_kemi_dict_item_t));
1631                 if(val==NULL) {
1632                         PKG_MEM_ERROR;
1633                         goto error;
1634                 }
1635                 memset(val, 0, sizeof(sr_kemi_xval_t));
1636                 val->vtype = SR_KEMIP_STR;
1637                 val->v.s.len = k->s.len;
1638                 val->v.s.s = k->s.s;
1639                 keys = k->next;
1640                 pkg_free(k);
1641                 if(last) {
1642                         last->next = val;
1643                 } else {
1644                         _sr_kemi_pv_xval.v.dict = val;
1645                 }
1646                 last = val;
1647         }
1648         return &_sr_kemi_pv_xval;
1649 error:
1650         while(keys!=NULL) {
1651                 k = keys;
1652                 keys = keys->next;
1653                 pkg_free(k);
1654         }
1655         last = _sr_kemi_pv_xval.v.dict;
1656         while(last) {
1657                 val = last;
1658                 last = last->next;
1659                 pkg_free(val);
1660         }
1661         sr_kemi_xval_null(&_sr_kemi_pv_xval, SR_KEMI_XVAL_NULL_NONE);
1662         return &_sr_kemi_pv_xval;
1663 }
1664
1665 /**
1666  *
1667  */
1668 static int ki_xavp_child_is_null(sip_msg_t *msg, str *rname, str *cname)
1669 {
1670         sr_xavp_t *xavp=NULL;
1671
1672         xavp = xavp_get_by_index(rname, 0, NULL);
1673         if(xavp==NULL) {
1674                 return 1;
1675         }
1676         if(xavp->val.type != SR_XTYPE_XAVP) {
1677                 return 1;
1678         }
1679         xavp = xavp_get_by_index(cname, 0, &xavp->val.v.xavp);
1680         if(xavp==NULL) {
1681                 return 1;
1682         }
1683         if(xavp->val.type == SR_XTYPE_NULL) {
1684                 return 1;
1685         }
1686         return -1;
1687 }
1688
1689 /**
1690  *
1691  */
1692 static sr_kemi_xval_t* ki_xavp_child_get_mode(sip_msg_t *msg, str *rname,
1693                 str *cname, int rmode)
1694 {
1695         sr_xavp_t *xavp=NULL;
1696
1697         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1698
1699         xavp = xavp_get_by_index(rname, 0, NULL);
1700         if(xavp==NULL) {
1701                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1702                 return &_sr_kemi_pv_xval;
1703         }
1704
1705         if(xavp->val.type != SR_XTYPE_XAVP) {
1706                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1707                 return &_sr_kemi_pv_xval;
1708         }
1709
1710         xavp = xavp_get_by_index(cname, 0, &xavp->val.v.xavp);
1711         if(xavp==NULL) {
1712                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1713                 return &_sr_kemi_pv_xval;
1714         }
1715
1716         return ki_xavp_get_xval(xavp, rmode);
1717 }
1718
1719 /**
1720  *
1721  */
1722 static sr_kemi_xval_t* ki_xavp_child_get(sip_msg_t *msg, str *rname, str *cname)
1723 {
1724         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_NONE);
1725 }
1726
1727
1728 /**
1729  *
1730  */
1731 static sr_kemi_xval_t* ki_xavp_child_gete(sip_msg_t *msg, str *rname, str *cname)
1732 {
1733         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_EMPTY);
1734 }
1735
1736
1737 /**
1738  *
1739  */
1740 static sr_kemi_xval_t* ki_xavp_child_getw(sip_msg_t *msg, str *rname, str *cname)
1741 {
1742         return ki_xavp_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_PRINT);
1743 }
1744
1745 /**
1746  *
1747  */
1748 static int ki_xavu_is_null(sip_msg_t *msg, str *rname)
1749 {
1750         sr_xavp_t *xavu=NULL;
1751
1752         xavu = xavu_lookup(rname, NULL);
1753         if(xavu==NULL) {
1754                 return 1;
1755         }
1756         if(xavu->val.type == SR_XTYPE_NULL) {
1757                 return 1;
1758         }
1759         return -1;
1760 }
1761
1762 /**
1763  *
1764  */
1765 static int ki_xavu_rm(sip_msg_t *msg, str *rname)
1766 {
1767         int ret;
1768
1769         ret = xavu_rm_by_name(rname, NULL);
1770
1771         return (ret==0)?1:ret;
1772 }
1773
1774 /**
1775  *
1776  */
1777 static int ki_xavu_child_rm(sip_msg_t *msg, str *rname, str *cname)
1778 {
1779         int ret;
1780
1781         ret = xavu_rm_child_by_name(rname, cname);
1782
1783         return (ret==0)?1:ret;
1784 }
1785
1786 /**
1787  *
1788  */
1789 static int ki_xavu_seti(sip_msg_t *msg, str *rname, int ival)
1790 {
1791         sr_xavp_t *xavp = NULL;
1792
1793         xavp = xavu_set_ival(rname, ival);
1794
1795         return (xavp!=NULL)?1:-1;
1796 }
1797
1798 /**
1799  *
1800  */
1801 static int ki_xavu_sets(sip_msg_t *msg, str *rname, str *sval)
1802 {
1803         sr_xavp_t *xavp = NULL;
1804
1805         xavp = xavu_set_sval(rname, sval);
1806
1807         return (xavp!=NULL)?1:-1;
1808 }
1809
1810 /**
1811  *
1812  */
1813 static int ki_xavu_child_seti(sip_msg_t *msg, str *rname, str *cname,
1814                 int ival)
1815 {
1816         sr_xavp_t *xavu = NULL;
1817
1818         xavu = xavu_set_child_ival(rname, cname, ival);
1819
1820         return (xavu!=NULL)?1:-1;
1821 }
1822
1823 /**
1824  *
1825  */
1826 static int ki_xavu_child_sets(sip_msg_t *msg, str *rname, str *cname,
1827                 str *sval)
1828 {
1829         sr_xavp_t *xavu = NULL;
1830
1831         xavu = xavu_set_child_sval(rname, cname, sval);
1832
1833         return (xavu!=NULL)?1:-1;
1834 }
1835
1836 /**
1837  *
1838  */
1839 static sr_kemi_xval_t* ki_xavu_get_mode(sip_msg_t *msg, str *rname, int rmode)
1840 {
1841         sr_xavp_t *xavu=NULL;
1842
1843         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1844
1845         xavu = xavu_lookup(rname, NULL);
1846         if(xavu==NULL) {
1847                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1848                 return &_sr_kemi_pv_xval;
1849         }
1850
1851         return ki_xavp_get_xval(xavu, rmode);
1852 }
1853
1854 /**
1855  *
1856  */
1857 static sr_kemi_xval_t* ki_xavu_get(sip_msg_t *msg, str *rname)
1858 {
1859         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_NONE);
1860 }
1861
1862 /**
1863  *
1864  */
1865 static sr_kemi_xval_t* ki_xavu_gete(sip_msg_t *msg, str *rname)
1866 {
1867         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_EMPTY);
1868 }
1869
1870 /**
1871  *
1872  */
1873 static sr_kemi_xval_t* ki_xavu_getw(sip_msg_t *msg, str *rname)
1874 {
1875         return ki_xavu_get_mode(msg, rname, SR_KEMI_XVAL_NULL_PRINT);
1876 }
1877
1878 /**
1879  *
1880  */
1881 static int ki_xavu_child_is_null(sip_msg_t *msg, str *rname, str *cname)
1882 {
1883         sr_xavp_t *xavu=NULL;
1884
1885         xavu = xavp_get_by_index(rname, 0, NULL);
1886         if(xavu==NULL) {
1887                 return 1;
1888         }
1889         if(xavu->val.type != SR_XTYPE_XAVP) {
1890                 return 1;
1891         }
1892         xavu = xavp_get_by_index(cname, 0, &xavu->val.v.xavp);
1893         if(xavu==NULL) {
1894                 return 1;
1895         }
1896         if(xavu->val.type == SR_XTYPE_NULL) {
1897                 return 1;
1898         }
1899         return -1;
1900 }
1901
1902 /**
1903  *
1904  */
1905 static sr_kemi_xval_t* ki_xavu_child_get_mode(sip_msg_t *msg, str *rname,
1906                 str *cname, int rmode)
1907 {
1908         sr_xavp_t *xavu=NULL;
1909
1910         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
1911
1912         xavu = xavu_lookup(rname, NULL);
1913         if(xavu==NULL) {
1914                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1915                 return &_sr_kemi_pv_xval;
1916         }
1917
1918         if(xavu->val.type != SR_XTYPE_XAVP) {
1919                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1920                 return &_sr_kemi_pv_xval;
1921         }
1922
1923         xavu = xavp_get_by_index(cname, 0, &xavu->val.v.xavp);
1924         if(xavu==NULL) {
1925                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
1926                 return &_sr_kemi_pv_xval;
1927         }
1928
1929         return ki_xavp_get_xval(xavu, rmode);
1930 }
1931
1932 /**
1933  *
1934  */
1935 static sr_kemi_xval_t* ki_xavu_child_get(sip_msg_t *msg, str *rname, str *cname)
1936 {
1937         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_NONE);
1938 }
1939
1940
1941 /**
1942  *
1943  */
1944 static sr_kemi_xval_t* ki_xavu_child_gete(sip_msg_t *msg, str *rname, str *cname)
1945 {
1946         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_EMPTY);
1947 }
1948
1949
1950 /**
1951  *
1952  */
1953 static sr_kemi_xval_t* ki_xavu_child_getw(sip_msg_t *msg, str *rname, str *cname)
1954 {
1955         return ki_xavu_child_get_mode(msg, rname, cname, SR_KEMI_XVAL_NULL_PRINT);
1956 }
1957
1958 /**
1959  *
1960  */
1961 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2)
1962 {
1963         if(sbranch_set_ruri(msg)<0)
1964                 return -1;
1965         return 1;
1966 }
1967
1968 /**
1969  *
1970  */
1971 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2)
1972 {
1973         if(sbranch_append(msg)<0)
1974                 return -1;
1975         return 1;
1976 }
1977
1978 /**
1979  *
1980  */
1981 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2)
1982 {
1983         if(sbranch_reset()<0)
1984                 return -1;
1985         return 1;
1986 }
1987
1988 /**
1989  *
1990  */
1991 static int ki_sbranch_set_ruri(sip_msg_t *msg)
1992 {
1993         if(sbranch_set_ruri(msg)<0)
1994                 return -1;
1995         return 1;
1996 }
1997
1998 /**
1999  *
2000  */
2001 static int ki_sbranch_append(sip_msg_t *msg)
2002 {
2003         if(sbranch_append(msg)<0)
2004                 return -1;
2005         return 1;
2006 }
2007
2008 /**
2009  *
2010  */
2011 static int ki_sbranch_reset(sip_msg_t *msg)
2012 {
2013         if(sbranch_reset()<0)
2014                 return -1;
2015         return 1;
2016 }
2017
2018 int pv_xavp_copy_fixup(void **param, int param_no)
2019 {
2020         if(param_no == 1 || param_no == 3)
2021                 return fixup_var_str_12(param, param_no);
2022         if (param_no == 2 || param_no == 4)
2023                 return fixup_var_int_12(param, param_no);
2024         LM_ERR("invalid parameter count [%d]\n", param_no);
2025         return -1;
2026 }
2027
2028 int pv_evalx_fixup(void** param, int param_no)
2029 {
2030         pv_spec_t *spec=NULL;
2031         pv_elem_t *pvmodel=NULL;
2032         str tstr;
2033
2034         if(param_no==1) {
2035                 spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
2036                 if(spec==NULL) {
2037                         LM_ERR("out of pkg\n");
2038                         return -1;
2039                 }
2040                 memset(spec, 0, sizeof(pv_spec_t));
2041                 tstr.s = (char*)(*param);
2042                 tstr.len = strlen(tstr.s);
2043                 if(pv_parse_spec(&tstr, spec)==NULL) {
2044                         LM_ERR("unknown script variable in first parameter\n");
2045                         pkg_free(spec);
2046                         return -1;
2047                 }
2048                 if(!pv_is_w(spec)) {
2049                         LM_ERR("read-only script variable in first parameter\n");
2050                         pkg_free(spec);
2051                         return -1;
2052                 }
2053                 *param = spec;
2054         } else if(param_no==2) {
2055                 pvmodel = 0;
2056                 tstr.s = (char*)(*param);
2057                 tstr.len = strlen(tstr.s);
2058                 if(pv_parse_format(&tstr, &pvmodel)<0) {
2059                         LM_ERR("error in second parameter\n");
2060                         return -1;
2061                 }
2062                 *param = pvmodel;
2063         }
2064         return 0;
2065 }
2066
2067 /**
2068  *
2069  */
2070 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt)
2071 {
2072         pv_spec_t *ispec=NULL;
2073         pv_elem_t *imodel=NULL;
2074         str tstr = {0, 0};
2075         pv_value_t val;
2076
2077         ispec = (pv_spec_t*)dst;
2078
2079         imodel = (pv_elem_t*)fmt;
2080
2081         memset(&val, 0, sizeof(pv_value_t));
2082
2083         if(pv_printf_s(msg, imodel, &tstr)!=0) {
2084                 LM_ERR("cannot eval second parameter\n");
2085                 goto error;
2086         }
2087
2088         LM_DBG("preparing to evaluate: [%.*s]\n", tstr.len, tstr.s);
2089         if(pv_eval_str(msg, &val.rs, &tstr)<0){
2090                 LM_ERR("cannot eval reparsed value of second parameter\n");
2091                 return -1;
2092         }
2093
2094         val.flags = PV_VAL_STR;
2095         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
2096                 LM_ERR("setting PV failed\n");
2097                 goto error;
2098         }
2099
2100         return 1;
2101 error:
2102         return -1;
2103 }
2104
2105 /**
2106  *
2107  */
2108 int ki_pv_evalx(sip_msg_t *msg, str *dst, str *fmt)
2109 {
2110         pv_value_t val;
2111         pv_spec_t *ispec=NULL;
2112
2113         if(dst==NULL || dst->s==NULL || dst->len<=0) {
2114                 LM_ERR("invalid destination var name\n");
2115                 return -1;
2116         }
2117         ispec = pv_cache_get(dst);
2118         if(ispec==NULL) {
2119                 LM_ERR("cannot get pv spec for [%.*s]\n", dst->len, dst->s);
2120                 return -1;
2121         }
2122
2123         memset(&val, 0, sizeof(pv_value_t));
2124         if(pv_eval_str(msg, &val.rs, fmt)<0) {
2125                 LM_ERR("cannot eval reparsed value of second parameter\n");
2126                 return -1;
2127         }
2128
2129         val.flags = PV_VAL_STR;
2130         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
2131                 LM_ERR("setting PV failed\n");
2132                 goto error;
2133         }
2134
2135         return 1;
2136 error:
2137         return -1;
2138 }
2139
2140 /**
2141  *
2142  */
2143 static int ki_avp_seti(sip_msg_t *msg, str *xname, int vn)
2144 {
2145         unsigned short atype;
2146         int_str aname;
2147         int_str avalue;
2148
2149         memset(&aname, 0, sizeof(int_str));
2150
2151         atype = AVP_NAME_STR;
2152         aname.s = *xname;
2153
2154         avalue.n = vn;
2155
2156         if (add_avp(atype, aname, avalue)<0) {
2157                 LM_ERR("error - cannot add AVP\n");
2158                 return -1;
2159         }
2160
2161         return 1;
2162 }
2163
2164 /**
2165  *
2166  */
2167 static int ki_avp_sets(sip_msg_t *msg, str *xname, str *vs)
2168 {
2169         unsigned short atype;
2170         int_str aname;
2171         int_str avalue;
2172
2173         memset(&aname, 0, sizeof(int_str));
2174
2175         atype = AVP_NAME_STR;
2176         aname.s = *xname;
2177
2178         avalue.s = *vs;
2179         atype |= AVP_VAL_STR;
2180
2181         if (add_avp(atype, aname, avalue)<0) {
2182                 LM_ERR("error - cannot add AVP\n");
2183                 return -1;
2184         }
2185
2186         return 1;
2187 }
2188
2189 /**
2190  *
2191  */
2192 static int ki_avp_rm(sip_msg_t *msg, str *xname)
2193 {
2194         unsigned short atype;
2195         int_str aname;
2196
2197         memset(&aname, 0, sizeof(int_str));
2198
2199         atype = AVP_NAME_STR;
2200         aname.s = *xname;
2201
2202         destroy_avps(atype, aname, 0);
2203
2204         return 1;
2205 }
2206
2207 /**
2208  *
2209  */
2210 static int ki_avp_is_null(sip_msg_t *msg, str *xname)
2211 {
2212         unsigned short atype;
2213         int_str aname;
2214         int_str avalue;
2215         avp_search_state_t astate;
2216
2217         memset(&astate, 0, sizeof(avp_search_state_t));
2218         memset(&aname, 0, sizeof(int_str));
2219
2220         atype = AVP_NAME_STR;
2221         aname.s = *xname;
2222
2223         destroy_avps(atype, aname, 0);
2224
2225         if (search_first_avp(atype, aname, &avalue, &astate)==0) {
2226                 return 1;
2227         }
2228
2229         return -1;
2230 }
2231
2232 /**
2233  *
2234  */
2235 static sr_kemi_xval_t* ki_avp_get_mode(sip_msg_t *msg, str *xname, int rmode)
2236 {
2237         avp_t *avp = NULL;
2238         avp_search_state_t astate;
2239         unsigned short atype;
2240         int_str aname;
2241         int_str avalue;
2242
2243         memset(&_sr_kemi_pv_xval, 0, sizeof(sr_kemi_xval_t));
2244         memset(&astate, 0, sizeof(avp_search_state_t));
2245         memset(&aname, 0, sizeof(int_str));
2246
2247         atype = AVP_NAME_STR;
2248         aname.s = *xname;
2249
2250         if ((avp=search_first_avp(atype, aname, &avalue, &astate))==0) {
2251                 sr_kemi_xval_null(&_sr_kemi_pv_xval, rmode);
2252                 return &_sr_kemi_pv_xval;
2253         }
2254         if(avp->flags & AVP_VAL_STR) {
2255                 _sr_kemi_pv_xval.vtype = SR_KEMIP_STR;
2256                 _sr_kemi_pv_xval.v.s = avalue.s;
2257                 return &_sr_kemi_pv_xval;
2258         } else {
2259                 _sr_kemi_pv_xval.vtype = SR_KEMIP_INT;
2260                 _sr_kemi_pv_xval.v.n = avalue.n;
2261                 return &_sr_kemi_pv_xval;
2262         }
2263 }
2264
2265 /**
2266  *
2267  */
2268 static sr_kemi_xval_t* ki_avp_get(sip_msg_t *msg, str *xname)
2269 {
2270         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_NONE);
2271 }
2272
2273 /**
2274  *
2275  */
2276 static sr_kemi_xval_t* ki_avp_gete(sip_msg_t *msg, str *xname)
2277 {
2278         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_EMPTY);
2279 }
2280
2281 /**
2282  *
2283  */
2284 static sr_kemi_xval_t* ki_avp_getw(sip_msg_t *msg, str *xname)
2285 {
2286         return ki_avp_get_mode(msg, xname, SR_KEMI_XVAL_NULL_PRINT);
2287 }
2288
2289 /**
2290  *
2291  */
2292 /* clang-format off */
2293 static sr_kemi_t sr_kemi_pvx_exports[] = {
2294         { str_init("pvx"), str_init("sbranch_set_ruri"),
2295                 SR_KEMIP_INT, ki_sbranch_set_ruri,
2296                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2297                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2298         },
2299         { str_init("pvx"), str_init("sbranch_append"),
2300                 SR_KEMIP_INT, ki_sbranch_append,
2301                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2302                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2303         },
2304         { str_init("pvx"), str_init("sbranch_reset"),
2305                 SR_KEMIP_INT, ki_sbranch_reset,
2306                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2307                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2308         },
2309         { str_init("pvx"), str_init("var_seti"),
2310                 SR_KEMIP_INT, ki_var_seti,
2311                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2312                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2313         },
2314         { str_init("pvx"), str_init("var_sets"),
2315                 SR_KEMIP_INT, ki_var_sets,
2316                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2317                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2318         },
2319         { str_init("pvx"), str_init("var_get"),
2320                 SR_KEMIP_XVAL, ki_var_get,
2321                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2322                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2323         },
2324         { str_init("pvx"), str_init("shv_seti"),
2325                 SR_KEMIP_INT, ki_shv_seti,
2326                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2327                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2328         },
2329         { str_init("pvx"), str_init("shv_sets"),
2330                 SR_KEMIP_INT, ki_shv_sets,
2331                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2332                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2333         },
2334         { str_init("pvx"), str_init("shv_get"),
2335                 SR_KEMIP_XVAL, ki_shv_get,
2336                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2337                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2338         },
2339         { str_init("pvx"), str_init("pv_var_to_xavp"),
2340                 SR_KEMIP_INT, ki_var_to_xavp,
2341                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2342                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2343         },
2344         { str_init("pvx"), str_init("pv_xavp_to_var"),
2345                 SR_KEMIP_INT, ki_xavp_to_var,
2346                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2347                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2348         },
2349         { str_init("pvx"), str_init("pv_xavp_print"),
2350                 SR_KEMIP_INT, ki_xavp_print,
2351                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2352                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2353         },
2354         { str_init("pvx"), str_init("pv_xavu_print"),
2355                 SR_KEMIP_INT, ki_xavu_print,
2356                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2357                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2358         },
2359         { str_init("pvx"), str_init("xavp_params_explode"),
2360                 SR_KEMIP_INT, ki_xavp_params_explode,
2361                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2362                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2363         },
2364         { str_init("pvx"), str_init("xavp_params_implode"),
2365                 SR_KEMIP_INT, ki_xavp_params_implode,
2366                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2367                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2368         },
2369         { str_init("pvx"), str_init("xavp_seti"),
2370                 SR_KEMIP_INT, ki_xavp_seti,
2371                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2372                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2373         },
2374         { str_init("pvx"), str_init("xavp_sets"),
2375                 SR_KEMIP_INT, ki_xavp_sets,
2376                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2377                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2378         },
2379         { str_init("pvx"), str_init("xavp_get"),
2380                 SR_KEMIP_XVAL, ki_xavp_get,
2381                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2382                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2383         },
2384         { str_init("pvx"), str_init("xavp_gete"),
2385                 SR_KEMIP_XVAL, ki_xavp_gete,
2386                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2387                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2388         },
2389         { str_init("pvx"), str_init("xavp_getw"),
2390                 SR_KEMIP_XVAL, ki_xavp_getw,
2391                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2392                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2393         },
2394         { str_init("pvx"), str_init("xavp_getd"),
2395                 SR_KEMIP_XVAL, ki_xavp_getd,
2396                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2397                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2398         },
2399         { str_init("pvx"), str_init("xavp_getd_p1"),
2400                 SR_KEMIP_XVAL, ki_xavp_getd_p1,
2401                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2402                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2403         },
2404         { str_init("pvx"), str_init("xavp_get_keys"),
2405                 SR_KEMIP_XVAL, ki_xavp_get_keys,
2406                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2407                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2408         },
2409         { str_init("pvx"), str_init("xavp_rm"),
2410                 SR_KEMIP_INT, ki_xavp_rm,
2411                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2412                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2413         },
2414         { str_init("pvx"), str_init("xavp_is_null"),
2415                 SR_KEMIP_INT, ki_xavp_is_null,
2416                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2417                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2418         },
2419         { str_init("pvx"), str_init("xavp_child_seti"),
2420                 SR_KEMIP_INT, ki_xavp_child_seti,
2421                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT,
2422                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2423         },
2424         { str_init("pvx"), str_init("xavp_child_sets"),
2425                 SR_KEMIP_INT, ki_xavp_child_sets,
2426                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2427                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2428         },
2429         { str_init("pvx"), str_init("xavp_child_rm"),
2430                 SR_KEMIP_INT, ki_xavp_child_rm,
2431                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2432                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2433         },
2434         { str_init("pvx"), str_init("xavp_child_is_null"),
2435                 SR_KEMIP_INT, ki_xavp_child_is_null,
2436                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2437                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2438         },
2439         { str_init("pvx"), str_init("xavp_child_get"),
2440                 SR_KEMIP_XVAL, ki_xavp_child_get,
2441                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2442                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2443         },
2444         { str_init("pvx"), str_init("xavp_child_gete"),
2445                 SR_KEMIP_XVAL, ki_xavp_child_gete,
2446                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2447                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2448         },
2449         { str_init("pvx"), str_init("xavp_child_getw"),
2450                 SR_KEMIP_XVAL, ki_xavp_child_getw,
2451                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2452                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2453         },
2454         { str_init("pvx"), str_init("xavu_seti"),
2455                 SR_KEMIP_INT, ki_xavu_seti,
2456                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2457                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2458         },
2459         { str_init("pvx"), str_init("xavu_sets"),
2460                 SR_KEMIP_INT, ki_xavu_sets,
2461                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2462                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2463         },
2464         { str_init("pvx"), str_init("xavu_get"),
2465                 SR_KEMIP_XVAL, ki_xavu_get,
2466                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2467                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2468         },
2469         { str_init("pvx"), str_init("xavu_gete"),
2470                 SR_KEMIP_XVAL, ki_xavu_gete,
2471                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2472                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2473         },
2474         { str_init("pvx"), str_init("xavu_getw"),
2475                 SR_KEMIP_XVAL, ki_xavu_getw,
2476                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2477                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2478         },
2479         { str_init("pvx"), str_init("xavu_rm"),
2480                 SR_KEMIP_INT, ki_xavu_rm,
2481                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2482                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2483         },
2484         { str_init("pvx"), str_init("xavu_is_null"),
2485                 SR_KEMIP_INT, ki_xavu_is_null,
2486                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2487                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2488         },
2489         { str_init("pvx"), str_init("xavu_child_seti"),
2490                 SR_KEMIP_INT, ki_xavu_child_seti,
2491                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT,
2492                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2493         },
2494         { str_init("pvx"), str_init("xavu_child_sets"),
2495                 SR_KEMIP_INT, ki_xavu_child_sets,
2496                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2497                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2498         },
2499         { str_init("pvx"), str_init("xavu_child_rm"),
2500                 SR_KEMIP_INT, ki_xavu_child_rm,
2501                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2502                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2503         },
2504         { str_init("pvx"), str_init("xavu_child_is_null"),
2505                 SR_KEMIP_INT, ki_xavu_child_is_null,
2506                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2507                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2508         },
2509         { str_init("pvx"), str_init("xavu_child_get"),
2510                 SR_KEMIP_XVAL, ki_xavu_child_get,
2511                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2512                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2513         },
2514         { str_init("pvx"), str_init("xavu_child_gete"),
2515                 SR_KEMIP_XVAL, ki_xavu_child_gete,
2516                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2517                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2518         },
2519         { str_init("pvx"), str_init("xavu_child_getw"),
2520                 SR_KEMIP_XVAL, ki_xavu_child_getw,
2521                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2522                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2523         },
2524         { str_init("pvx"), str_init("evalx"),
2525                 SR_KEMIP_INT, ki_pv_evalx,
2526                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2527                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2528         },
2529         { str_init("pvx"), str_init("avp_seti"),
2530                 SR_KEMIP_INT, ki_avp_seti,
2531                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
2532                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2533         },
2534         { str_init("pvx"), str_init("avp_sets"),
2535                 SR_KEMIP_INT, ki_avp_sets,
2536                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
2537                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2538         },
2539         { str_init("pvx"), str_init("avp_get"),
2540                 SR_KEMIP_XVAL, ki_avp_get,
2541                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2542                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2543         },
2544         { str_init("pvx"), str_init("avp_gete"),
2545                 SR_KEMIP_XVAL, ki_avp_gete,
2546                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2547                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2548         },
2549         { str_init("pvx"), str_init("avp_getw"),
2550                 SR_KEMIP_XVAL, ki_avp_getw,
2551                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2552                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2553         },
2554         { str_init("pvx"), str_init("avp_rm"),
2555                 SR_KEMIP_INT, ki_avp_rm,
2556                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2557                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2558         },
2559         { str_init("pvx"), str_init("avp_is_null"),
2560                 SR_KEMIP_INT, ki_avp_is_null,
2561                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2562                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2563         },
2564         { str_init("pvx"), str_init("xavp_copy"),
2565                 SR_KEMIP_INT, ki_xavp_copy,
2566                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR,
2567                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2568         },
2569         { str_init("pvx"), str_init("xavp_copy_dst"),
2570                 SR_KEMIP_INT, ki_xavp_copy_dst,
2571                 { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR,
2572                         SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE }
2573         },
2574
2575         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2576 };
2577 /* clang-format on */
2578
2579 /**
2580  *
2581  */
2582 static const char* rpc_shv_set_doc[2] = {
2583         "Set a shared variable (args: name type value)",
2584         0
2585 };
2586
2587 static const char* rpc_shv_get_doc[2] = {
2588         "Get the value of a shared variable. If no argument, dumps all",
2589         0
2590 };
2591
2592 rpc_export_t pv_rpc[] = {
2593         {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
2594         {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
2595         {0, 0, 0, 0}
2596 };
2597
2598 static int pv_init_rpc(void)
2599 {
2600         if (rpc_register_array(pv_rpc)!=0)
2601         {
2602                 LM_ERR("failed to register RPC commands\n");
2603                 return -1;
2604         }
2605         return 0;
2606 }
2607
2608 /**
2609  *
2610  */
2611 int mod_register(char *path, int *dlflags, void *p1, void *p2)
2612 {
2613         sr_kemi_modules_add(sr_kemi_pvx_exports);
2614         if(tr_init_buffers()<0)
2615         {
2616                 LM_ERR("failed to initialize transformations buffers\n");
2617                 return -1;
2618         }
2619         return register_trans_mod(path, mod_trans);
2620 }