pv: return false if pv_unset() fails
[sip-router] / 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 "../../sr_module.h"
26 #include "../../pvar.h"
27 #include "../../lvalue.h"
28 #include "../../mod_fix.h"
29 #include "../../lib/kmi/mi.h"
30 #include "../../rpc.h"
31 #include "../../rpc_lookup.h"
32
33
34 #include "pv_branch.h"
35 #include "pv_core.h"
36 #include "pv_stats.h"
37 #include "pv_shv.h"
38 #include "pv_time.h"
39 #include "pv_trans.h"
40 #include "pv_select.h"
41 #ifdef WITH_XAVP
42 #include "pv_xavp.h"
43 #endif
44 #include "pv_api.h"
45
46 MODULE_VERSION
47
48 static tr_export_t mod_trans[] = {
49         { {"s", sizeof("s")-1}, /* string class */
50                 tr_parse_string },
51         { {"nameaddr", sizeof("nameaddr")-1}, /* nameaddr class */
52                 tr_parse_nameaddr },
53         { {"uri", sizeof("uri")-1}, /* uri class */
54                 tr_parse_uri },
55         { {"param", sizeof("param")-1}, /* param class */
56                 tr_parse_paramlist },
57         { {"tobody", sizeof("tobody")-1}, /* param class */
58                 tr_parse_tobody },
59         { {"line", sizeof("line")-1}, /* line class */
60                 tr_parse_line },
61
62         { { 0, 0 }, 0 }
63 };
64
65 static pv_export_t mod_pvs[] = {
66         { {"_s", (sizeof("_s")-1)}, PVT_OTHER, pv_get__s, 0,
67                 pv_parse__s_name, 0, 0, 0 },
68         { {"af", (sizeof("af")-1)}, PVT_OTHER, pv_get_af, 0,
69                 pv_parse_af_name, 0, 0, 0 },
70         { {"branch", sizeof("branch")-1}, /* branch attributes */
71                 PVT_CONTEXT, pv_get_branchx, pv_set_branchx,
72                 pv_parse_branchx_name, pv_parse_index, 0, 0 },
73         { {"sbranch", sizeof("sbranch")-1}, /* static branch attributes */
74                 PVT_CONTEXT, pv_get_sbranch, pv_set_sbranch,
75                 pv_parse_branchx_name, 0, 0, 0 },
76         { {"mi", (sizeof("mi")-1)}, /* message id */
77                 PVT_OTHER, pv_get_msgid, 0,
78                 0, 0, 0, 0},
79         { {"stat", sizeof("stat")-1}, /* statistics */
80                 PVT_OTHER, pv_get_stat, 0,
81                 pv_parse_stat_name, 0, 0, 0 },
82         { {"sel", sizeof("sel")-1}, /* select */
83                 PVT_OTHER, pv_get_select, 0,
84                 pv_parse_select_name, 0, 0, 0 },
85         { {"snd", (sizeof("snd")-1)}, PVT_OTHER, pv_get_sndto, 0,
86                 pv_parse_snd_name, 0, 0, 0 },
87         { {"sndto", (sizeof("sndto")-1)}, PVT_OTHER, pv_get_sndto, 0,
88                 pv_parse_snd_name, 0, 0, 0 },
89         { {"sndfrom", (sizeof("sndfrom")-1)}, PVT_OTHER, pv_get_sndfrom, 0,
90                 pv_parse_snd_name, 0, 0, 0 },
91 #ifdef WITH_XAVP
92         { {"xavp", sizeof("xavp")-1}, /* xavp */
93                 PVT_XAVP, pv_get_xavp, pv_set_xavp,
94                 pv_parse_xavp_name, 0, 0, 0 },
95 #endif
96
97         {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp,
98                 pv_parse_avp_name, pv_parse_index, 0, 0},
99         {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name,
100                 pv_parse_index, 0, 0},
101         {{"var", (sizeof("var")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
102                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
103         {{"vz", (sizeof("vz")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
104                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
105         {{"vn", (sizeof("vn")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
106                 pv_set_scriptvar, pv_parse_scriptvarnull_name, 0, 0, 0},
107         {{"ai", (sizeof("ai")-1)}, /* */
108                 PVT_OTHER, pv_get_pai, 0,
109                 0, pv_parse_index, 0, 0},
110         {{"adu", (sizeof("adu")-1)}, /* auth digest uri */
111                 PVT_OTHER, pv_get_authattr, 0,
112                 0, 0, pv_init_iname, 3},
113         {{"ar", (sizeof("ar")-1)}, /* auth realm */
114                 PVT_OTHER, pv_get_authattr, 0,
115                 0, 0, pv_init_iname, 2},
116         {{"au", (sizeof("au")-1)}, /* */
117                 PVT_OTHER, pv_get_authattr, 0,
118                 0, 0, pv_init_iname, 1},
119         {{"ad", (sizeof("ad")-1)}, /* */
120                 PVT_OTHER, pv_get_authattr, 0,
121                 0, 0, pv_init_iname, 4},
122         {{"aU", (sizeof("aU")-1)}, /* */
123                 PVT_OTHER, pv_get_authattr, 0,
124                 0, 0, pv_init_iname, 5},
125         {{"aa", (sizeof("aa")-1)}, /* auth algorithm */
126                 PVT_OTHER, pv_get_authattr, 0,
127                 0, 0, pv_init_iname, 6},
128         {{"adn", (sizeof("adn")-1)}, /* auth nonce */
129                 PVT_OTHER, pv_get_authattr, 0,
130                 0, 0, pv_init_iname, 7},
131         {{"adc", (sizeof("adc")-1)}, /* auth cnonce */
132                 PVT_OTHER, pv_get_authattr, 0,
133                 0, 0, pv_init_iname, 8},
134         {{"adr", (sizeof("adr")-1)}, /* auth response */
135                 PVT_OTHER, pv_get_authattr, 0,
136                 0, 0, pv_init_iname, 9},
137         {{"ado", (sizeof("ado")-1)}, /* auth opaque */
138                 PVT_OTHER, pv_get_authattr, 0,
139                 0, 0, pv_init_iname, 10},
140         {{"Au", (sizeof("Au")-1)}, /* */
141                 PVT_OTHER, pv_get_acc_username, 0,
142                 0, 0, pv_init_iname, 1},
143         {{"bf", (sizeof("bf")-1)}, /* */
144                 PVT_CONTEXT, pv_get_bflags, pv_set_bflags,
145                 0, 0, 0, 0},
146         {{"bF", (sizeof("bF")-1)}, /* */
147                 PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags,
148                 0, 0, 0, 0},
149         {{"Bf", (sizeof("Bf")-1)}, /* */
150                 PVT_CONTEXT, pv_get_bflag, pv_set_bflag,
151                 pv_parse_flag_param, 0, 0, 0},
152         {{"br", (sizeof("br")-1)}, /* */
153                 PVT_BRANCH, pv_get_branch, pv_set_branch,
154                 0, 0, 0, 0},
155         {{"bR", (sizeof("bR")-1)}, /* */
156                 PVT_CONTEXT, pv_get_branches, 0,
157                 0, 0, 0, 0},
158         {{"bs", (sizeof("bs")-1)}, /* */
159                 PVT_OTHER, pv_get_body_size, 0,
160                 0, 0, 0, 0},
161         {{"ci", (sizeof("ci")-1)}, /* */
162                 PVT_OTHER, pv_get_callid, 0,
163                 0, 0, 0, 0},
164         {{"cl", (sizeof("cl")-1)}, /* */
165                 PVT_OTHER, pv_get_content_length, 0,
166                 0, 0, 0, 0},
167         {{"cnt", sizeof("cnt")-1},
168                 PVT_OTHER, pv_get_cnt, 0,
169                 pv_parse_cnt_name, 0, 0, 0 },
170         {{"conid", (sizeof("conid")-1)}, /* */
171                 PVT_OTHER, pv_get_tcpconn_id, 0,
172                 0, 0, 0, 0},
173         {{"cs", (sizeof("cs")-1)}, /* */
174                 PVT_OTHER, pv_get_cseq, 0,
175                 0, 0, 0, 0},
176         {{"ct", (sizeof("ct")-1)}, /* */
177                 PVT_OTHER, pv_get_contact, 0,
178                 0, 0, 0, 0},
179         {{"cT", (sizeof("cT")-1)}, /* */
180                 PVT_OTHER, pv_get_content_type, 0,
181                 0, 0, 0, 0},
182         {{"dd", (sizeof("dd")-1)}, /* */
183                 PVT_OTHER, pv_get_dsturi_attr, 0,
184                 0, 0, pv_init_iname, 1},
185         {{"di", (sizeof("di")-1)}, /* */
186                 PVT_OTHER, pv_get_diversion, 0,
187                 0, 0, pv_init_iname, 1},
188         {{"dir", (sizeof("dir")-1)}, /* */
189                 PVT_OTHER, pv_get_diversion, 0,
190                 0, 0, pv_init_iname, 2},
191         {{"dip", (sizeof("dis")-1)}, /* */
192                 PVT_OTHER, pv_get_diversion, 0,
193                 0, 0, pv_init_iname, 3},
194         {{"dic", (sizeof("dic")-1)}, /* */
195                 PVT_OTHER, pv_get_diversion, 0,
196                 0, 0, pv_init_iname, 4},
197         {{"dp", (sizeof("dp")-1)}, /* */
198                 PVT_OTHER, pv_get_dsturi_attr, 0,
199                 0, 0, pv_init_iname, 2},
200         {{"dP", (sizeof("dP")-1)}, /* */
201                 PVT_OTHER, pv_get_dsturi_attr, 0,
202                 0, 0, pv_init_iname, 3},
203         {{"ds", (sizeof("ds")-1)}, /* */
204                 PVT_CONTEXT, pv_get_dset, 0,
205                 0, 0, 0, 0},
206         {{"du", (sizeof("du")-1)}, /* */
207                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
208                 0, 0, 0, 0},
209         {{"duri", (sizeof("duri")-1)}, /* */
210                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
211                 0, 0, 0, 0},
212         {{"err.class", (sizeof("err.class")-1)}, /* */
213                 PVT_OTHER, pv_get_errinfo_attr, 0,
214                 0, 0, 0, 0},
215         {{"err.level", (sizeof("err.level")-1)}, /* */
216                 PVT_OTHER, pv_get_errinfo_attr, 0,
217                 0, 0, pv_init_iname, 1},
218         {{"err.info", (sizeof("err.info")-1)}, /* */
219                 PVT_OTHER, pv_get_errinfo_attr, 0,
220                 0, 0, pv_init_iname, 2},
221         {{"err.rcode", (sizeof("err.rcode")-1)}, /* */
222                 PVT_OTHER, pv_get_errinfo_attr, 0,
223                 0, 0, pv_init_iname, 3},
224         {{"err.rreason", (sizeof("err.rreason")-1)}, /* */
225                 PVT_OTHER, pv_get_errinfo_attr, 0,
226                 0, 0, pv_init_iname, 4},
227         {{"fd", (sizeof("fd")-1)}, /* */
228                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
229                 0, 0, pv_init_iname, 3},
230         {{"from.domain", (sizeof("from.domain")-1)}, /* */
231                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
232                 0, 0, pv_init_iname, 3},
233         {{"fn", (sizeof("fn")-1)}, /* */
234                 PVT_OTHER, pv_get_from_attr, pv_set_from_display,
235                 0, 0, pv_init_iname, 5},
236         {{"fs", (sizeof("fs")-1)}, /* */
237                 PVT_OTHER, pv_get_force_sock, pv_set_force_sock,
238                 0, 0, 0, 0},
239         {{"ft", (sizeof("ft")-1)}, /* */
240                 PVT_OTHER, pv_get_from_attr, 0,
241                 0, 0, pv_init_iname, 4},
242         {{"fu", (sizeof("fu")-1)}, /* */
243                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
244                 0, 0, pv_init_iname, 1},
245         {{"from", (sizeof("from")-1)}, /* */
246                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
247                 0, 0, pv_init_iname, 1},
248         {{"fU", (sizeof("fU")-1)}, /* */
249                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
250                 0, 0, pv_init_iname, 2},
251         {{"from.user", (sizeof("from.user")-1)}, /* */
252                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
253                 0, 0, pv_init_iname, 2},
254         {{"mb", (sizeof("mb")-1)}, /* */
255                 PVT_OTHER, pv_get_msg_buf, 0,
256                 0, 0, 0, 0},
257         {{"mf", (sizeof("mf")-1)}, /* */
258                 PVT_OTHER, pv_get_flags, pv_set_mflags,
259                 0, 0, 0, 0},
260         {{"mF", (sizeof("mF")-1)}, /* */
261                 PVT_OTHER, pv_get_hexflags, pv_set_mflags,
262                 0, 0, 0, 0},
263         {{"Mf", (sizeof("mf")-1)}, /* */
264                 PVT_OTHER, pv_get_flag, pv_set_mflag,
265                 pv_parse_flag_param, 0, 0, 0},
266         {{"ml", (sizeof("ml")-1)}, /* */
267                 PVT_OTHER, pv_get_msg_len, 0,
268                 0, 0, 0, 0},
269         {{"mt", (sizeof("mt")-1)}, /* */
270                 PVT_OTHER, pv_get_msgtype, 0,
271                 0, 0, 0, 0},
272         {{"od", (sizeof("od")-1)}, /* */
273                 PVT_OTHER, pv_get_ouri_attr, 0,
274                 0, 0, pv_init_iname, 2},
275         {{"op", (sizeof("op")-1)}, /* */
276                 PVT_OTHER, pv_get_ouri_attr, 0,
277                 0, 0, pv_init_iname, 3},
278         {{"oP", (sizeof("oP")-1)}, /* */
279                 PVT_OTHER, pv_get_ouri_attr, 0,
280                 0, 0, pv_init_iname, 4},
281         {{"ou", (sizeof("ou")-1)}, /* */
282                 PVT_OURI, pv_get_ouri, 0,
283                 0, 0, 0, 0},
284         {{"ouri", (sizeof("ouri")-1)}, /* */
285                 PVT_OURI, pv_get_ouri, 0,
286                 0, 0, 0, 0},
287         {{"oU", (sizeof("oU")-1)}, /* */
288                 PVT_OTHER, pv_get_ouri_attr, 0,
289                 0, 0, pv_init_iname, 1},
290         {{"pd", (sizeof("pd")-1)}, /* */
291                 PVT_OTHER, pv_get_ppi_attr, 0,
292                 0, pv_parse_index, pv_init_iname, 3},
293         {{"pn", (sizeof("pn")-1)}, /* */
294                 PVT_OTHER, pv_get_ppi_attr, 0,
295                 0, pv_parse_index, pv_init_iname, 4},
296         {{"pp", (sizeof("pp")-1)}, /* */
297                 PVT_OTHER, pv_get_pid, 0,
298                 0, 0, 0, 0},
299         {{"pr", (sizeof("pr")-1)}, /* */
300                 PVT_OTHER, pv_get_proto, 0,
301                 0, 0, 0, 0},
302         {{"proto", (sizeof("proto")-1)}, /* */
303                 PVT_OTHER, pv_get_proto, 0,
304                 0, 0, 0, 0},
305         {{"pu", (sizeof("pu")-1)}, /* */
306                 PVT_OTHER, pv_get_ppi_attr, 0,
307                 0, pv_parse_index, pv_init_iname, 1},
308         {{"pU", (sizeof("pU")-1)}, /* */
309                 PVT_OTHER, pv_get_ppi_attr, 0,
310                 0, pv_parse_index, pv_init_iname, 2},
311         {{"rb", (sizeof("rb")-1)}, /* */
312                 PVT_MSG_BODY, pv_get_msg_body, 0,
313                 0, 0, 0, 0},
314         /* {{"rc", (sizeof("rc")-1)},
315                 PVT_OTHER, pv_get_return_code, 0,
316                 0, 0, 0, 0},
317         {{"retcode", (sizeof("retcode")-1)},
318                 PVT_OTHER, pv_get_return_code, 0,
319                 0, 0, 0, 0}, */
320         {{"rd", (sizeof("rd")-1)}, /* */
321                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
322                 0, 0, pv_init_iname, 2},
323         {{"ruri.domain", (sizeof("ruri.domain")-1)}, /* */
324                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
325                 0, 0, pv_init_iname, 2},
326         {{"re", (sizeof("re")-1)}, /* */
327                 PVT_OTHER, pv_get_rpid, 0,
328                 0, 0, 0, 0},
329         {{"rm", (sizeof("rm")-1)}, /* */
330                 PVT_OTHER, pv_get_method, 0,
331                 0, 0, 0, 0},
332         {{"rmid", (sizeof("rmid")-1)}, /* */
333                 PVT_OTHER, pv_get_methodid, 0,
334                 0, 0, 0, 0},
335         {{"rp", (sizeof("rp")-1)}, /* */
336                 PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port,
337                 0, 0, pv_init_iname, 3},
338         {{"rP", (sizeof("rP")-1)}, /* */
339                 PVT_OTHER, pv_get_ruri_attr, 0,
340                 0, 0, pv_init_iname, 4},
341         {{"rr", (sizeof("rr")-1)}, /* */
342                 PVT_OTHER, pv_get_reason, 0,
343                 0, 0, 0, 0},
344         {{"rs", (sizeof("rs")-1)}, /* */
345                 PVT_OTHER, pv_get_status, 0,
346                 0, 0, 0, 0},
347         {{"rt", (sizeof("rt")-1)}, /* */
348                 PVT_OTHER, pv_get_refer_to, 0,
349                 0, 0, 0, 0},
350         {{"ru", (sizeof("ru")-1)}, /* */
351                 PVT_RURI, pv_get_ruri, pv_set_ruri,
352                 0, 0, 0, 0},
353         {{"ruri", (sizeof("ruri")-1)}, /* */
354                 PVT_RURI, pv_get_ruri, pv_set_ruri,
355                 0, 0, 0, 0},
356         {{"rU", (sizeof("rU")-1)}, /* */
357                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
358                 0, 0, pv_init_iname, 1},
359         {{"ruri.user", (sizeof("ruri.user")-1)}, /* */
360                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
361                 0, 0, pv_init_iname, 1},
362         {{"rv", (sizeof("rv")-1)}, /* */
363                 PVT_OTHER, pv_get_version, 0,
364                 0, 0, 0, 0},
365         {{"rz", (sizeof("rz")-1)}, /* */
366                 PVT_OTHER, pv_get_ruri_attr, 0,
367                 0, 0, pv_init_iname, 5},
368         {{"Ri", (sizeof("Ri")-1)}, /* */
369                 PVT_OTHER, pv_get_rcvip, 0,
370                 0, 0, 0, 0},
371         {{"Rp", (sizeof("Rp")-1)}, /* */
372                 PVT_OTHER, pv_get_rcvport, 0,
373                 0, 0, 0, 0},
374         {{"sf", (sizeof("sf")-1)}, /* */
375                 PVT_OTHER, pv_get_sflags, pv_set_sflags,
376                 0, 0, 0, 0},
377         {{"sF", (sizeof("sF")-1)}, /* */
378                 PVT_OTHER, pv_get_hexsflags, pv_set_sflags,
379                 0, 0, 0, 0},
380         {{"Sf", (sizeof("sf")-1)}, /* */
381                 PVT_OTHER, pv_get_sflag, pv_set_sflag,
382                 pv_parse_flag_param, 0, 0, 0},
383         {{"src_ip", (sizeof("src_ip")-1)}, /* */
384                 PVT_OTHER, pv_get_srcip, 0,
385                 0, 0, 0, 0},
386         {{"si", (sizeof("si")-1)}, /* */
387                 PVT_OTHER, pv_get_srcip, 0,
388                 0, 0, 0, 0},
389         { {"sid", (sizeof("sid")-1)}, /* server id */
390                 PVT_OTHER, pv_get_server_id, 0,
391                 0, 0, 0, 0},
392         {{"sp", (sizeof("sp")-1)}, /* */
393                 PVT_OTHER, pv_get_srcport, 0,
394                 0, 0, 0, 0},
395         {{"su", (sizeof("su")-1)}, /* */
396                 PVT_OTHER, pv_get_srcaddr_uri, 0,
397                 0, 0, 0, 0},
398         {{"td", (sizeof("td")-1)}, /* */
399                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
400                 0, 0, pv_init_iname, 3},
401         {{"sut", (sizeof("sut")-1)}, /* */
402                 PVT_OTHER, pv_get_srcaddr_uri_full, 0,
403                 0, 0, 0, 0},
404         {{"to.domain", (sizeof("to.domain")-1)}, /* */
405                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
406                 0, 0, pv_init_iname, 3},
407         {{"tn", (sizeof("tn")-1)}, /* */
408                 PVT_OTHER, pv_get_to_attr, pv_set_to_display,
409                 0, 0, pv_init_iname, 5},
410         {{"tt", (sizeof("tt")-1)}, /* */
411                 PVT_OTHER, pv_get_to_attr, 0,
412                 0, 0, pv_init_iname, 4},
413         {{"tu", (sizeof("tu")-1)}, /* */
414                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
415                 0, 0, pv_init_iname, 1},
416         {{"to", (sizeof("to")-1)}, /* */
417                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
418                 0, 0, pv_init_iname, 1},
419         {{"tU", (sizeof("tU")-1)}, /* */
420                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
421                 0, 0, pv_init_iname, 2},
422         {{"to.user", (sizeof("to.user")-1)}, /* */
423                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
424                 0, 0, pv_init_iname, 2},
425         {{"true", (sizeof("true")-1)}, /* */
426                 PVT_OTHER, pv_get_true, 0,
427                 0, 0, 0, 0},
428         {{"Tb", (sizeof("Tb")-1)}, /* */
429                 PVT_OTHER, pv_get_timeb, 0,
430                 0, 0, 0, 0},
431         {{"Tf", (sizeof("Tf")-1)}, /* */
432                 PVT_CONTEXT, pv_get_timef, 0,
433                 0, 0, 0, 0},
434         {{"TF", (sizeof("TF")-1)}, /* */
435                 PVT_OTHER, pv_get_timenowf, 0,
436                 0, 0, 0, 0},
437         {{"Ts", (sizeof("Ts")-1)}, /* */
438                 PVT_CONTEXT, pv_get_times, 0,
439                 0, 0, 0, 0},
440         {{"TS", (sizeof("TS")-1)}, /* */
441                 PVT_OTHER, pv_get_timenows, 0,
442                 0, 0, 0, 0},
443         {{"ua", (sizeof("ua")-1)}, /* */
444                 PVT_OTHER, pv_get_useragent, 0,
445                 0, 0, 0, 0},
446         {{"ruid", (sizeof("ruid")-1)}, /* */
447                 PVT_OTHER, pv_get_ruid, 0,
448                 0, 0, 0, 0},
449         {{"location_ua", (sizeof("location_ua")-1)}, /* */
450                 PVT_OTHER, pv_get_location_ua, 0,
451                 0, 0, 0, 0},
452
453         { {"shv", (sizeof("shv")-1)}, PVT_OTHER, pv_get_shvar,
454                 pv_set_shvar, pv_parse_shvar_name, 0, 0, 0},
455         { {"time", (sizeof("time")-1)}, PVT_CONTEXT, pv_get_local_time,
456                 0, pv_parse_time_name, 0, 0, 0},
457         { {"timef", (sizeof("timef")-1)}, PVT_CONTEXT, pv_get_local_strftime,
458                 0, pv_parse_strftime_name, 0, 0, 0},
459         { {"utime", (sizeof("utime")-1)}, PVT_CONTEXT, pv_get_utc_time,
460                 0, pv_parse_time_name, 0, 0, 0},
461         { {"utimef", (sizeof("utimef")-1)}, PVT_CONTEXT, pv_get_utc_strftime,
462                 0, pv_parse_strftime_name, 0, 0, 0},
463         { {"TV", (sizeof("TV")-1)}, PVT_OTHER, pv_get_timeval,
464                 0, pv_parse_timeval_name, 0, 0, 0},
465         { {"nh", (sizeof("nh")-1)}, PVT_OTHER, pv_get_nh,
466                 0, pv_parse_nh_name, 0, 0, 0},
467         { {"version", (sizeof("version")-1)}, PVT_OTHER, pv_get_sr_version,
468                 0, pv_parse_sr_version_name, 0, 0, 0},
469         { {"K", (sizeof("K")-1)}, PVT_OTHER, pv_get_K, 0,
470                 pv_parse_K_name, 0, 0, 0 },
471         { {"expires", (sizeof("expires")-1)}, PVT_OTHER, pv_get_expires, 0,
472                 pv_parse_expires_name, 0, 0, 0 },
473         { {"msg", (sizeof("msg")-1)}, PVT_OTHER, pv_get_msg_attrs, 0,
474                 pv_parse_msg_attrs_name, 0, 0, 0 },
475
476         { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
477 };
478
479 static int add_avp_aliases(modparam_t type, void* val);
480
481 static param_export_t params[]={
482         {"shvset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_shvar },
483         {"varset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_var },
484         {"avp_aliases",         PARAM_STRING|USE_FUNC_PARAM, (void*)add_avp_aliases },
485         {0,0,0}
486 };
487
488 static mi_export_t mi_cmds[] = {
489         { "shv_get",       mi_shvar_get,  0,                 0,  0 },
490         { "shv_set" ,      mi_shvar_set,  0,                 0,  0 },
491         { 0, 0, 0, 0, 0}
492 };
493
494 static int mod_init(void);
495 static void mod_destroy(void);
496 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo);
497 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
498 static int is_int(struct sip_msg* msg, char* pvar, char* s2);
499 static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
500 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
501 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname);
502 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2);
503 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2);
504 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2);
505 static int w_var_to_xavp(sip_msg_t *msg, char *p1, char *p2);
506 static int w_xavp_to_var(sip_msg_t *msg, char *p1);
507
508 int pv_evalx_fixup(void** param, int param_no);
509 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt);
510
511 static int pv_init_rpc(void);
512 int pv_register_api(pv_api_t*);
513
514 static cmd_export_t cmds[]={
515         {"pv_isset",  (cmd_function)pv_isset,  1, fixup_pvar_null, 0,
516                 ANY_ROUTE },
517         {"pv_unset",  (cmd_function)pv_unset,  1, fixup_pvar_null, 0,
518                 ANY_ROUTE },
519 #ifdef WITH_XAVP
520         {"pv_xavp_print",  (cmd_function)pv_xavp_print,  0, 0, 0,
521                 ANY_ROUTE },
522         {"pv_var_to_xavp",  (cmd_function)w_var_to_xavp, 2, 0, 0,
523                 ANY_ROUTE },
524         {"pv_xavp_to_var",  (cmd_function)w_xavp_to_var, 1, 0, 0,
525                 ANY_ROUTE },
526 #endif
527         {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, fixup_free_pvar_null,
528                 ANY_ROUTE},
529         {"typeof", (cmd_function)pv_typeof,       2, fixup_pvar_none,
530                 fixup_free_pvar_none,
531                 ANY_ROUTE},
532         {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null,
533                 fixup_free_pvar_null,
534                 ANY_ROUTE},
535         {"xavp_params_explode", (cmd_function)w_xavp_params_explode,
536                 2, fixup_spve_spve, fixup_free_spve_spve,
537                 ANY_ROUTE},
538         {"sbranch_set_ruri",  (cmd_function)w_sbranch_set_ruri,  0, 0, 0,
539                 ANY_ROUTE },
540         {"sbranch_append",    (cmd_function)w_sbranch_append,    0, 0, 0,
541                 ANY_ROUTE },
542         {"sbranch_reset",     (cmd_function)w_sbranch_reset,     0, 0, 0,
543                 ANY_ROUTE },
544         {"pv_evalx",          (cmd_function)w_pv_evalx,    2, pv_evalx_fixup,
545                 0, ANY_ROUTE },
546         /* API exports */
547         {"pv_register_api",   (cmd_function)pv_register_api,     NO_SCRIPT, 0, 0},
548         {0,0,0,0,0,0}
549 };
550
551
552
553 /** module exports */
554 struct module_exports exports= {
555         "pv",
556         DEFAULT_DLFLAGS, /* dlopen flags */
557         cmds,
558         params,
559         0,          /* exported statistics */
560         mi_cmds,    /* exported MI functions */
561         mod_pvs,    /* exported pseudo-variables */
562         0,          /* extra processes */
563         mod_init,   /* module initialization function */
564         0,
565         mod_destroy,
566         0           /* per-child init function */
567 };
568
569 static int mod_init(void)
570 {
571         if(register_mi_mod(exports.name, mi_cmds)!=0)
572         {
573                 LM_ERR("failed to register MI commands\n");
574                 return -1;
575         }
576         if(pv_init_rpc()!=0)
577         {
578                 LM_ERR("failed to register RPC commands\n");
579                 return -1;
580         }
581         pv_init_sbranch();
582
583         return 0;
584 }
585
586 static void mod_destroy(void)
587 {
588         shvar_destroy_locks();
589         destroy_shvars();
590 }
591
592 int mod_register(char *path, int *dlflags, void *p1, void *p2)
593 {
594         if(tr_init_buffers()<0)
595         {
596                 LM_ERR("failed to initialize transformations buffers\n");
597                 return -1;
598         }
599         return register_trans_mod(path, mod_trans);
600 }
601
602 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo)
603 {
604         pv_spec_t *sp;
605         pv_value_t value;
606         int ret;
607
608         sp = (pv_spec_t*)pvid;
609         if(pv_get_spec_value(msg, sp, &value)!=0)
610                 return -1;
611         ret =1;
612         if(value.flags & (PV_VAL_EMPTY|PV_VAL_NULL))
613                 ret = -1;
614         pv_value_destroy(&value);
615         return ret;
616 }
617
618 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo)
619 {
620         pv_spec_t *sp;
621
622         sp = (pv_spec_t*)pvid;
623         if(pv_set_spec_value(msg, sp, 0, NULL)<0) {
624                 LM_ERR("faile to unset variable\n");
625                 return -1;
626         }
627
628         return 1;
629 }
630
631 static int add_avp_aliases(modparam_t type, void* val)
632 {
633         if (val!=0 && ((char*)val)[0]!=0)
634         {
635                 if ( add_avp_galias_str((char*)val)!=0 )
636                         return -1;
637         }
638
639         return 0;
640 }
641
642 /**
643  * match the type of the variable value
644  */
645 static int pv_typeof(sip_msg_t *msg, char *pv, char *t)
646 {
647         pv_value_t val;
648
649         if (pv==NULL || t==NULL)
650                 return -1;
651         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
652                 return -1;
653
654         switch(t[0]) {
655                 case 'i':
656                 case 'I':
657                         if(val.flags & PV_TYPE_INT)
658                                 return 1;
659                         return -1;
660                 case 'n':
661                 case 'N':
662                         if(val.flags & PV_VAL_NULL)
663                                 return 1;
664                         return -1;
665                 case 's':
666                 case 'S':
667                         if(!(val.flags & PV_VAL_STR))
668                                 return -1;
669                         if(val.flags & PV_TYPE_INT)
670                                 return -1;
671                         return 1;
672                 default:
673                         return -1;
674         }
675 }
676
677 /**
678  * return true if the type is string and value not empty
679  */
680 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2)
681 {
682         pv_value_t val;
683
684         if (pv==NULL)
685                 return -1;
686
687         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
688                 return -1;
689
690         if(!(val.flags & PV_VAL_STR))
691                 return -1;
692         if(val.flags & PV_TYPE_INT)
693                 return -1;
694
695         if(val.rs.len>0)
696                 return 1;
697
698         return -1;
699 }
700
701 /**
702  * Copyright (C) 2011 Juha Heinanen
703  *
704  * Checks if pvar argument contains int value
705  */
706 static int is_int(struct sip_msg* msg, char* pvar, char* s2)
707 {
708         pv_spec_t *pvar_sp;
709         pv_value_t pv_val;
710
711         pvar_sp = (pv_spec_t *)pvar;
712
713         if (pvar_sp && (pv_get_spec_value(msg, pvar_sp, &pv_val) == 0)) {
714                 return (pv_val.flags & PV_VAL_INT)?1:-1;
715         }
716
717         return -1;
718 }
719
720 static int w_var_to_xavp(sip_msg_t *msg, char *s1, char *s2)
721 {
722         str xname, varname;
723
724         if(s1 == NULL || s2 == NULL) {
725                 LM_ERR("wrong parameters\n");
726                 return -1;
727         }
728
729         varname.len = strlen(s1); varname.s = s1;
730         xname.s = s2; xname.len = strlen(s2);
731         return pv_var_to_xavp(&varname, &xname);
732 }
733
734 static int w_xavp_to_var(sip_msg_t *msg, char *s1)
735 {
736         str xname;
737
738         if(s1 == NULL) {
739                 LM_ERR("wrong parameters\n");
740                 return -1;
741         }
742
743         xname.s = s1; xname.len = strlen(s1);
744         return pv_xavp_to_var(&xname);
745 }
746
747 /**
748  *
749  */
750 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname)
751 {
752         str sparams;
753         str sxname;
754
755         if(fixup_get_svalue(msg, (gparam_t*)pparams, &sparams)!=0) {
756                 LM_ERR("cannot get the params\n");
757                 return -1;
758         }
759         if(fixup_get_svalue(msg, (gparam_t*)pxname, &sxname)!=0) {
760                 LM_ERR("cannot get the xavp name\n");
761                 return -1;
762         }
763
764         if(xavp_params_explode(&sparams, &sxname)<0)
765                 return -1;
766
767         return 1;
768 }
769
770 /**
771  *
772  */
773 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2)
774 {
775         if(sbranch_set_ruri(msg)<0)
776                 return -1;
777         return 1;
778 }
779
780 /**
781  *
782  */
783 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2)
784 {
785         if(sbranch_append(msg)<0)
786                 return -1;
787         return 1;
788 }
789
790 /**
791  *
792  */
793 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2)
794 {
795         if(sbranch_reset()<0)
796                 return -1;
797         return 1;
798 }
799
800 int pv_evalx_fixup(void** param, int param_no)
801 {
802         pv_spec_t *spec=NULL;
803         pv_elem_t *pvmodel=NULL;
804         str tstr;
805
806         if(param_no==1) {
807                 spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
808                 if(spec==NULL) {
809                         LM_ERR("out of pkg\n");
810                         return -1;
811                 }
812                 memset(spec, 0, sizeof(pv_spec_t));
813                 tstr.s = (char*)(*param);
814                 tstr.len = strlen(tstr.s);
815                 if(pv_parse_spec(&tstr, spec)==NULL) {
816                         LM_ERR("unknown script variable in first parameter\n");
817                         pkg_free(spec);
818                         return -1;
819                 }
820                 if(!pv_is_w(spec)) {
821                         LM_ERR("read-only script variable in first parameter\n");
822                         pkg_free(spec);
823                         return -1;
824                 }
825                 *param = spec;
826         } else if(param_no==2) {
827                 pvmodel = 0;
828                 tstr.s = (char*)(*param);
829                 tstr.len = strlen(tstr.s);
830                 if(pv_parse_format(&tstr, &pvmodel)<0) {
831                         LM_ERR("error in second parameter\n");
832                         return -1;
833                 }
834                 *param = pvmodel;
835         }
836         return 0;
837 }
838
839 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt)
840 {
841         pv_spec_t *ispec=NULL;
842         pv_elem_t *imodel=NULL;
843         str tstr = {0, 0};
844         pv_value_t val;
845
846         ispec = (pv_spec_t*)dst;
847
848         imodel = (pv_elem_t*)fmt;
849
850         memset(&val, 0, sizeof(pv_value_t));
851
852         if(pv_printf_s(msg, imodel, &tstr)!=0) {
853                 LM_ERR("cannot eval second parameter\n");
854                 goto error;
855         }
856
857         if(pv_eval_str(msg, &val.rs, &tstr)<0){
858                 LM_ERR("cannot eval reparsed value of second parameter\n");
859                 return -1;
860         }
861
862         val.flags = PV_VAL_STR;
863         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
864                 LM_ERR("setting PV failed\n");
865                 goto error;
866         }
867
868         return 1;
869 error:
870         return -1;
871 }
872
873 /**
874  *
875  */
876 static const char* rpc_shv_set_doc[2] = {
877         "Set a shared variable (args: name type value)",
878         0
879 };
880
881 static const char* rpc_shv_get_doc[2] = {
882         "Get the value of a shared variable. If no argument, dumps all",
883         0
884 };
885
886 rpc_export_t pv_rpc[] = {
887         {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
888         {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
889         {0, 0, 0, 0}
890 };
891
892 static int pv_init_rpc(void)
893 {
894         if (rpc_register_array(pv_rpc)!=0)
895         {
896                 LM_ERR("failed to register RPC commands\n");
897                 return -1;
898         }
899         return 0;
900 }