pv.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /**
  2. * $Id$
  3. *
  4. * Copyright (C) 2008 Daniel-Constantin Mierla (asipto.com)
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include "../../sr_module.h"
  26. #include "../../pvar.h"
  27. #include "../../mod_fix.h"
  28. #include "../../lib/kmi/mi.h"
  29. #include "../../rpc.h"
  30. #include "../../rpc_lookup.h"
  31. #include "pv_branch.h"
  32. #include "pv_core.h"
  33. #include "pv_stats.h"
  34. #include "pv_shv.h"
  35. #include "pv_time.h"
  36. #include "pv_trans.h"
  37. #include "pv_select.h"
  38. #ifdef WITH_XAVP
  39. #include "pv_xavp.h"
  40. #endif
  41. MODULE_VERSION
  42. static tr_export_t mod_trans[] = {
  43. { {"s", sizeof("s")-1}, /* string class */
  44. tr_parse_string },
  45. { {"nameaddr", sizeof("nameaddr")-1}, /* nameaddr class */
  46. tr_parse_nameaddr },
  47. { {"uri", sizeof("uri")-1}, /* uri class */
  48. tr_parse_uri },
  49. { {"param", sizeof("param")-1}, /* param class */
  50. tr_parse_paramlist },
  51. { {"tobody", sizeof("tobody")-1}, /* param class */
  52. tr_parse_tobody },
  53. { {"line", sizeof("line")-1}, /* line class */
  54. tr_parse_line },
  55. { { 0, 0 }, 0 }
  56. };
  57. static pv_export_t mod_pvs[] = {
  58. { {"_s", (sizeof("_s")-1)}, PVT_OTHER, pv_get__s, 0,
  59. pv_parse__s_name, 0, 0, 0 },
  60. { {"af", (sizeof("af")-1)}, PVT_OTHER, pv_get_af, 0,
  61. pv_parse_af_name, 0, 0, 0 },
  62. { {"branch", sizeof("branch")-1}, /* branch attributes */
  63. PVT_CONTEXT, pv_get_branchx, pv_set_branchx,
  64. pv_parse_branchx_name, pv_parse_index, 0, 0 },
  65. { {"mi", (sizeof("mi")-1)}, /* message id */
  66. PVT_OTHER, pv_get_msgid, 0,
  67. 0, 0, 0, 0},
  68. { {"stat", sizeof("stat")-1}, /* statistics */
  69. PVT_OTHER, pv_get_stat, 0,
  70. pv_parse_stat_name, 0, 0, 0 },
  71. { {"sel", sizeof("sel")-1}, /* select */
  72. PVT_OTHER, pv_get_select, 0,
  73. pv_parse_select_name, 0, 0, 0 },
  74. { {"snd", (sizeof("snd")-1)}, PVT_OTHER, pv_get_sndto, 0,
  75. pv_parse_snd_name, 0, 0, 0 },
  76. { {"sndto", (sizeof("sndto")-1)}, PVT_OTHER, pv_get_sndto, 0,
  77. pv_parse_snd_name, 0, 0, 0 },
  78. { {"sndfrom", (sizeof("sndfrom")-1)}, PVT_OTHER, pv_get_sndfrom, 0,
  79. pv_parse_snd_name, 0, 0, 0 },
  80. #ifdef WITH_XAVP
  81. { {"xavp", sizeof("xavp")-1}, /* xavp */
  82. PVT_XAVP, pv_get_xavp, pv_set_xavp,
  83. pv_parse_xavp_name, 0, 0, 0 },
  84. #endif
  85. {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp,
  86. pv_parse_avp_name, pv_parse_index, 0, 0},
  87. {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name,
  88. pv_parse_index, 0, 0},
  89. {{"var", (sizeof("var")-1)}, PVT_SCRIPTVAR, pv_get_scriptvar,
  90. pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0},
  91. {{"ai", (sizeof("ai")-1)}, /* */
  92. PVT_OTHER, pv_get_pai, 0,
  93. 0, pv_parse_index, 0, 0},
  94. {{"adu", (sizeof("adu")-1)}, /* auth digest uri */
  95. PVT_OTHER, pv_get_authattr, 0,
  96. 0, 0, pv_init_iname, 3},
  97. {{"ar", (sizeof("ar")-1)}, /* auth realm */
  98. PVT_OTHER, pv_get_authattr, 0,
  99. 0, 0, pv_init_iname, 2},
  100. {{"au", (sizeof("au")-1)}, /* */
  101. PVT_OTHER, pv_get_authattr, 0,
  102. 0, 0, pv_init_iname, 1},
  103. {{"ad", (sizeof("ad")-1)}, /* */
  104. PVT_OTHER, pv_get_authattr, 0,
  105. 0, 0, pv_init_iname, 4},
  106. {{"aU", (sizeof("aU")-1)}, /* */
  107. PVT_OTHER, pv_get_authattr, 0,
  108. 0, 0, pv_init_iname, 5},
  109. {{"aa", (sizeof("aa")-1)}, /* auth algorithm */
  110. PVT_OTHER, pv_get_authattr, 0,
  111. 0, 0, pv_init_iname, 6},
  112. {{"Au", (sizeof("Au")-1)}, /* */
  113. PVT_OTHER, pv_get_acc_username, 0,
  114. 0, 0, pv_init_iname, 1},
  115. {{"bf", (sizeof("bf")-1)}, /* */
  116. PVT_CONTEXT, pv_get_bflags, pv_set_bflags,
  117. 0, 0, 0, 0},
  118. {{"bF", (sizeof("bF")-1)}, /* */
  119. PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags,
  120. 0, 0, 0, 0},
  121. {{"Bf", (sizeof("Bf")-1)}, /* */
  122. PVT_CONTEXT, pv_get_bflag, pv_set_bflag,
  123. pv_parse_flag_param, 0, 0, 0},
  124. {{"br", (sizeof("br")-1)}, /* */
  125. PVT_BRANCH, pv_get_branch, pv_set_branch,
  126. 0, 0, 0, 0},
  127. {{"bR", (sizeof("bR")-1)}, /* */
  128. PVT_CONTEXT, pv_get_branches, 0,
  129. 0, 0, 0, 0},
  130. {{"bs", (sizeof("bs")-1)}, /* */
  131. PVT_OTHER, pv_get_body_size, 0,
  132. 0, 0, 0, 0},
  133. {{"ci", (sizeof("ci")-1)}, /* */
  134. PVT_OTHER, pv_get_callid, 0,
  135. 0, 0, 0, 0},
  136. {{"cl", (sizeof("cl")-1)}, /* */
  137. PVT_OTHER, pv_get_content_length, 0,
  138. 0, 0, 0, 0},
  139. {{"cnt", sizeof("cnt")-1},
  140. PVT_OTHER, pv_get_cnt, 0,
  141. pv_parse_cnt_name, 0, 0, 0 },
  142. {{"conid", (sizeof("conid")-1)}, /* */
  143. PVT_OTHER, pv_get_tcpconn_id, 0,
  144. 0, 0, 0, 0},
  145. {{"cs", (sizeof("cs")-1)}, /* */
  146. PVT_OTHER, pv_get_cseq, 0,
  147. 0, 0, 0, 0},
  148. {{"ct", (sizeof("ct")-1)}, /* */
  149. PVT_OTHER, pv_get_contact, 0,
  150. 0, 0, 0, 0},
  151. {{"cT", (sizeof("cT")-1)}, /* */
  152. PVT_OTHER, pv_get_content_type, 0,
  153. 0, 0, 0, 0},
  154. {{"dd", (sizeof("dd")-1)}, /* */
  155. PVT_OTHER, pv_get_dsturi_attr, 0,
  156. 0, 0, pv_init_iname, 1},
  157. {{"di", (sizeof("di")-1)}, /* */
  158. PVT_OTHER, pv_get_diversion, 0,
  159. 0, 0, pv_init_iname, 1},
  160. {{"dir", (sizeof("dir")-1)}, /* */
  161. PVT_OTHER, pv_get_diversion, 0,
  162. 0, 0, pv_init_iname, 2},
  163. {{"dip", (sizeof("dis")-1)}, /* */
  164. PVT_OTHER, pv_get_diversion, 0,
  165. 0, 0, pv_init_iname, 3},
  166. {{"dic", (sizeof("dic")-1)}, /* */
  167. PVT_OTHER, pv_get_diversion, 0,
  168. 0, 0, pv_init_iname, 4},
  169. {{"dp", (sizeof("dp")-1)}, /* */
  170. PVT_OTHER, pv_get_dsturi_attr, 0,
  171. 0, 0, pv_init_iname, 2},
  172. {{"dP", (sizeof("dP")-1)}, /* */
  173. PVT_OTHER, pv_get_dsturi_attr, 0,
  174. 0, 0, pv_init_iname, 3},
  175. {{"ds", (sizeof("ds")-1)}, /* */
  176. PVT_CONTEXT, pv_get_dset, 0,
  177. 0, 0, 0, 0},
  178. {{"du", (sizeof("du")-1)}, /* */
  179. PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
  180. 0, 0, 0, 0},
  181. {{"duri", (sizeof("duri")-1)}, /* */
  182. PVT_DSTURI, pv_get_dsturi, pv_set_dsturi,
  183. 0, 0, 0, 0},
  184. {{"err.class", (sizeof("err.class")-1)}, /* */
  185. PVT_OTHER, pv_get_errinfo_attr, 0,
  186. 0, 0, 0, 0},
  187. {{"err.level", (sizeof("err.level")-1)}, /* */
  188. PVT_OTHER, pv_get_errinfo_attr, 0,
  189. 0, 0, pv_init_iname, 1},
  190. {{"err.info", (sizeof("err.info")-1)}, /* */
  191. PVT_OTHER, pv_get_errinfo_attr, 0,
  192. 0, 0, pv_init_iname, 2},
  193. {{"err.rcode", (sizeof("err.rcode")-1)}, /* */
  194. PVT_OTHER, pv_get_errinfo_attr, 0,
  195. 0, 0, pv_init_iname, 3},
  196. {{"err.rreason", (sizeof("err.rreason")-1)}, /* */
  197. PVT_OTHER, pv_get_errinfo_attr, 0,
  198. 0, 0, pv_init_iname, 4},
  199. {{"fd", (sizeof("fd")-1)}, /* */
  200. PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
  201. 0, 0, pv_init_iname, 3},
  202. {{"from.domain", (sizeof("from.domain")-1)}, /* */
  203. PVT_OTHER, pv_get_from_attr, pv_set_from_domain,
  204. 0, 0, pv_init_iname, 3},
  205. {{"fn", (sizeof("fn")-1)}, /* */
  206. PVT_OTHER, pv_get_from_attr, pv_set_from_display,
  207. 0, 0, pv_init_iname, 5},
  208. {{"fs", (sizeof("fs")-1)}, /* */
  209. PVT_OTHER, pv_get_force_sock, pv_set_force_sock,
  210. 0, 0, 0, 0},
  211. {{"ft", (sizeof("ft")-1)}, /* */
  212. PVT_OTHER, pv_get_from_attr, 0,
  213. 0, 0, pv_init_iname, 4},
  214. {{"fu", (sizeof("fu")-1)}, /* */
  215. PVT_FROM, pv_get_from_attr, pv_set_from_uri,
  216. 0, 0, pv_init_iname, 1},
  217. {{"from", (sizeof("from")-1)}, /* */
  218. PVT_FROM, pv_get_from_attr, pv_set_from_uri,
  219. 0, 0, pv_init_iname, 1},
  220. {{"fU", (sizeof("fU")-1)}, /* */
  221. PVT_OTHER, pv_get_from_attr, pv_set_from_username,
  222. 0, 0, pv_init_iname, 2},
  223. {{"from.user", (sizeof("from.user")-1)}, /* */
  224. PVT_OTHER, pv_get_from_attr, pv_set_from_username,
  225. 0, 0, pv_init_iname, 2},
  226. {{"mb", (sizeof("mb")-1)}, /* */
  227. PVT_OTHER, pv_get_msg_buf, 0,
  228. 0, 0, 0, 0},
  229. {{"mf", (sizeof("mf")-1)}, /* */
  230. PVT_OTHER, pv_get_flags, pv_set_mflags,
  231. 0, 0, 0, 0},
  232. {{"mF", (sizeof("mF")-1)}, /* */
  233. PVT_OTHER, pv_get_hexflags, pv_set_mflags,
  234. 0, 0, 0, 0},
  235. {{"Mf", (sizeof("mf")-1)}, /* */
  236. PVT_OTHER, pv_get_flag, pv_set_mflag,
  237. pv_parse_flag_param, 0, 0, 0},
  238. {{"ml", (sizeof("ml")-1)}, /* */
  239. PVT_OTHER, pv_get_msg_len, 0,
  240. 0, 0, 0, 0},
  241. {{"mt", (sizeof("mt")-1)}, /* */
  242. PVT_OTHER, pv_get_msgtype, 0,
  243. 0, 0, 0, 0},
  244. {{"od", (sizeof("od")-1)}, /* */
  245. PVT_OTHER, pv_get_ouri_attr, 0,
  246. 0, 0, pv_init_iname, 2},
  247. {{"op", (sizeof("op")-1)}, /* */
  248. PVT_OTHER, pv_get_ouri_attr, 0,
  249. 0, 0, pv_init_iname, 3},
  250. {{"oP", (sizeof("oP")-1)}, /* */
  251. PVT_OTHER, pv_get_ouri_attr, 0,
  252. 0, 0, pv_init_iname, 4},
  253. {{"ou", (sizeof("ou")-1)}, /* */
  254. PVT_OURI, pv_get_ouri, 0,
  255. 0, 0, 0, 0},
  256. {{"ouri", (sizeof("ouri")-1)}, /* */
  257. PVT_OURI, pv_get_ouri, 0,
  258. 0, 0, 0, 0},
  259. {{"oU", (sizeof("oU")-1)}, /* */
  260. PVT_OTHER, pv_get_ouri_attr, 0,
  261. 0, 0, pv_init_iname, 1},
  262. {{"pd", (sizeof("pd")-1)}, /* */
  263. PVT_OTHER, pv_get_ppi_attr, 0,
  264. 0, pv_parse_index, pv_init_iname, 3},
  265. {{"pn", (sizeof("pn")-1)}, /* */
  266. PVT_OTHER, pv_get_ppi_attr, 0,
  267. 0, pv_parse_index, pv_init_iname, 4},
  268. {{"pp", (sizeof("pp")-1)}, /* */
  269. PVT_OTHER, pv_get_pid, 0,
  270. 0, 0, 0, 0},
  271. {{"pr", (sizeof("pr")-1)}, /* */
  272. PVT_OTHER, pv_get_proto, 0,
  273. 0, 0, 0, 0},
  274. {{"proto", (sizeof("proto")-1)}, /* */
  275. PVT_OTHER, pv_get_proto, 0,
  276. 0, 0, 0, 0},
  277. {{"pu", (sizeof("pu")-1)}, /* */
  278. PVT_OTHER, pv_get_ppi_attr, 0,
  279. 0, pv_parse_index, pv_init_iname, 1},
  280. {{"pU", (sizeof("pU")-1)}, /* */
  281. PVT_OTHER, pv_get_ppi_attr, 0,
  282. 0, pv_parse_index, pv_init_iname, 2},
  283. {{"rb", (sizeof("rb")-1)}, /* */
  284. PVT_MSG_BODY, pv_get_msg_body, 0,
  285. 0, 0, 0, 0},
  286. /* {{"rc", (sizeof("rc")-1)},
  287. PVT_OTHER, pv_get_return_code, 0,
  288. 0, 0, 0, 0},
  289. {{"retcode", (sizeof("retcode")-1)},
  290. PVT_OTHER, pv_get_return_code, 0,
  291. 0, 0, 0, 0}, */
  292. {{"rd", (sizeof("rd")-1)}, /* */
  293. PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
  294. 0, 0, pv_init_iname, 2},
  295. {{"ruri.domain", (sizeof("ruri.domain")-1)}, /* */
  296. PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host,
  297. 0, 0, pv_init_iname, 2},
  298. {{"re", (sizeof("re")-1)}, /* */
  299. PVT_OTHER, pv_get_rpid, 0,
  300. 0, 0, 0, 0},
  301. {{"rm", (sizeof("rm")-1)}, /* */
  302. PVT_OTHER, pv_get_method, 0,
  303. 0, 0, 0, 0},
  304. {{"rmid", (sizeof("rmid")-1)}, /* */
  305. PVT_OTHER, pv_get_methodid, 0,
  306. 0, 0, 0, 0},
  307. {{"rp", (sizeof("rp")-1)}, /* */
  308. PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port,
  309. 0, 0, pv_init_iname, 3},
  310. {{"rP", (sizeof("rP")-1)}, /* */
  311. PVT_OTHER, pv_get_ruri_attr, 0,
  312. 0, 0, pv_init_iname, 4},
  313. {{"rr", (sizeof("rr")-1)}, /* */
  314. PVT_OTHER, pv_get_reason, 0,
  315. 0, 0, 0, 0},
  316. {{"rs", (sizeof("rs")-1)}, /* */
  317. PVT_OTHER, pv_get_status, 0,
  318. 0, 0, 0, 0},
  319. {{"rt", (sizeof("rt")-1)}, /* */
  320. PVT_OTHER, pv_get_refer_to, 0,
  321. 0, 0, 0, 0},
  322. {{"ru", (sizeof("ru")-1)}, /* */
  323. PVT_RURI, pv_get_ruri, pv_set_ruri,
  324. 0, 0, 0, 0},
  325. {{"ruri", (sizeof("ruri")-1)}, /* */
  326. PVT_RURI, pv_get_ruri, pv_set_ruri,
  327. 0, 0, 0, 0},
  328. {{"rU", (sizeof("rU")-1)}, /* */
  329. PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
  330. 0, 0, pv_init_iname, 1},
  331. {{"ruri.user", (sizeof("ruri.user")-1)}, /* */
  332. PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user,
  333. 0, 0, pv_init_iname, 1},
  334. {{"rv", (sizeof("rv")-1)}, /* */
  335. PVT_OTHER, pv_get_version, 0,
  336. 0, 0, 0, 0},
  337. {{"rz", (sizeof("rz")-1)}, /* */
  338. PVT_OTHER, pv_get_ruri_attr, 0,
  339. 0, 0, pv_init_iname, 5},
  340. {{"Ri", (sizeof("Ri")-1)}, /* */
  341. PVT_OTHER, pv_get_rcvip, 0,
  342. 0, 0, 0, 0},
  343. {{"Rp", (sizeof("Rp")-1)}, /* */
  344. PVT_OTHER, pv_get_rcvport, 0,
  345. 0, 0, 0, 0},
  346. {{"sf", (sizeof("sf")-1)}, /* */
  347. PVT_OTHER, pv_get_sflags, pv_set_sflags,
  348. 0, 0, 0, 0},
  349. {{"sF", (sizeof("sF")-1)}, /* */
  350. PVT_OTHER, pv_get_hexsflags, pv_set_sflags,
  351. 0, 0, 0, 0},
  352. {{"Sf", (sizeof("sf")-1)}, /* */
  353. PVT_OTHER, pv_get_sflag, pv_set_sflag,
  354. pv_parse_flag_param, 0, 0, 0},
  355. {{"src_ip", (sizeof("src_ip")-1)}, /* */
  356. PVT_OTHER, pv_get_srcip, 0,
  357. 0, 0, 0, 0},
  358. {{"si", (sizeof("si")-1)}, /* */
  359. PVT_OTHER, pv_get_srcip, 0,
  360. 0, 0, 0, 0},
  361. { {"sid", (sizeof("sid")-1)}, /* server id */
  362. PVT_OTHER, pv_get_server_id, 0,
  363. 0, 0, 0, 0},
  364. {{"sp", (sizeof("sp")-1)}, /* */
  365. PVT_OTHER, pv_get_srcport, 0,
  366. 0, 0, 0, 0},
  367. {{"su", (sizeof("su")-1)}, /* */
  368. PVT_OTHER, pv_get_srcaddr_uri, 0,
  369. 0, 0, 0, 0},
  370. {{"td", (sizeof("td")-1)}, /* */
  371. PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
  372. 0, 0, pv_init_iname, 3},
  373. {{"to.domain", (sizeof("to.domain")-1)}, /* */
  374. PVT_OTHER, pv_get_to_attr, pv_set_to_domain,
  375. 0, 0, pv_init_iname, 3},
  376. {{"tn", (sizeof("tn")-1)}, /* */
  377. PVT_OTHER, pv_get_to_attr, pv_set_to_display,
  378. 0, 0, pv_init_iname, 5},
  379. {{"tt", (sizeof("tt")-1)}, /* */
  380. PVT_OTHER, pv_get_to_attr, 0,
  381. 0, 0, pv_init_iname, 4},
  382. {{"tu", (sizeof("tu")-1)}, /* */
  383. PVT_TO, pv_get_to_attr, pv_set_to_uri,
  384. 0, 0, pv_init_iname, 1},
  385. {{"to", (sizeof("to")-1)}, /* */
  386. PVT_TO, pv_get_to_attr, pv_set_to_uri,
  387. 0, 0, pv_init_iname, 1},
  388. {{"tU", (sizeof("tU")-1)}, /* */
  389. PVT_OTHER, pv_get_to_attr, pv_set_to_username,
  390. 0, 0, pv_init_iname, 2},
  391. {{"to.user", (sizeof("to.user")-1)}, /* */
  392. PVT_OTHER, pv_get_to_attr, pv_set_to_username,
  393. 0, 0, pv_init_iname, 2},
  394. {{"true", (sizeof("true")-1)}, /* */
  395. PVT_OTHER, pv_get_true, 0,
  396. 0, 0, 0, 0},
  397. {{"Tb", (sizeof("Tb")-1)}, /* */
  398. PVT_OTHER, pv_get_timeb, 0,
  399. 0, 0, 0, 0},
  400. {{"Tf", (sizeof("Tf")-1)}, /* */
  401. PVT_CONTEXT, pv_get_timef, 0,
  402. 0, 0, 0, 0},
  403. {{"TF", (sizeof("TF")-1)}, /* */
  404. PVT_OTHER, pv_get_timenowf, 0,
  405. 0, 0, 0, 0},
  406. {{"Ts", (sizeof("Ts")-1)}, /* */
  407. PVT_CONTEXT, pv_get_times, 0,
  408. 0, 0, 0, 0},
  409. {{"TS", (sizeof("TS")-1)}, /* */
  410. PVT_OTHER, pv_get_timenows, 0,
  411. 0, 0, 0, 0},
  412. {{"ua", (sizeof("ua")-1)}, /* */
  413. PVT_OTHER, pv_get_useragent, 0,
  414. 0, 0, 0, 0},
  415. {{"ruid", (sizeof("ruid")-1)}, /* */
  416. PVT_OTHER, pv_get_ruid, 0,
  417. 0, 0, 0, 0},
  418. {{"location_ua", (sizeof("location_ua")-1)}, /* */
  419. PVT_OTHER, pv_get_location_ua, 0,
  420. 0, 0, 0, 0},
  421. { {"shv", (sizeof("shv")-1)}, PVT_OTHER, pv_get_shvar,
  422. pv_set_shvar, pv_parse_shvar_name, 0, 0, 0},
  423. { {"time", (sizeof("time")-1)}, PVT_CONTEXT, pv_get_time,
  424. 0, pv_parse_time_name, 0, 0, 0},
  425. { {"timef", (sizeof("timef")-1)}, PVT_CONTEXT, pv_get_strftime,
  426. 0, pv_parse_strftime_name, 0, 0, 0},
  427. { {"TV", (sizeof("TV")-1)}, PVT_OTHER, pv_get_timeval,
  428. 0, pv_parse_timeval_name, 0, 0, 0},
  429. { {"nh", (sizeof("nh")-1)}, PVT_OTHER, pv_get_nh,
  430. 0, pv_parse_nh_name, 0, 0, 0},
  431. { {"version", (sizeof("version")-1)}, PVT_OTHER, pv_get_sr_version,
  432. 0, pv_parse_sr_version_name, 0, 0, 0},
  433. { {"K", (sizeof("K")-1)}, PVT_OTHER, pv_get_K, 0,
  434. pv_parse_K_name, 0, 0, 0 },
  435. { {"expires", (sizeof("expires")-1)}, PVT_OTHER, pv_get_expires, 0,
  436. pv_parse_expires_name, 0, 0, 0 },
  437. { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
  438. };
  439. static int add_avp_aliases(modparam_t type, void* val);
  440. static param_export_t params[]={
  441. {"shvset", PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_shvar },
  442. {"varset", PARAM_STRING|USE_FUNC_PARAM, (void*)param_set_var },
  443. {"avp_aliases", PARAM_STRING|USE_FUNC_PARAM, (void*)add_avp_aliases },
  444. {0,0,0}
  445. };
  446. static mi_export_t mi_cmds[] = {
  447. { "shv_get", mi_shvar_get, 0, 0, 0 },
  448. { "shv_set" , mi_shvar_set, 0, 0, 0 },
  449. { 0, 0, 0, 0, 0}
  450. };
  451. static int mod_init(void);
  452. static void mod_destroy(void);
  453. static int pv_isset(struct sip_msg* msg, char* pvid, char *foo);
  454. static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
  455. static int is_int(struct sip_msg* msg, char* pvar, char* s2);
  456. static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
  457. static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
  458. static int pv_init_rpc(void);
  459. static cmd_export_t cmds[]={
  460. {"pv_isset", (cmd_function)pv_isset, 1, fixup_pvar_null, 0,
  461. ANY_ROUTE },
  462. {"pv_unset", (cmd_function)pv_unset, 1, fixup_pvar_null, 0,
  463. ANY_ROUTE },
  464. #ifdef WITH_XAVP
  465. {"pv_xavp_print", (cmd_function)pv_xavp_print, 0, 0, 0,
  466. ANY_ROUTE },
  467. #endif
  468. {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, fixup_free_pvar_null,
  469. ANY_ROUTE},
  470. {"typeof", (cmd_function)pv_typeof, 2, fixup_pvar_none,
  471. fixup_free_pvar_none,
  472. ANY_ROUTE},
  473. {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null,
  474. fixup_free_pvar_null,
  475. ANY_ROUTE},
  476. {0,0,0,0,0,0}
  477. };
  478. /** module exports */
  479. struct module_exports exports= {
  480. "pv",
  481. DEFAULT_DLFLAGS, /* dlopen flags */
  482. cmds,
  483. params,
  484. 0, /* exported statistics */
  485. mi_cmds, /* exported MI functions */
  486. mod_pvs, /* exported pseudo-variables */
  487. 0, /* extra processes */
  488. mod_init, /* module initialization function */
  489. 0,
  490. mod_destroy,
  491. 0 /* per-child init function */
  492. };
  493. static int mod_init(void)
  494. {
  495. if(register_mi_mod(exports.name, mi_cmds)!=0)
  496. {
  497. LM_ERR("failed to register MI commands\n");
  498. return -1;
  499. }
  500. if(pv_init_rpc()!=0)
  501. {
  502. LM_ERR("failed to register RPC commands\n");
  503. return -1;
  504. }
  505. return 0;
  506. }
  507. static void mod_destroy(void)
  508. {
  509. shvar_destroy_locks();
  510. destroy_shvars();
  511. }
  512. int mod_register(char *path, int *dlflags, void *p1, void *p2)
  513. {
  514. if(tr_init_buffers()<0)
  515. {
  516. LM_ERR("failed to initialize transformations buffers\n");
  517. return -1;
  518. }
  519. return register_trans_mod(path, mod_trans);
  520. }
  521. static int pv_isset(struct sip_msg* msg, char* pvid, char *foo)
  522. {
  523. pv_spec_t *sp;
  524. pv_value_t value;
  525. int ret;
  526. sp = (pv_spec_t*)pvid;
  527. if(pv_get_spec_value(msg, sp, &value)!=0)
  528. return -1;
  529. ret =1;
  530. if(value.flags & (PV_VAL_EMPTY|PV_VAL_NULL))
  531. ret = -1;
  532. pv_value_destroy(&value);
  533. return ret;
  534. }
  535. static int pv_unset(struct sip_msg* msg, char* pvid, char *foo)
  536. {
  537. pv_spec_t *sp;
  538. sp = (pv_spec_t*)pvid;
  539. pv_set_spec_value(msg, sp, 0, NULL);
  540. return 1;
  541. }
  542. static int add_avp_aliases(modparam_t type, void* val)
  543. {
  544. if (val!=0 && ((char*)val)[0]!=0)
  545. {
  546. if ( add_avp_galias_str((char*)val)!=0 )
  547. return -1;
  548. }
  549. return 0;
  550. }
  551. /**
  552. * match the type of the variable value
  553. */
  554. static int pv_typeof(sip_msg_t *msg, char *pv, char *t)
  555. {
  556. pv_value_t val;
  557. if (pv==NULL || t==NULL)
  558. return -1;
  559. if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
  560. return -1;
  561. switch(t[0]) {
  562. case 'i':
  563. case 'I':
  564. if(val.flags & PV_TYPE_INT)
  565. return 1;
  566. return -1;
  567. case 'n':
  568. case 'N':
  569. if(val.flags & PV_VAL_NULL)
  570. return 1;
  571. return -1;
  572. case 's':
  573. case 'S':
  574. if(!(val.flags & PV_VAL_STR))
  575. return -1;
  576. if(val.flags & PV_TYPE_INT)
  577. return -1;
  578. return 1;
  579. default:
  580. return -1;
  581. }
  582. }
  583. /**
  584. * return true if the type is string and value not empty
  585. */
  586. static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2)
  587. {
  588. pv_value_t val;
  589. if (pv==NULL)
  590. return -1;
  591. if(pv_get_spec_value(msg, (pv_spec_t*)pv, &val) != 0)
  592. return -1;
  593. if(!(val.flags & PV_VAL_STR))
  594. return -1;
  595. if(val.flags & PV_TYPE_INT)
  596. return -1;
  597. if(val.rs.len>0)
  598. return 1;
  599. return -1;
  600. }
  601. /**
  602. * Copyright (C) 2011 Juha Heinanen
  603. *
  604. * Checks if pvar argument contains int value
  605. */
  606. static int is_int(struct sip_msg* msg, char* pvar, char* s2)
  607. {
  608. pv_spec_t *pvar_sp;
  609. pv_value_t pv_val;
  610. pvar_sp = (pv_spec_t *)pvar;
  611. if (pvar_sp && (pv_get_spec_value(msg, pvar_sp, &pv_val) == 0)) {
  612. return (pv_val.flags & PV_VAL_INT)?1:-1;
  613. }
  614. return -1;
  615. }
  616. static const char* rpc_shv_set_doc[2] = {
  617. "Set a shared variable (args: name type value)",
  618. 0
  619. };
  620. static const char* rpc_shv_get_doc[2] = {
  621. "Get the value of a shared variable. If no argument, dumps all",
  622. 0
  623. };
  624. rpc_export_t pv_rpc[] = {
  625. {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
  626. {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
  627. {0, 0, 0, 0}
  628. };
  629. static int pv_init_rpc(void)
  630. {
  631. if (rpc_register_array(pv_rpc)!=0)
  632. {
  633. LM_ERR("failed to register RPC commands\n");
  634. return -1;
  635. }
  636. return 0;
  637. }