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