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