pv: new config variable $sas
[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         {{"sas", (sizeof("sas")-1)}, /* */
404                 PVT_OTHER, pv_get_srcaddr_socket, 0,
405                 0, 0, 0, 0},
406         {{"sf", (sizeof("sf")-1)}, /* */
407                 PVT_OTHER, pv_get_sflags, pv_set_sflags,
408                 0, 0, 0, 0},
409         {{"sF", (sizeof("sF")-1)}, /* */
410                 PVT_OTHER, pv_get_hexsflags, pv_set_sflags,
411                 0, 0, 0, 0},
412         {{"Sf", (sizeof("sf")-1)}, /* */
413                 PVT_OTHER, pv_get_sflag, pv_set_sflag,
414                 pv_parse_flag_param, 0, 0, 0},
415         {{"src_ip", (sizeof("src_ip")-1)}, /* */
416                 PVT_OTHER, pv_get_srcip, 0,
417                 0, 0, 0, 0},
418         {{"si", (sizeof("si")-1)}, /* */
419                 PVT_OTHER, pv_get_srcip, 0,
420                 0, 0, 0, 0},
421         {{"siz", (sizeof("siz")-1)}, /* */
422                 PVT_OTHER, pv_get_srcipz, 0,
423                 0, 0, 0, 0},
424         { {"sid", (sizeof("sid")-1)}, /* server id */
425                 PVT_OTHER, pv_get_server_id, 0,
426                 0, 0, 0, 0},
427         {{"sp", (sizeof("sp")-1)}, /* */
428                 PVT_OTHER, pv_get_srcport, 0,
429                 0, 0, 0, 0},
430         {{"su", (sizeof("su")-1)}, /* */
431                 PVT_OTHER, pv_get_srcaddr_uri, 0,
432                 0, 0, 0, 0},
433         {{"sut", (sizeof("sut")-1)}, /* */
434                 PVT_OTHER, pv_get_srcaddr_uri_full, 0,
435                 0, 0, 0, 0},
436         {{"td", (sizeof("td")-1)}, /* */
437                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
438                 0, 0, pv_init_iname, 3},
439         {{"to.domain", (sizeof("to.domain")-1)}, /* */
440                 PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
441                 0, 0, pv_init_iname, 3},
442         {{"tn", (sizeof("tn")-1)}, /* */
443                 PVT_OTHER, pv_get_to_attr, pv_set_to_display,
444                 0, 0, pv_init_iname, 5},
445         {{"tt", (sizeof("tt")-1)}, /* */
446                 PVT_OTHER, pv_get_to_attr, 0,
447                 0, 0, pv_init_iname, 4},
448         {{"tu", (sizeof("tu")-1)}, /* */
449                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
450                 0, 0, pv_init_iname, 1},
451         {{"to", (sizeof("to")-1)}, /* */
452                 PVT_TO, pv_get_to_attr, pv_set_to_uri,
453                 0, 0, pv_init_iname, 1},
454         {{"tU", (sizeof("tU")-1)}, /* */
455                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
456                 0, 0, pv_init_iname, 2},
457         {{"to.user", (sizeof("to.user")-1)}, /* */
458                 PVT_OTHER, pv_get_to_attr, pv_set_to_username,
459                 0, 0, pv_init_iname, 2},
460         {{"true", (sizeof("true")-1)}, /* */
461                 PVT_OTHER, pv_get_true, 0,
462                 0, 0, 0, 0},
463         {{"Tb", (sizeof("Tb")-1)}, /* */
464                 PVT_OTHER, pv_get_timeb, 0,
465                 0, 0, 0, 0},
466         {{"Tf", (sizeof("Tf")-1)}, /* */
467                 PVT_CONTEXT, pv_get_timef, 0,
468                 0, 0, 0, 0},
469         {{"TF", (sizeof("TF")-1)}, /* */
470                 PVT_OTHER, pv_get_timenowf, 0,
471                 0, 0, 0, 0},
472         {{"Ts", (sizeof("Ts")-1)}, /* */
473                 PVT_CONTEXT, pv_get_times, 0,
474                 0, 0, 0, 0},
475         {{"TS", (sizeof("TS")-1)}, /* */
476                 PVT_OTHER, pv_get_timenows, 0,
477                 0, 0, 0, 0},
478         {{"ua", (sizeof("ua")-1)}, /* */
479                 PVT_OTHER, pv_get_useragent, 0,
480                 0, 0, 0, 0},
481         {{"ruid", (sizeof("ruid")-1)}, /* */
482                 PVT_OTHER, pv_get_ruid, 0,
483                 0, 0, 0, 0},
484         {{"location_ua", (sizeof("location_ua")-1)}, /* */
485                 PVT_OTHER, pv_get_location_ua, 0,
486                 0, 0, 0, 0},
487
488         { {"shv", (sizeof("shv")-1)}, PVT_OTHER, pv_get_shvar,
489                 pv_set_shvar, pv_parse_shvar_name, 0, 0, 0},
490         { {"time", (sizeof("time")-1)}, PVT_CONTEXT, pv_get_local_time,
491                 0, pv_parse_time_name, 0, 0, 0},
492         { {"timef", (sizeof("timef")-1)}, PVT_CONTEXT, pv_get_local_strftime,
493                 0, pv_parse_strftime_name, 0, 0, 0},
494         { {"utime", (sizeof("utime")-1)}, PVT_CONTEXT, pv_get_utc_time,
495                 0, pv_parse_time_name, 0, 0, 0},
496         { {"utimef", (sizeof("utimef")-1)}, PVT_CONTEXT, pv_get_utc_strftime,
497                 0, pv_parse_strftime_name, 0, 0, 0},
498         { {"TV", (sizeof("TV")-1)}, PVT_OTHER, pv_get_timeval,
499                 0, pv_parse_timeval_name, 0, 0, 0},
500         { {"nh", (sizeof("nh")-1)}, PVT_OTHER, pv_get_nh,
501                 0, pv_parse_nh_name, 0, 0, 0},
502         { {"version", (sizeof("version")-1)}, PVT_OTHER, pv_get_sr_version,
503                 0, pv_parse_sr_version_name, 0, 0, 0},
504         { {"K", (sizeof("K")-1)}, PVT_OTHER, pv_get_K, 0,
505                 pv_parse_K_name, 0, 0, 0 },
506         { {"expires", (sizeof("expires")-1)}, PVT_OTHER, pv_get_expires, 0,
507                 pv_parse_expires_name, 0, 0, 0 },
508         { {"msg", (sizeof("msg")-1)}, PVT_OTHER, pv_get_msg_attrs, 0,
509                 pv_parse_msg_attrs_name, 0, 0, 0 },
510
511         { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
512 };
513
514 static int add_avp_aliases(modparam_t type, void* val);
515
516 static param_export_t params[]={
517         {"shvset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_shvar },
518         {"varset",              PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_var },
519         {"avp_aliases",         PARAM_STRING|USE_FUNC_PARAM, (void*)add_avp_aliases },
520         {0,0,0}
521 };
522
523 static int mod_init(void);
524 static void mod_destroy(void);
525 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo);
526 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
527 static int is_int(struct sip_msg* msg, char* pvar, char* s2);
528 static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
529 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
530 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname);
531 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2);
532 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2);
533 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2);
534 static int w_var_to_xavp(sip_msg_t *msg, char *p1, char *p2);
535 static int w_xavp_to_var(sip_msg_t *msg, char *p1);
536
537 int pv_evalx_fixup(void** param, int param_no);
538 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt);
539
540 static int pv_init_rpc(void);
541 int pv_register_api(pv_api_t*);
542
543 static cmd_export_t cmds[]={
544         {"pv_isset",  (cmd_function)pv_isset,  1, fixup_pvar_null, 0,
545                 ANY_ROUTE },
546         {"pv_unset",  (cmd_function)pv_unset,  1, fixup_pvar_null, 0,
547                 ANY_ROUTE },
548 #ifdef WITH_XAVP
549         {"pv_xavp_print",  (cmd_function)pv_xavp_print,  0, 0, 0,
550                 ANY_ROUTE },
551         {"pv_var_to_xavp",  (cmd_function)w_var_to_xavp, 2, fixup_spve_spve,
552                 fixup_free_spve_spve, ANY_ROUTE },
553         {"pv_xavp_to_var",  (cmd_function)w_xavp_to_var, 1, fixup_spve_null,
554                 fixup_free_spve_null, ANY_ROUTE },
555 #endif
556         {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, fixup_free_pvar_null,
557                 ANY_ROUTE},
558         {"typeof", (cmd_function)pv_typeof,       2, fixup_pvar_none,
559                 fixup_free_pvar_none,
560                 ANY_ROUTE},
561         {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null,
562                 fixup_free_pvar_null,
563                 ANY_ROUTE},
564         {"xavp_params_explode", (cmd_function)w_xavp_params_explode,
565                 2, fixup_spve_spve, fixup_free_spve_spve,
566                 ANY_ROUTE},
567         {"sbranch_set_ruri",  (cmd_function)w_sbranch_set_ruri,  0, 0, 0,
568                 ANY_ROUTE },
569         {"sbranch_append",    (cmd_function)w_sbranch_append,    0, 0, 0,
570                 ANY_ROUTE },
571         {"sbranch_reset",     (cmd_function)w_sbranch_reset,     0, 0, 0,
572                 ANY_ROUTE },
573         {"pv_evalx",          (cmd_function)w_pv_evalx,    2, pv_evalx_fixup,
574                 0, ANY_ROUTE },
575         /* API exports */
576         {"pv_register_api",   (cmd_function)pv_register_api,     NO_SCRIPT, 0, 0},
577         {0,0,0,0,0,0}
578 };
579
580
581
582 /** module exports */
583 struct module_exports exports= {
584         "pv",
585         DEFAULT_DLFLAGS, /* dlopen flags */
586         cmds,
587         params,
588         0,          /* exported statistics */
589         0,          /* exported MI functions */
590         mod_pvs,    /* exported pseudo-variables */
591         0,          /* extra processes */
592         mod_init,   /* module initialization function */
593         0,
594         mod_destroy,
595         0           /* per-child init function */
596 };
597
598 static int mod_init(void)
599 {
600         if(pv_init_rpc()!=0)
601         {
602                 LM_ERR("failed to register RPC commands\n");
603                 return -1;
604         }
605         pv_init_sbranch();
606
607         return 0;
608 }
609
610 static void mod_destroy(void)
611 {
612         shvar_destroy_locks();
613         destroy_shvars();
614 }
615
616 static int pv_isset(struct sip_msg* msg, char* pvid, char *foo)
617 {
618         pv_spec_t *sp;
619         pv_value_t value;
620         int ret;
621
622         sp = (pv_spec_t*)pvid;
623         if(pv_get_spec_value(msg, sp, &value)!=0)
624                 return -1;
625         ret =1;
626         if(value.flags & (PV_VAL_EMPTY|PV_VAL_NULL))
627                 ret = -1;
628         pv_value_destroy(&value);
629         return ret;
630 }
631
632 static int pv_unset(struct sip_msg* msg, char* pvid, char *foo)
633 {
634         pv_spec_t *sp;
635
636         sp = (pv_spec_t*)pvid;
637         if(pv_set_spec_value(msg, sp, 0, NULL)<0) {
638                 LM_ERR("faile to unset variable\n");
639                 return -1;
640         }
641
642         return 1;
643 }
644
645 static int add_avp_aliases(modparam_t type, void* val)
646 {
647         if (val!=0 && ((char*)val)[0]!=0)
648         {
649                 if ( add_avp_galias_str((char*)val)!=0 )
650                         return -1;
651         }
652
653         return 0;
654 }
655
656 /**
657  * match the type of the variable value
658  */
659 static int pv_typeof(sip_msg_t *msg, char *pv, char *t)
660 {
661         pv_value_t val;
662
663         if (pv==NULL || t==NULL)
664                 return -1;
665         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
666                 return -1;
667
668         switch(t[0]) {
669                 case 'i':
670                 case 'I':
671                         if(val.flags & PV_TYPE_INT)
672                                 return 1;
673                         return -1;
674                 case 'n':
675                 case 'N':
676                         if(val.flags & PV_VAL_NULL)
677                                 return 1;
678                         return -1;
679                 case 's':
680                 case 'S':
681                         if(!(val.flags & PV_VAL_STR))
682                                 return -1;
683                         if(val.flags & PV_TYPE_INT)
684                                 return -1;
685                         return 1;
686                 default:
687                         return -1;
688         }
689 }
690
691 /**
692  * return true if the type is string and value not empty
693  */
694 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2)
695 {
696         pv_value_t val;
697
698         if (pv==NULL)
699                 return -1;
700
701         if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
702                 return -1;
703
704         if(!(val.flags & PV_VAL_STR))
705                 return -1;
706         if(val.flags & PV_TYPE_INT)
707                 return -1;
708
709         if(val.rs.len>0)
710                 return 1;
711
712         return -1;
713 }
714
715 /**
716  * Copyright (C) 2011 Juha Heinanen
717  *
718  * Checks if pvar argument contains int value
719  */
720 static int is_int(struct sip_msg* msg, char* pvar, char* s2)
721 {
722         pv_spec_t *pvar_sp;
723         pv_value_t pv_val;
724
725         pvar_sp = (pv_spec_t *)pvar;
726
727         if (pvar_sp && (pv_get_spec_value(msg, pvar_sp, &pv_val) == 0)) {
728                 return (pv_val.flags & PV_VAL_INT)?1:-1;
729         }
730
731         return -1;
732 }
733
734 /**
735  * script variable to xavp
736  */
737 static int w_var_to_xavp(sip_msg_t *msg, char *s1, char *s2)
738 {
739         str xname = STR_NULL;
740         str varname = STR_NULL;
741
742         if(fixup_get_svalue(msg, (gparam_t*)s1, &varname)<0) {
743                 LM_ERR("failed to get the var name\n");
744                 return -1;
745         }
746         if(fixup_get_svalue(msg, (gparam_t*)s2, &xname)<0) {
747                 LM_ERR("failed to get the xavp name\n");
748                 return -1;
749         }
750
751         return pv_var_to_xavp(&varname, &xname);
752 }
753
754 static int ki_var_to_xavp(sip_msg_t *msg, str *varname, str *xname)
755 {
756         return pv_var_to_xavp(varname, xname);
757 }
758
759 /**
760  * xavp to script variable
761  */
762 static int w_xavp_to_var(sip_msg_t *msg, char *s1)
763 {
764         str xname = STR_NULL;
765
766         if(fixup_get_svalue(msg, (gparam_t*)s1, &xname)<0) {
767                 LM_ERR("failed to get the xavp name\n");
768                 return -1;
769         }
770
771         return pv_xavp_to_var(&xname);
772 }
773
774 static int ki_xavp_to_var(sip_msg_t *msg, str *xname)
775 {
776         return pv_xavp_to_var(xname);
777 }
778
779 static int ki_xavp_print(sip_msg_t* msg)
780 {
781         xavp_print_list(NULL);
782         return 1;
783 }
784
785 /**
786  *
787  */
788 static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname)
789 {
790         str sparams;
791         str sxname;
792
793         if(fixup_get_svalue(msg, (gparam_t*)pparams, &sparams)!=0) {
794                 LM_ERR("cannot get the params\n");
795                 return -1;
796         }
797         if(fixup_get_svalue(msg, (gparam_t*)pxname, &sxname)!=0) {
798                 LM_ERR("cannot get the xavp name\n");
799                 return -1;
800         }
801
802         if(xavp_params_explode(&sparams, &sxname)<0)
803                 return -1;
804
805         return 1;
806 }
807
808 /**
809  *
810  */
811 static int ki_xavp_params_explode(sip_msg_t *msg, str *sparams, str *sxname)
812 {
813         if(xavp_params_explode(sparams, sxname)<0)
814                 return -1;
815
816         return 1;
817 }
818
819 /**
820  *
821  */
822 static int w_sbranch_set_ruri(sip_msg_t *msg, char p1, char *p2)
823 {
824         if(sbranch_set_ruri(msg)<0)
825                 return -1;
826         return 1;
827 }
828
829 /**
830  *
831  */
832 static int w_sbranch_append(sip_msg_t *msg, char p1, char *p2)
833 {
834         if(sbranch_append(msg)<0)
835                 return -1;
836         return 1;
837 }
838
839 /**
840  *
841  */
842 static int w_sbranch_reset(sip_msg_t *msg, char p1, char *p2)
843 {
844         if(sbranch_reset()<0)
845                 return -1;
846         return 1;
847 }
848
849 /**
850  *
851  */
852 static int ki_sbranch_set_ruri(sip_msg_t *msg)
853 {
854         if(sbranch_set_ruri(msg)<0)
855                 return -1;
856         return 1;
857 }
858
859 /**
860  *
861  */
862 static int ki_sbranch_append(sip_msg_t *msg)
863 {
864         if(sbranch_append(msg)<0)
865                 return -1;
866         return 1;
867 }
868
869 /**
870  *
871  */
872 static int ki_sbranch_reset(sip_msg_t *msg)
873 {
874         if(sbranch_reset()<0)
875                 return -1;
876         return 1;
877 }
878
879 int pv_evalx_fixup(void** param, int param_no)
880 {
881         pv_spec_t *spec=NULL;
882         pv_elem_t *pvmodel=NULL;
883         str tstr;
884
885         if(param_no==1) {
886                 spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
887                 if(spec==NULL) {
888                         LM_ERR("out of pkg\n");
889                         return -1;
890                 }
891                 memset(spec, 0, sizeof(pv_spec_t));
892                 tstr.s = (char*)(*param);
893                 tstr.len = strlen(tstr.s);
894                 if(pv_parse_spec(&tstr, spec)==NULL) {
895                         LM_ERR("unknown script variable in first parameter\n");
896                         pkg_free(spec);
897                         return -1;
898                 }
899                 if(!pv_is_w(spec)) {
900                         LM_ERR("read-only script variable in first parameter\n");
901                         pkg_free(spec);
902                         return -1;
903                 }
904                 *param = spec;
905         } else if(param_no==2) {
906                 pvmodel = 0;
907                 tstr.s = (char*)(*param);
908                 tstr.len = strlen(tstr.s);
909                 if(pv_parse_format(&tstr, &pvmodel)<0) {
910                         LM_ERR("error in second parameter\n");
911                         return -1;
912                 }
913                 *param = pvmodel;
914         }
915         return 0;
916 }
917
918 /**
919  *
920  */
921 int w_pv_evalx(struct sip_msg *msg, char *dst, str *fmt)
922 {
923         pv_spec_t *ispec=NULL;
924         pv_elem_t *imodel=NULL;
925         str tstr = {0, 0};
926         pv_value_t val;
927
928         ispec = (pv_spec_t*)dst;
929
930         imodel = (pv_elem_t*)fmt;
931
932         memset(&val, 0, sizeof(pv_value_t));
933
934         if(pv_printf_s(msg, imodel, &tstr)!=0) {
935                 LM_ERR("cannot eval second parameter\n");
936                 goto error;
937         }
938
939         if(pv_eval_str(msg, &val.rs, &tstr)<0){
940                 LM_ERR("cannot eval reparsed value of second parameter\n");
941                 return -1;
942         }
943
944         val.flags = PV_VAL_STR;
945         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
946                 LM_ERR("setting PV failed\n");
947                 goto error;
948         }
949
950         return 1;
951 error:
952         return -1;
953 }
954
955 /**
956  *
957  */
958 int ki_pv_evalx(sip_msg_t *msg, str *dst, str *fmt)
959 {
960         pv_value_t val;
961         pv_spec_t *ispec=NULL;
962
963         if(dst==NULL || dst->s==NULL || dst->len<=0) {
964                 LM_ERR("invalid destination var name\n");
965                 return -1;
966         }
967         ispec = pv_cache_get(dst);
968         if(ispec==NULL) {
969                 LM_ERR("cannot get pv spec for [%.*s]\n", dst->len, dst->s);
970                 return -1;
971         }
972
973         memset(&val, 0, sizeof(pv_value_t));
974         if(pv_eval_str(msg, &val.rs, fmt)<0) {
975                 LM_ERR("cannot eval reparsed value of second parameter\n");
976                 return -1;
977         }
978
979         val.flags = PV_VAL_STR;
980         if(ispec->setf(msg, &ispec->pvp, EQ_T, &val)<0) {
981                 LM_ERR("setting PV failed\n");
982                 goto error;
983         }
984
985         return 1;
986 error:
987         return -1;
988 }
989
990 /**
991  *
992  */
993 static const char* rpc_shv_set_doc[2] = {
994         "Set a shared variable (args: name type value)",
995         0
996 };
997
998 static const char* rpc_shv_get_doc[2] = {
999         "Get the value of a shared variable. If no argument, dumps all",
1000         0
1001 };
1002
1003 rpc_export_t pv_rpc[] = {
1004         {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
1005         {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
1006         {0, 0, 0, 0}
1007 };
1008
1009 static int pv_init_rpc(void)
1010 {
1011         if (rpc_register_array(pv_rpc)!=0)
1012         {
1013                 LM_ERR("failed to register RPC commands\n");
1014                 return -1;
1015         }
1016         return 0;
1017 }
1018
1019
1020 /**
1021  *
1022  */
1023 /* clang-format off */
1024 static sr_kemi_t sr_kemi_pvx_exports[] = {
1025         { str_init("pvx"), str_init("sbranch_set_ruri"),
1026                 SR_KEMIP_INT, ki_sbranch_set_ruri,
1027                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1028                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1029         },
1030         { str_init("pvx"), str_init("sbranch_append"),
1031                 SR_KEMIP_INT, ki_sbranch_append,
1032                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1033                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1034         },
1035         { str_init("pvx"), str_init("sbranch_reset"),
1036                 SR_KEMIP_INT, ki_sbranch_reset,
1037                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1038                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1039         },
1040         { str_init("pvx"), str_init("pv_var_to_xavp"),
1041                 SR_KEMIP_INT, ki_var_to_xavp,
1042                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1043                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1044         },
1045         { str_init("pvx"), str_init("pv_xavp_to_var"),
1046                 SR_KEMIP_INT, ki_xavp_to_var,
1047                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1048                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1049         },
1050         { str_init("pvx"), str_init("pv_xavp_print"),
1051                 SR_KEMIP_INT, ki_xavp_print,
1052                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1053                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1054         },
1055         { str_init("pvx"), str_init("xavp_params_explode"),
1056                 SR_KEMIP_INT, ki_xavp_params_explode,
1057                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1058                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1059         },
1060         { str_init("pvx"), str_init("evalx"),
1061                 SR_KEMIP_INT, ki_pv_evalx,
1062                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1063                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1064         },
1065
1066         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1067 };
1068 /* clang-format on */
1069
1070 /**
1071  *
1072  */
1073 int mod_register(char *path, int *dlflags, void *p1, void *p2)
1074 {
1075         sr_kemi_modules_add(sr_kemi_pvx_exports);
1076         if(tr_init_buffers()<0)
1077         {
1078                 LM_ERR("failed to initialize transformations buffers\n");
1079                 return -1;
1080         }
1081         return register_trans_mod(path, mod_trans);
1082 }