5743dd6d4df3d87277823bd7b8f123c9dc656c67
[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/lvalue.h"
28 #include "../../core/mod_fix.h"
29 #include "../../core/xavp.h"
30 #include "../../core/kemi.h"
31 #include "../../core/rpc.h"
32 #include "../../core/rpc_lookup.h"
33
34
35 #include "pv_branch.h"
36 #include "pv_core.h"
37 #include "pv_stats.h"
38 #include "pv_shv.h"
39 #include "pv_time.h"
40 #include "pv_trans.h"
41 #include "pv_select.h"
42 #ifdef WITH_XAVP
43 #include "pv_xavp.h"
44 #endif
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 #ifdef WITH_XAVP
93         { {"xavp", sizeof("xavp")-1}, /* xavp */
94                 PVT_XAVP, pv_get_xavp, pv_set_xavp,
95                 pv_parse_xavp_name, 0, 0, 0 },
96 #endif
97
98         {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp,
99                 pv_parse_avp_name, pv_parse_index, 0, 0},
100         {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name,
101                 pv_parse_index, 0, 0},
102         {{"hdrc", (sizeof("hdrc")-1)}, PVT_HDRC, pv_get_hdrc, 0, pv_parse_hdr_name,
103                 0, 0, 0},
104         {{"var", (sizeof("var")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
105                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
106         {{"vz", (sizeof("vz")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
107                 pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
108         {{"vn", (sizeof("vn")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
109                 pv_set_scriptvar, pv_parse_scriptvarnull_name, 0, 0, 0},
110         {{"ai", (sizeof("ai")-1)}, /* */
111                 PVT_OTHER, pv_get_pai, 0,
112                 0, pv_parse_index, 0, 0},
113         {{"adu", (sizeof("adu")-1)}, /* auth digest uri */
114                 PVT_OTHER, pv_get_authattr, 0,
115                 0, 0, pv_init_iname, 3},
116         {{"ar", (sizeof("ar")-1)}, /* auth realm */
117                 PVT_OTHER, pv_get_authattr, 0,
118                 0, 0, pv_init_iname, 2},
119         {{"au", (sizeof("au")-1)}, /* */
120                 PVT_OTHER, pv_get_authattr, 0,
121                 0, 0, pv_init_iname, 1},
122         {{"ad", (sizeof("ad")-1)}, /* */
123                 PVT_OTHER, pv_get_authattr, 0,
124                 0, 0, pv_init_iname, 4},
125         {{"aU", (sizeof("aU")-1)}, /* */
126                 PVT_OTHER, pv_get_authattr, 0,
127                 0, 0, pv_init_iname, 5},
128         {{"aa", (sizeof("aa")-1)}, /* auth algorithm */
129                 PVT_OTHER, pv_get_authattr, 0,
130                 0, 0, pv_init_iname, 6},
131         {{"adn", (sizeof("adn")-1)}, /* auth nonce */
132                 PVT_OTHER, pv_get_authattr, 0,
133                 0, 0, pv_init_iname, 7},
134         {{"adc", (sizeof("adc")-1)}, /* auth cnonce */
135                 PVT_OTHER, pv_get_authattr, 0,
136                 0, 0, pv_init_iname, 8},
137         {{"adr", (sizeof("adr")-1)}, /* auth response */
138                 PVT_OTHER, pv_get_authattr, 0,
139                 0, 0, pv_init_iname, 9},
140         {{"ado", (sizeof("ado")-1)}, /* auth opaque */
141                 PVT_OTHER, pv_get_authattr, 0,
142                 0, 0, pv_init_iname, 10},
143         {{"Au", (sizeof("Au")-1)}, /* */
144                 PVT_OTHER, pv_get_acc_username, 0,
145                 0, 0, pv_init_iname, 1},
146         {{"bf", (sizeof("bf")-1)}, /* */
147                 PVT_CONTEXT, pv_get_bflags, pv_set_bflags,
148                 0, 0, 0, 0},
149         {{"bF", (sizeof("bF")-1)}, /* */
150                 PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags,
151                 0, 0, 0, 0},
152         {{"Bf", (sizeof("Bf")-1)}, /* */
153                 PVT_CONTEXT, pv_get_bflag, pv_set_bflag,
154                 pv_parse_flag_param, 0, 0, 0},
155         {{"br", (sizeof("br")-1)}, /* */
156                 PVT_BRANCH, pv_get_branch, pv_set_branch,
157                 0, 0, 0, 0},
158         {{"bR", (sizeof("bR")-1)}, /* */
159                 PVT_CONTEXT, pv_get_branches, 0,
160                 0, 0, 0, 0},
161         {{"bs", (sizeof("bs")-1)}, /* */
162                 PVT_OTHER, pv_get_body_size, 0,
163                 0, 0, 0, 0},
164         {{"ci", (sizeof("ci")-1)}, /* */
165                 PVT_OTHER, pv_get_callid, 0,
166                 0, 0, 0, 0},
167         {{"cl", (sizeof("cl")-1)}, /* */
168                 PVT_OTHER, pv_get_content_length, 0,
169                 0, 0, 0, 0},
170         {{"cnt", sizeof("cnt")-1},
171                 PVT_OTHER, pv_get_cnt, 0,
172                 pv_parse_cnt_name, 0, 0, 0 },
173         {{"conid", (sizeof("conid")-1)}, /* */
174                 PVT_OTHER, pv_get_tcpconn_id, 0,
175                 0, 0, 0, 0},
176         {{"cs", (sizeof("cs")-1)}, /* */
177                 PVT_OTHER, pv_get_cseq, 0,
178                 0, 0, 0, 0},
179         {{"csb", (sizeof("csb")-1)}, /* */
180                 PVT_OTHER, pv_get_cseq_body, 0,
181                 0, 0, 0, 0},
182         {{"ct", (sizeof("ct")-1)}, /* */
183                 PVT_OTHER, pv_get_contact, 0,
184                 0, 0, 0, 0},
185         {{"cT", (sizeof("cT")-1)}, /* */
186                 PVT_OTHER, pv_get_content_type, 0,
187                 0, 0, 0, 0},
188         {{"dd", (sizeof("dd")-1)}, /* */
189                 PVT_OTHER, pv_get_dsturi_attr, 0,
190                 0, 0, pv_init_iname, 1},
191         {{"di", (sizeof("di")-1)}, /* */
192                 PVT_OTHER, pv_get_diversion, 0,
193                 0, 0, pv_init_iname, 1},
194         {{"dir", (sizeof("dir")-1)}, /* */
195                 PVT_OTHER, pv_get_diversion, 0,
196                 0, 0, pv_init_iname, 2},
197         {{"dip", (sizeof("dis")-1)}, /* */
198                 PVT_OTHER, pv_get_diversion, 0,
199                 0, 0, pv_init_iname, 3},
200         {{"dic", (sizeof("dic")-1)}, /* */
201                 PVT_OTHER, pv_get_diversion, 0,
202                 0, 0, pv_init_iname, 4},
203         {{"dp", (sizeof("dp")-1)}, /* */
204                 PVT_OTHER, pv_get_dsturi_attr, 0,
205                 0, 0, pv_init_iname, 2},
206         {{"dP", (sizeof("dP")-1)}, /* */
207                 PVT_OTHER, pv_get_dsturi_attr, 0,
208                 0, 0, pv_init_iname, 3},
209         {{"ds", (sizeof("ds")-1)}, /* */
210                 PVT_CONTEXT, pv_get_dset, 0,
211                 0, 0, 0, 0},
212         {{"du", (sizeof("du")-1)}, /* */
213                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
214                 0, 0, 0, 0},
215         {{"duri", (sizeof("duri")-1)}, /* */
216                 PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
217                 0, 0, 0, 0},
218         {{"env", (sizeof("env")-1)}, PVT_OTHER, pv_get_env, 0,
219                 pv_parse_env_name, 0, 0, 0},
220         {{"err.class", (sizeof("err.class")-1)}, /* */
221                 PVT_OTHER, pv_get_errinfo_attr, 0,
222                 0, 0, 0, 0},
223         {{"err.level", (sizeof("err.level")-1)}, /* */
224                 PVT_OTHER, pv_get_errinfo_attr, 0,
225                 0, 0, pv_init_iname, 1},
226         {{"err.info", (sizeof("err.info")-1)}, /* */
227                 PVT_OTHER, pv_get_errinfo_attr, 0,
228                 0, 0, pv_init_iname, 2},
229         {{"err.rcode", (sizeof("err.rcode")-1)}, /* */
230                 PVT_OTHER, pv_get_errinfo_attr, 0,
231                 0, 0, pv_init_iname, 3},
232         {{"err.rreason", (sizeof("err.rreason")-1)}, /* */
233                 PVT_OTHER, pv_get_errinfo_attr, 0,
234                 0, 0, pv_init_iname, 4},
235         {{"fd", (sizeof("fd")-1)}, /* */
236                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
237                 0, 0, pv_init_iname, 3},
238         {{"from.domain", (sizeof("from.domain")-1)}, /* */
239                 PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
240                 0, 0, pv_init_iname, 3},
241         {{"fn", (sizeof("fn")-1)}, /* */
242                 PVT_OTHER, pv_get_from_attr, pv_set_from_display,
243                 0, 0, pv_init_iname, 5},
244         {{"fs", (sizeof("fs")-1)}, /* */
245                 PVT_OTHER, pv_get_force_sock, pv_set_force_sock,
246                 0, 0, 0, 0},
247         {{"ft", (sizeof("ft")-1)}, /* */
248                 PVT_OTHER, pv_get_from_attr, 0,
249                 0, 0, pv_init_iname, 4},
250         {{"fu", (sizeof("fu")-1)}, /* */
251                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
252                 0, 0, pv_init_iname, 1},
253         {{"from", (sizeof("from")-1)}, /* */
254                 PVT_FROM, pv_get_from_attr, pv_set_from_uri,
255                 0, 0, pv_init_iname, 1},
256         {{"fU", (sizeof("fU")-1)}, /* */
257                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
258                 0, 0, pv_init_iname, 2},
259         {{"from.user", (sizeof("from.user")-1)}, /* */
260                 PVT_OTHER, pv_get_from_attr, pv_set_from_username,
261                 0, 0, pv_init_iname, 2},
262         {{"mb", (sizeof("mb")-1)}, /* */
263                 PVT_OTHER, pv_get_msg_buf, 0,
264                 0, 0, 0, 0},
265         {{"mf", (sizeof("mf")-1)}, /* */
266                 PVT_OTHER, pv_get_flags, pv_set_mflags,
267                 0, 0, 0, 0},
268         {{"mF", (sizeof("mF")-1)}, /* */
269                 PVT_OTHER, pv_get_hexflags, pv_set_mflags,
270                 0, 0, 0, 0},
271         {{"Mf", (sizeof("mf")-1)}, /* */
272                 PVT_OTHER, pv_get_flag, pv_set_mflag,
273                 pv_parse_flag_param, 0, 0, 0},
274         {{"ml", (sizeof("ml")-1)}, /* */
275                 PVT_OTHER, pv_get_msg_len, 0,
276                 0, 0, 0, 0},
277         {{"mt", (sizeof("mt")-1)}, /* */
278                 PVT_OTHER, pv_get_msgtype, 0,
279                 0, 0, 0, 0},
280         {{"od", (sizeof("od")-1)}, /* */
281                 PVT_OTHER, pv_get_ouri_attr, 0,
282                 0, 0, pv_init_iname, 2},
283         {{"op", (sizeof("op")-1)}, /* */
284                 PVT_OTHER, pv_get_ouri_attr, 0,
285                 0, 0, pv_init_iname, 3},
286         {{"oP", (sizeof("oP")-1)}, /* */
287                 PVT_OTHER, pv_get_ouri_attr, 0,
288                 0, 0, pv_init_iname, 4},
289         {{"ou", (sizeof("ou")-1)}, /* */
290                 PVT_OURI, pv_get_ouri, 0,
291                 0, 0, 0, 0},
292         {{"ouri", (sizeof("ouri")-1)}, /* */
293                 PVT_OURI, pv_get_ouri, 0,
294                 0, 0, 0, 0},
295         {{"oU", (sizeof("oU")-1)}, /* */
296                 PVT_OTHER, pv_get_ouri_attr, 0,
297                 0, 0, pv_init_iname, 1},
298         {{"pd", (sizeof("pd")-1)}, /* */
299                 PVT_OTHER, pv_get_ppi_attr, 0,
300                 0, pv_parse_index, pv_init_iname, 3},
301         {{"pn", (sizeof("pn")-1)}, /* */
302                 PVT_OTHER, pv_get_ppi_attr, 0,
303                 0, pv_parse_index, pv_init_iname, 4},
304         {{"pp", (sizeof("pp")-1)}, /* */
305                 PVT_OTHER, pv_get_pid, 0,
306                 0, 0, 0, 0},
307         {{"pr", (sizeof("pr")-1)}, /* */
308                 PVT_OTHER, pv_get_proto, 0,
309                 0, 0, 0, 0},
310         {{"prid", (sizeof("prid")-1)}, /* */
311                 PVT_OTHER, pv_get_protoid, 0,
312                 0, 0, 0, 0},
313         {{"proto", (sizeof("proto")-1)}, /* */
314                 PVT_OTHER, pv_get_proto, 0,
315                 0, 0, 0, 0},
316         {{"pu", (sizeof("pu")-1)}, /* */
317                 PVT_OTHER, pv_get_ppi_attr, 0,
318                 0, pv_parse_index, pv_init_iname, 1},
319         {{"pU", (sizeof("pU")-1)}, /* */
320                 PVT_OTHER, pv_get_ppi_attr, 0,
321                 0, pv_parse_index, pv_init_iname, 2},
322         {{"rb", (sizeof("rb")-1)}, /* */
323                 PVT_MSG_BODY, pv_get_msg_body, 0,
324                 0, 0, 0, 0},
325         /* {{"rc", (sizeof("rc")-1)},
326                 PVT_OTHER, pv_get_return_code, 0,
327                 0, 0, 0, 0},
328         {{"retcode", (sizeof("retcode")-1)},
329                 PVT_OTHER, pv_get_return_code, 0,
330                 0, 0, 0, 0}, */
331         {{"rd", (sizeof("rd")-1)}, /* */
332                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
333                 0, 0, pv_init_iname, 2},
334         {{"ruri.domain", (sizeof("ruri.domain")-1)}, /* */
335                 PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
336                 0, 0, pv_init_iname, 2},
337         {{"re", (sizeof("re")-1)}, /* */
338                 PVT_OTHER, pv_get_rpid, 0,
339                 0, 0, 0, 0},
340         {{"rm", (sizeof("rm")-1)}, /* */
341                 PVT_OTHER, pv_get_method, 0,
342                 0, 0, 0, 0},
343         {{"rmid", (sizeof("rmid")-1)}, /* */
344                 PVT_OTHER, pv_get_methodid, 0,
345                 0, 0, 0, 0},
346         {{"rp", (sizeof("rp")-1)}, /* */
347                 PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port,
348                 0, 0, pv_init_iname, 3},
349         {{"rP", (sizeof("rP")-1)}, /* */
350                 PVT_OTHER, pv_get_ruri_attr, 0,
351                 0, 0, pv_init_iname, 4},
352         {{"rr", (sizeof("rr")-1)}, /* */
353                 PVT_OTHER, pv_get_reason, 0,
354                 0, 0, 0, 0},
355         {{"rs", (sizeof("rs")-1)}, /* */
356                 PVT_OTHER, pv_get_status, 0,
357                 0, 0, 0, 0},
358         {{"rt", (sizeof("rt")-1)}, /* */
359                 PVT_OTHER, pv_get_refer_to, 0,
360                 0, 0, 0, 0},
361         {{"ru", (sizeof("ru")-1)}, /* */
362                 PVT_RURI, pv_get_ruri, pv_set_ruri,
363                 0, 0, 0, 0},
364         {{"ruri", (sizeof("ruri")-1)}, /* */
365                 PVT_RURI, pv_get_ruri, pv_set_ruri,
366                 0, 0, 0, 0},
367         {{"rU", (sizeof("rU")-1)}, /* */
368                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
369                 0, 0, pv_init_iname, 1},
370         {{"ruri.user", (sizeof("ruri.user")-1)}, /* */
371                 PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
372                 0, 0, pv_init_iname, 1},
373         {{"rv", (sizeof("rv")-1)}, /* */
374                 PVT_OTHER, pv_get_version, 0,
375                 0, 0, 0, 0},
376         {{"rz", (sizeof("rz")-1)}, /* */
377                 PVT_OTHER, pv_get_ruri_attr, 0,
378                 0, 0, pv_init_iname, 5},
379         {{"Ri", (sizeof("Ri")-1)}, /* */
380                 PVT_OTHER, pv_get_rcvip, 0,
381                 0, 0, 0, 0},
382         {{"Rp", (sizeof("Rp")-1)}, /* */
383                 PVT_OTHER, pv_get_rcvport, 0,
384                 0, 0, 0, 0},
385         {{"Ru", (sizeof("Ru")-1)}, /* */
386                 PVT_OTHER, pv_get_rcvaddr_uri, 0,
387                 0, 0, 0, 0},
388         {{"Rut", (sizeof("Rut")-1)}, /* */
389                 PVT_OTHER, pv_get_rcvaddr_uri_full, 0,
390                 0, 0, 0, 0},
391         {{"RAi", (sizeof("RAi")-1)}, /* */
392                 PVT_OTHER, pv_get_rcv_advertised_ip, 0,
393                 0, 0, 0, 0},
394         {{"RAp", (sizeof("RAp")-1)}, /* */
395                 PVT_OTHER, pv_get_rcv_advertised_port, 0,
396                 0, 0, 0, 0},
397         {{"RAu", (sizeof("RAu")-1)}, /* */
398                 PVT_OTHER, pv_get_rcvadv_uri, 0,
399                 0, 0, 0, 0},
400         {{"RAut", (sizeof("RAut")-1)}, /* */
401                 PVT_OTHER, pv_get_rcvadv_uri_full, 0,
402                 0, 0, 0, 0},
403         {{"sf", (sizeof("sf")-1)}, /* */
404                 PVT_OTHER, pv_get_sflags, pv_set_sflags,
405                 0, 0, 0, 0},
406         {{"sF", (sizeof("sF")-1)}, /* */
407                 PVT_OTHER, pv_get_hexsflags, pv_set_sflags,
408                 0, 0, 0, 0},
409         {{"Sf", (sizeof("sf")-1)}, /* */
410                 PVT_OTHER, pv_get_sflag, pv_set_sflag,
411                 pv_parse_flag_param, 0, 0, 0},
412         {{"src_ip", (sizeof("src_ip")-1)}, /* */
413                 PVT_OTHER, pv_get_srcip, 0,
414                 0, 0, 0, 0},
415         {{"si", (sizeof("si")-1)}, /* */
416                 PVT_OTHER, pv_get_srcip, 0,
417                 0, 0, 0, 0},
418         {{"siz", (sizeof("siz")-1)}, /* */
419                 PVT_OTHER, pv_get_srcipz, 0,
420                 0, 0, 0, 0},
421         { {"sid", (sizeof("sid")-1)}, /* server id */
422                 PVT_OTHER, pv_get_server_id, 0,
423                 0, 0, 0, 0},
424         {{"sp", (sizeof("sp")-1)}, /* */
425                 PVT_OTHER, pv_get_srcport, 0,
426                 0, 0, 0, 0},
427         {{"su", (sizeof("su")-1)}, /* */
428                 PVT_OTHER, pv_get_srcaddr_uri, 0,
429                 0, 0, 0, 0},
430         {{"sut", (sizeof("sut")-1)}, /* */
431                 PVT_OTHER, pv_get_srcaddr_uri_full, 0,
432                 0, 0, 0, 0},
433         {{"td", (sizeof("td")-1)}, /* */
434                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
435                 0, 0, pv_init_iname, 3},
436         {{"to.domain", (sizeof("to.domain")-1)}, /* */
437                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
438                 0, 0, pv_init_iname, 3},
439         {{"tn", (sizeof("tn")-1)}, /* */
440                 PVT_OTHER, pv_get_to_attr, pv_set_to_display,
441                 0, 0, pv_init_iname, 5},
442         {{"tt", (sizeof("tt")-1)}, /* */
443                 PVT_OTHER, pv_get_to_attr, 0,
444                 0, 0, pv_init_iname, 4},
445         {{"tu", (sizeof("tu")-1)}, /* */
446                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
447                 0, 0, pv_init_iname, 1},
448         {{"to", (sizeof("to")-1)}, /* */
449                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
450                 0, 0, pv_init_iname, 1},
451         {{"tU", (sizeof("tU")-1)}, /* */
452                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
453                 0, 0, pv_init_iname, 2},
454         {{"to.user", (sizeof("to.user")-1)}, /* */
455                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
456                 0, 0, pv_init_iname, 2},
457         {{"true", (sizeof("true")-1)}, /* */
458                 PVT_OTHER, pv_get_true, 0,
459                 0, 0, 0, 0},
460         {{"Tb", (sizeof("Tb")-1)}, /* */
461                 PVT_OTHER, pv_get_timeb, 0,
462                 0, 0, 0, 0},
463         {{"Tf", (sizeof("Tf")-1)}, /* */
464                 PVT_CONTEXT, pv_get_timef, 0,
465                 0, 0, 0, 0},
466         {{"TF", (sizeof("TF")-1)}, /* */
467                 PVT_OTHER, pv_get_timenowf, 0,
468                 0, 0, 0, 0},
469         {{"Ts", (sizeof("Ts")-1)}, /* */
470                 PVT_CONTEXT, pv_get_times, 0,
471                 0, 0, 0, 0},
472         {{"TS", (sizeof("TS")-1)}, /* */
473                 PVT_OTHER, pv_get_timenows, 0,
474                 0, 0, 0, 0},
475         {{"ua", (sizeof("ua")-1)}, /* */
476                 PVT_OTHER, pv_get_useragent, 0,
477                 0, 0, 0, 0},
478         {{"ruid", (sizeof("ruid")-1)}, /* */
479                 PVT_OTHER, pv_get_ruid, 0,
480                 0, 0, 0, 0},
481         {{"location_ua", (sizeof("location_ua")-1)}, /* */
482                 PVT_OTHER, pv_get_location_ua, 0,
483                 0, 0, 0, 0},
484
485         { {"shv", (sizeof("shv")-1)}, PVT_OTHER, pv_get_shvar,
486                 pv_set_shvar, pv_parse_shvar_name, 0, 0, 0},
487         { {"time", (sizeof("time")-1)}, PVT_CONTEXT, pv_get_local_time,
488                 0, pv_parse_time_name, 0, 0, 0},
489         { {"timef", (sizeof("timef")-1)}, PVT_CONTEXT, pv_get_local_strftime,
490                 0, pv_parse_strftime_name, 0, 0, 0},
491         { {"utime", (sizeof("utime")-1)}, PVT_CONTEXT, pv_get_utc_time,
492                 0, pv_parse_time_name, 0, 0, 0},
493         { {"utimef", (sizeof("utimef")-1)}, PVT_CONTEXT, pv_get_utc_strftime,
494                 0, pv_parse_strftime_name, 0, 0, 0},
495         { {"TV", (sizeof("TV")-1)}, PVT_OTHER, pv_get_timeval,
496                 0, pv_parse_timeval_name, 0, 0, 0},
497         { {"nh", (sizeof("nh")-1)}, PVT_OTHER, pv_get_nh,
498                 0, pv_parse_nh_name, 0, 0, 0},
499         { {"version", (sizeof("version")-1)}, PVT_OTHER, pv_get_sr_version,
500                 0, pv_parse_sr_version_name, 0, 0, 0},
501         { {"K", (sizeof("K")-1)}, PVT_OTHER, pv_get_K, 0,
502                 pv_parse_K_name, 0, 0, 0 },
503         { {"expires", (sizeof("expires")-1)}, PVT_OTHER, pv_get_expires, 0,
504                 pv_parse_expires_name, 0, 0, 0 },
505         { {"msg", (sizeof("msg")-1)}, PVT_OTHER, pv_get_msg_attrs, 0,
506                 pv_parse_msg_attrs_name, 0, 0, 0 },
507
508         { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
509 };
510
511 static int add_avp_aliases(modparam_t type, void* val);
512
513 static param_export_t params[]={
514         {"shvset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_shvar },
515         {"varset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_var },
516         {"avp_aliases",         PARAM_STRING|USE_FUNC_PARAM, (void*)add_avp_aliases },
517         {0,0,0}
518 };
519
520 static int mod_init(void);
521 static void mod_destroy(void);
522 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo);
523 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
524 static int is_int(struct sip_msg* msg, char* pvar, char* s2);
525 static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
526 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
527 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname);
528 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2);
529 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2);
530 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2);
531 static int w_var_to_xavp(sip_msg_t *msg, char *p1, char *p2);
532 static int w_xavp_to_var(sip_msg_t *msg, char *p1);
533
534 int pv_evalx_fixup(void** param, int param_no);
535 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt);
536
537 static int pv_init_rpc(void);
538 int pv_register_api(pv_api_t*);
539
540 static cmd_export_t cmds[]={
541         {"pv_isset",  (cmd_function)pv_isset,  1, fixup_pvar_null, 0,
542                 ANY_ROUTE },
543         {"pv_unset",  (cmd_function)pv_unset,  1, fixup_pvar_null, 0,
544                 ANY_ROUTE },
545 #ifdef WITH_XAVP
546         {"pv_xavp_print",  (cmd_function)pv_xavp_print,  0, 0, 0,
547                 ANY_ROUTE },
548         {"pv_var_to_xavp",  (cmd_function)w_var_to_xavp, 2, fixup_spve_spve,
549                 fixup_free_spve_spve, ANY_ROUTE },
550         {"pv_xavp_to_var",  (cmd_function)w_xavp_to_var, 1, fixup_spve_null,
551                 fixup_free_spve_null, ANY_ROUTE },
552 #endif
553         {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, fixup_free_pvar_null,
554                 ANY_ROUTE},
555         {"typeof", (cmd_function)pv_typeof,       2, fixup_pvar_none,
556                 fixup_free_pvar_none,
557                 ANY_ROUTE},
558         {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null,
559                 fixup_free_pvar_null,
560                 ANY_ROUTE},
561         {"xavp_params_explode", (cmd_function)w_xavp_params_explode,
562                 2, fixup_spve_spve, fixup_free_spve_spve,
563                 ANY_ROUTE},
564         {"sbranch_set_ruri",  (cmd_function)w_sbranch_set_ruri,  0, 0, 0,
565                 ANY_ROUTE },
566         {"sbranch_append",    (cmd_function)w_sbranch_append,    0, 0, 0,
567                 ANY_ROUTE },
568         {"sbranch_reset",     (cmd_function)w_sbranch_reset,     0, 0, 0,
569                 ANY_ROUTE },
570         {"pv_evalx",          (cmd_function)w_pv_evalx,    2, pv_evalx_fixup,
571                 0, ANY_ROUTE },
572         /* API exports */
573         {"pv_register_api",   (cmd_function)pv_register_api,     NO_SCRIPT, 0, 0},
574         {0,0,0,0,0,0}
575 };
576
577
578
579 /** module exports */
580 struct module_exports exports= {
581         "pv",
582         DEFAULT_DLFLAGS, /* dlopen flags */
583         cmds,
584         params,
585         0,          /* exported statistics */
586         0,          /* exported MI functions */
587         mod_pvs,    /* exported pseudo-variables */
588         0,          /* extra processes */
589         mod_init,   /* module initialization function */
590         0,
591         mod_destroy,
592         0           /* per-child init function */
593 };
594
595 static int mod_init(void)
596 {
597         if(pv_init_rpc()!=0)
598         {
599                 LM_ERR("failed to register RPC commands\n");
600                 return -1;
601         }
602         pv_init_sbranch();
603
604         return 0;
605 }
606
607 static void mod_destroy(void)
608 {
609         shvar_destroy_locks();
610         destroy_shvars();
611 }
612
613 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo)
614 {
615         pv_spec_t *sp;
616         pv_value_t value;
617         int ret;
618
619         sp = (pv_spec_t*)pvid;
620         if(pv_get_spec_value(msg, sp, &value)!=0)
621                 return -1;
622         ret =1;
623         if(value.flags & (PV_VAL_EMPTY|PV_VAL_NULL))
624                 ret = -1;
625         pv_value_destroy(&value);
626         return ret;
627 }
628
629 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo)
630 {
631         pv_spec_t *sp;
632
633         sp = (pv_spec_t*)pvid;
634         if(pv_set_spec_value(msg, sp, 0, NULL)<0) {
635                 LM_ERR("faile to unset variable\n");
636                 return -1;
637         }
638
639         return 1;
640 }
641
642 static int add_avp_aliases(modparam_t type, void* val)
643 {
644         if (val!=0 && ((char*)val)[0]!=0)
645         {
646                 if ( add_avp_galias_str((char*)val)!=0 )
647                         return -1;
648         }
649
650         return 0;
651 }
652
653 /**
654  * match the type of the variable value
655  */
656 static int pv_typeof(sip_msg_t *msg, char *pv, char *t)
657 {
658         pv_value_t val;
659
660         if (pv==NULL || t==NULL)
661                 return -1;
662         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
663                 return -1;
664
665         switch(t[0]) {
666                 case 'i':
667                 case 'I':
668                         if(val.flags & PV_TYPE_INT)
669                                 return 1;
670                         return -1;
671                 case 'n':
672                 case 'N':
673                         if(val.flags & PV_VAL_NULL)
674                                 return 1;
675                         return -1;
676                 case 's':
677                 case 'S':
678                         if(!(val.flags & PV_VAL_STR))
679                                 return -1;
680                         if(val.flags & PV_TYPE_INT)
681                                 return -1;
682                         return 1;
683                 default:
684                         return -1;
685         }
686 }
687
688 /**
689  * return true if the type is string and value not empty
690  */
691 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2)
692 {
693         pv_value_t val;
694
695         if (pv==NULL)
696                 return -1;
697
698         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
699                 return -1;
700
701         if(!(val.flags & PV_VAL_STR))
702                 return -1;
703         if(val.flags & PV_TYPE_INT)
704                 return -1;
705
706         if(val.rs.len>0)
707                 return 1;
708
709         return -1;
710 }
711
712 /**
713  * Copyright (C) 2011 Juha Heinanen
714  *
715  * Checks if pvar argument contains int value
716  */
717 static int is_int(struct sip_msg* msg, char* pvar, char* s2)
718 {
719         pv_spec_t *pvar_sp;
720         pv_value_t pv_val;
721
722         pvar_sp = (pv_spec_t *)pvar;
723
724         if (pvar_sp && (pv_get_spec_value(msg, pvar_sp, &pv_val) == 0)) {
725                 return (pv_val.flags & PV_VAL_INT)?1:-1;
726         }
727
728         return -1;
729 }
730
731 /**
732  * script variable to xavp
733  */
734 static int w_var_to_xavp(sip_msg_t *msg, char *s1, char *s2)
735 {
736         str xname = STR_NULL;
737         str varname = STR_NULL;
738
739         if(fixup_get_svalue(msg, (gparam_t*)s1, &varname)<0) {
740                 LM_ERR("failed to get the var name\n");
741                 return -1;
742         }
743         if(fixup_get_svalue(msg, (gparam_t*)s2, &xname)<0) {
744                 LM_ERR("failed to get the xavp name\n");
745                 return -1;
746         }
747
748         return pv_var_to_xavp(&varname, &xname);
749 }
750
751 static int ki_var_to_xavp(sip_msg_t *msg, str *varname, str *xname)
752 {
753         return pv_var_to_xavp(varname, xname);
754 }
755
756 /**
757  * xavp to script variable
758  */
759 static int w_xavp_to_var(sip_msg_t *msg, char *s1)
760 {
761         str xname = STR_NULL;
762
763         if(fixup_get_svalue(msg, (gparam_t*)s1, &xname)<0) {
764                 LM_ERR("failed to get the xavp name\n");
765                 return -1;
766         }
767
768         return pv_xavp_to_var(&xname);
769 }
770
771 static int ki_xavp_to_var(sip_msg_t *msg, str *xname)
772 {
773         return pv_xavp_to_var(xname);
774 }
775
776 static int ki_xavp_print(sip_msg_t* msg)
777 {
778         xavp_print_list(NULL);
779         return 1;
780 }
781
782 /**
783  *
784  */
785 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname)
786 {
787         str sparams;
788         str sxname;
789
790         if(fixup_get_svalue(msg, (gparam_t*)pparams, &sparams)!=0) {
791                 LM_ERR("cannot get the params\n");
792                 return -1;
793         }
794         if(fixup_get_svalue(msg, (gparam_t*)pxname, &sxname)!=0) {
795                 LM_ERR("cannot get the xavp name\n");
796                 return -1;
797         }
798
799         if(xavp_params_explode(&sparams, &sxname)<0)
800                 return -1;
801
802         return 1;
803 }
804
805 /**
806  *
807  */
808 static int ki_xavp_params_explode(sip_msg_t *msg, str *sparams, str *sxname)
809 {
810         if(xavp_params_explode(sparams, sxname)<0)
811                 return -1;
812
813         return 1;
814 }
815
816 /**
817  *
818  */
819 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2)
820 {
821         if(sbranch_set_ruri(msg)<0)
822                 return -1;
823         return 1;
824 }
825
826 /**
827  *
828  */
829 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2)
830 {
831         if(sbranch_append(msg)<0)
832                 return -1;
833         return 1;
834 }
835
836 /**
837  *
838  */
839 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2)
840 {
841         if(sbranch_reset()<0)
842                 return -1;
843         return 1;
844 }
845
846 /**
847  *
848  */
849 static int ki_sbranch_set_ruri(sip_msg_t *msg)
850 {
851         if(sbranch_set_ruri(msg)<0)
852                 return -1;
853         return 1;
854 }
855
856 /**
857  *
858  */
859 static int ki_sbranch_append(sip_msg_t *msg)
860 {
861         if(sbranch_append(msg)<0)
862                 return -1;
863         return 1;
864 }
865
866 /**
867  *
868  */
869 static int ki_sbranch_reset(sip_msg_t *msg)
870 {
871         if(sbranch_reset()<0)
872                 return -1;
873         return 1;
874 }
875
876 int pv_evalx_fixup(void** param, int param_no)
877 {
878         pv_spec_t *spec=NULL;
879         pv_elem_t *pvmodel=NULL;
880         str tstr;
881
882         if(param_no==1) {
883                 spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
884                 if(spec==NULL) {
885                         LM_ERR("out of pkg\n");
886                         return -1;
887                 }
888                 memset(spec, 0, sizeof(pv_spec_t));
889                 tstr.s = (char*)(*param);
890                 tstr.len = strlen(tstr.s);
891                 if(pv_parse_spec(&tstr, spec)==NULL) {
892                         LM_ERR("unknown script variable in first parameter\n");
893                         pkg_free(spec);
894                         return -1;
895                 }
896                 if(!pv_is_w(spec)) {
897                         LM_ERR("read-only script variable in first parameter\n");
898                         pkg_free(spec);
899                         return -1;
900                 }
901                 *param = spec;
902         } else if(param_no==2) {
903                 pvmodel = 0;
904                 tstr.s = (char*)(*param);
905                 tstr.len = strlen(tstr.s);
906                 if(pv_parse_format(&tstr, &pvmodel)<0) {
907                         LM_ERR("error in second parameter\n");
908                         return -1;
909                 }
910                 *param = pvmodel;
911         }
912         return 0;
913 }
914
915 /**
916  *
917  */
918 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt)
919 {
920         pv_spec_t *ispec=NULL;
921         pv_elem_t *imodel=NULL;
922         str tstr = {0, 0};
923         pv_value_t val;
924
925         ispec = (pv_spec_t*)dst;
926
927         imodel = (pv_elem_t*)fmt;
928
929         memset(&val, 0, sizeof(pv_value_t));
930
931         if(pv_printf_s(msg, imodel, &tstr)!=0) {
932                 LM_ERR("cannot eval second parameter\n");
933                 goto error;
934         }
935
936         if(pv_eval_str(msg, &val.rs, &tstr)<0){
937                 LM_ERR("cannot eval reparsed value of second parameter\n");
938                 return -1;
939         }
940
941         val.flags = PV_VAL_STR;
942         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
943                 LM_ERR("setting PV failed\n");
944                 goto error;
945         }
946
947         return 1;
948 error:
949         return -1;
950 }
951
952 /**
953  *
954  */
955 int ki_pv_evalx(sip_msg_t *msg, str *dst, str *fmt)
956 {
957         pv_value_t val;
958         pv_spec_t *ispec=NULL;
959
960         if(dst==NULL || dst->s==NULL || dst->len<=0) {
961                 LM_ERR("invalid destination var name\n");
962                 return -1;
963         }
964         ispec = pv_cache_get(dst);
965         if(ispec==NULL) {
966                 LM_ERR("cannot get pv spec for [%.*s]\n", dst->len, dst->s);
967                 return -1;
968         }
969
970         memset(&val, 0, sizeof(pv_value_t));
971         if(pv_eval_str(msg, &val.rs, fmt)<0) {
972                 LM_ERR("cannot eval reparsed value of second parameter\n");
973                 return -1;
974         }
975
976         val.flags = PV_VAL_STR;
977         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
978                 LM_ERR("setting PV failed\n");
979                 goto error;
980         }
981
982         return 1;
983 error:
984         return -1;
985 }
986
987 /**
988  *
989  */
990 static const char* rpc_shv_set_doc[2] = {
991         "Set a shared variable (args: name type value)",
992         0
993 };
994
995 static const char* rpc_shv_get_doc[2] = {
996         "Get the value of a shared variable. If no argument, dumps all",
997         0
998 };
999
1000 rpc_export_t pv_rpc[] = {
1001         {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
1002         {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
1003         {0, 0, 0, 0}
1004 };
1005
1006 static int pv_init_rpc(void)
1007 {
1008         if (rpc_register_array(pv_rpc)!=0)
1009         {
1010                 LM_ERR("failed to register RPC commands\n");
1011                 return -1;
1012         }
1013         return 0;
1014 }
1015
1016
1017 /**
1018  *
1019  */
1020 /* clang-format off */
1021 static sr_kemi_t sr_kemi_pvx_exports[] = {
1022         { str_init("pvx"), str_init("sbranch_set_ruri"),
1023                 SR_KEMIP_INT, ki_sbranch_set_ruri,
1024                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1025                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1026         },
1027         { str_init("pvx"), str_init("sbranch_append"),
1028                 SR_KEMIP_INT, ki_sbranch_append,
1029                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1030                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1031         },
1032         { str_init("pvx"), str_init("sbranch_reset"),
1033                 SR_KEMIP_INT, ki_sbranch_reset,
1034                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1035                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1036         },
1037         { str_init("pvx"), str_init("pv_var_to_xavp"),
1038                 SR_KEMIP_INT, ki_var_to_xavp,
1039                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1040                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1041         },
1042         { str_init("pvx"), str_init("pv_xavp_to_var"),
1043                 SR_KEMIP_INT, ki_xavp_to_var,
1044                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1045                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1046         },
1047         { str_init("pvx"), str_init("pv_xavp_print"),
1048                 SR_KEMIP_INT, ki_xavp_print,
1049                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1050                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1051         },
1052         { str_init("pvx"), str_init("xavp_params_explode"),
1053                 SR_KEMIP_INT, ki_xavp_params_explode,
1054                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1055                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1056         },
1057         { str_init("pvx"), str_init("evalx"),
1058                 SR_KEMIP_INT, ki_pv_evalx,
1059                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1060                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1061         },
1062
1063         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1064 };
1065 /* clang-format on */
1066
1067 /**
1068  *
1069  */
1070 int mod_register(char *path, int *dlflags, void *p1, void *p2)
1071 {
1072         sr_kemi_modules_add(sr_kemi_pvx_exports);
1073         if(tr_init_buffers()<0)
1074         {
1075                 LM_ERR("failed to initialize transformations buffers\n");
1076                 return -1;
1077         }
1078         return register_trans_mod(path, mod_trans);
1079 }