pv_xavp.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /**
  2. * $Id$
  3. *
  4. * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #ifdef WITH_XAVP
  19. #include <stdio.h>
  20. #include "../../dprint.h"
  21. #include "../../xavp.h"
  22. #include "../../pvapi.h"
  23. #include "pv_xavp.h"
  24. #define PV_FIELD_DELIM ", "
  25. #define PV_FIELD_DELIM_LEN (sizeof(PV_FIELD_DELIM) - 1)
  26. int pv_xavp_get_value(struct sip_msg *msg, pv_param_t *param,
  27. pv_value_t *res, sr_xavp_t *avp)
  28. {
  29. static char _pv_xavp_buf[128];
  30. str s;
  31. switch(avp->val.type) {
  32. case SR_XTYPE_NULL:
  33. return pv_get_null(msg, param, res);
  34. break;
  35. case SR_XTYPE_INT:
  36. return pv_get_sintval(msg, param, res, avp->val.v.i);
  37. break;
  38. case SR_XTYPE_STR:
  39. return pv_get_strval(msg, param, res, &avp->val.v.s);
  40. break;
  41. case SR_XTYPE_TIME:
  42. if(snprintf(_pv_xavp_buf, 128, "%lu", (long unsigned)avp->val.v.t)<0)
  43. return pv_get_null(msg, param, res);
  44. break;
  45. case SR_XTYPE_LONG:
  46. if(snprintf(_pv_xavp_buf, 128, "%ld", (long unsigned)avp->val.v.l)<0)
  47. return pv_get_null(msg, param, res);
  48. break;
  49. case SR_XTYPE_LLONG:
  50. if(snprintf(_pv_xavp_buf, 128, "%lld", avp->val.v.ll)<0)
  51. return pv_get_null(msg, param, res);
  52. break;
  53. case SR_XTYPE_XAVP:
  54. if(snprintf(_pv_xavp_buf, 128, "<<xavp:%p>>", avp->val.v.xavp)<0)
  55. return pv_get_null(msg, param, res);
  56. break;
  57. case SR_XTYPE_DATA:
  58. if(snprintf(_pv_xavp_buf, 128, "<<data:%p>>", avp->val.v.data)<0)
  59. return pv_get_null(msg, param, res);
  60. break;
  61. default:
  62. return pv_get_null(msg, param, res);
  63. }
  64. s.s = _pv_xavp_buf;
  65. s.len = strlen(_pv_xavp_buf);
  66. return pv_get_strval(msg, param, res, &s);
  67. }
  68. int pv_get_xavp(struct sip_msg *msg, pv_param_t *param,
  69. pv_value_t *res)
  70. {
  71. pv_xavp_name_t *xname=NULL;
  72. sr_xavp_t *avp=NULL;
  73. int idxf = 0;
  74. int idx = 0;
  75. int count;
  76. char *p, *p_ini;
  77. int p_size;
  78. if(param==NULL)
  79. {
  80. LM_ERR("bad parameters\n");
  81. return -1;
  82. }
  83. xname = (pv_xavp_name_t*)param->pvn.u.dname;
  84. if(xname->index.type==PVT_EXTRA)
  85. {
  86. /* get the index */
  87. if(pv_get_spec_index(msg, &xname->index.pvp, &idx, &idxf)!=0)
  88. {
  89. LM_ERR("invalid index\n");
  90. return -1;
  91. }
  92. }
  93. /* fix the index */
  94. if(idx<0)
  95. {
  96. count = xavp_count(&xname->name, NULL);
  97. idx = count + idx;
  98. }
  99. avp = xavp_get_by_index(&xname->name, idx, NULL);
  100. if(avp==NULL)
  101. return pv_get_null(msg, param, res);
  102. if(xname->next==NULL)
  103. return pv_xavp_get_value(msg, param, res, avp);
  104. idx = 0;
  105. idxf = 0;
  106. if(xname->next->index.type==PVT_EXTRA)
  107. {
  108. /* get the index */
  109. if(pv_get_spec_index(msg, &xname->next->index.pvp, &idx, &idxf)!=0)
  110. {
  111. LM_ERR("invalid index\n");
  112. return -1;
  113. }
  114. }
  115. /* fix the index */
  116. if(idx<0)
  117. {
  118. count = xavp_count(&xname->next->name, &avp->val.v.xavp);
  119. idx = count + idx;
  120. }
  121. avp = xavp_get_by_index(&xname->next->name, idx, &avp->val.v.xavp);
  122. if(avp==NULL)
  123. return pv_get_null(msg, param, res);
  124. /* get all values of second key */
  125. if(idxf==PV_IDX_ALL)
  126. {
  127. p_ini = pv_get_buffer();
  128. p = p_ini;
  129. p_size = pv_get_buffer_size();
  130. do {
  131. if(p!=p_ini)
  132. {
  133. if(p-p_ini+PV_FIELD_DELIM_LEN+1>p_size)
  134. {
  135. LM_ERR("local buffer length exceeded\n");
  136. return pv_get_null(msg, param, res);
  137. }
  138. memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN);
  139. p += PV_FIELD_DELIM_LEN;
  140. }
  141. if(pv_xavp_get_value(msg, param, res, avp)<0)
  142. {
  143. LM_ERR("can get value\n");
  144. return pv_get_null(msg, param, res);
  145. }
  146. if(p-p_ini+res->rs.len+1>p_size)
  147. {
  148. LM_ERR("local buffer length exceeded!\n");
  149. return pv_get_null(msg, param, res);
  150. }
  151. memcpy(p, res->rs.s, res->rs.len);
  152. p += res->rs.len;
  153. } while ((avp=xavp_get_next(avp))!=0);
  154. res->rs.s = p_ini;
  155. res->rs.len = p - p_ini;
  156. return 0;
  157. }
  158. return pv_xavp_get_value(msg, param, res, avp);
  159. }
  160. /**
  161. * $xavp(name1[idx1]=>name2[idx2])
  162. */
  163. int pv_set_xavp(struct sip_msg* msg, pv_param_t *param,
  164. int op, pv_value_t *val)
  165. {
  166. pv_xavp_name_t *xname=NULL;
  167. sr_xavp_t *avp=NULL;
  168. sr_xavp_t *list=NULL;
  169. sr_xval_t xval;
  170. int idxf = 0;
  171. int idx = 0;
  172. int idxf1 = 0;
  173. int idx1 = 0;
  174. int count;
  175. if(param==NULL)
  176. {
  177. LM_ERR("bad parameters\n");
  178. return -1;
  179. }
  180. xname = (pv_xavp_name_t*)param->pvn.u.dname;
  181. if(xname->index.type==PVT_EXTRA)
  182. {
  183. /* get the index */
  184. if(pv_get_spec_index(msg, &xname->index.pvp, &idx, &idxf)!=0)
  185. {
  186. LM_ERR("invalid index\n");
  187. return -1;
  188. }
  189. }
  190. if((val==NULL) || (val->flags&PV_VAL_NULL))
  191. {
  192. if(xname->next==NULL)
  193. {
  194. if(xname->index.type==PVT_EXTRA) {
  195. if(idxf==PV_IDX_ALL) {
  196. xavp_rm_by_name(&xname->name, 1, NULL);
  197. return 0;
  198. }
  199. }
  200. if(idx==0) {
  201. xavp_rm_by_name(&xname->name, 0, NULL);
  202. return 0;
  203. }
  204. /* fix the index */
  205. if(idx<0)
  206. {
  207. count = xavp_count(&xname->name, NULL);
  208. idx = count + idx + 1;
  209. }
  210. xavp_rm_by_index(&xname->name, idx, NULL);
  211. return 0;
  212. }
  213. if(xname->next->index.type==PVT_EXTRA)
  214. {
  215. /* get the index */
  216. if(pv_get_spec_index(msg,&xname->next->index.pvp,&idx1,&idxf1)!=0)
  217. {
  218. LM_ERR("invalid index!\n");
  219. return -1;
  220. }
  221. }
  222. if(idxf==PV_IDX_ALL) {
  223. /* iterate */
  224. avp = xavp_get(&xname->name, NULL);
  225. while(avp) {
  226. if(avp->val.type==SR_XTYPE_XAVP) {
  227. if(xname->next->index.type==PVT_EXTRA) {
  228. if(idxf1==PV_IDX_ALL) {
  229. xavp_rm_by_name(&xname->next->name, 1,
  230. &avp->val.v.xavp);
  231. } else {
  232. /* fix the index */
  233. idx = idx1;
  234. if(idx<0)
  235. {
  236. count = xavp_count(&xname->next->name,
  237. &avp->val.v.xavp);
  238. idx = count + idx1 + 1;
  239. }
  240. xavp_rm_by_index(&xname->next->name, idx,
  241. &avp->val.v.xavp);
  242. }
  243. } else {
  244. xavp_rm_by_name(&xname->next->name, 0,
  245. &avp->val.v.xavp);
  246. }
  247. }
  248. avp = xavp_get_next(avp);
  249. }
  250. return 0;
  251. }
  252. if(idx==0) {
  253. avp = xavp_get(&xname->name, NULL);
  254. } else {
  255. /* fix the index */
  256. if(idx<0)
  257. {
  258. count = xavp_count(&xname->name, NULL);
  259. idx = count + idx + 1;
  260. }
  261. avp = xavp_get_by_index(&xname->name, idx, NULL);
  262. }
  263. if(avp) {
  264. if(avp->val.type==SR_XTYPE_XAVP) {
  265. if(xname->next->index.type==PVT_EXTRA) {
  266. if(idxf1==PV_IDX_ALL) {
  267. xavp_rm_by_name(&xname->next->name, 1,
  268. &avp->val.v.xavp);
  269. } else {
  270. /* fix the index */
  271. idx = idx1;
  272. if(idx<0)
  273. {
  274. count = xavp_count(&xname->next->name,
  275. &avp->val.v.xavp);
  276. idx = count + idx1 + 1;
  277. }
  278. xavp_rm_by_index(&xname->next->name, idx,
  279. &avp->val.v.xavp);
  280. }
  281. } else {
  282. xavp_rm_by_name(&xname->next->name, 0,
  283. &avp->val.v.xavp);
  284. }
  285. }
  286. }
  287. return 0;
  288. } /* NULL assignment */
  289. /* build xavp value */
  290. memset(&xval, 0, sizeof(sr_xval_t));
  291. if(val->flags&PV_TYPE_INT)
  292. {
  293. xval.type = SR_XTYPE_INT;
  294. xval.v.i = val->ri;
  295. } else {
  296. xval.type = SR_XTYPE_STR;
  297. xval.v.s = val->rs;
  298. }
  299. /* where to add */
  300. if(xname->next==NULL)
  301. {
  302. /* xavp with single value */
  303. if(xname->index.type==PVT_EXTRA) {
  304. if(idxf==PV_IDX_ALL) {
  305. /* ignore: should iterate and set same value to all xavps
  306. * with same name?!?! */
  307. return -1;
  308. }
  309. /* fix the index */
  310. if(idx<0)
  311. {
  312. count = xavp_count(&xname->name, NULL);
  313. idx = count + idx + 1;
  314. }
  315. /* set the value */
  316. if(xavp_set_value(&xname->name, idx, &xval, NULL)==NULL)
  317. return -1;
  318. return 0;
  319. }
  320. /* add new value */
  321. if(xavp_add_value(&xname->name, &xval, NULL)==NULL)
  322. return -1;
  323. return 0;
  324. }
  325. /* xavp with xavp list value */
  326. if(xname->next->index.type==PVT_EXTRA)
  327. {
  328. /* get the index */
  329. if(pv_get_spec_index(msg,&xname->next->index.pvp,&idx1,&idxf1)!=0)
  330. {
  331. LM_ERR("invalid index!\n");
  332. return -1;
  333. }
  334. }
  335. if(xname->index.type==PVT_EXTRA)
  336. {
  337. /* set the value */
  338. if(idxf==PV_IDX_ALL) {
  339. /* ignore: should iterate and set same value to all xavps
  340. * with same name?!?! */
  341. return 0;
  342. }
  343. if(idx==0) {
  344. avp = xavp_get(&xname->name, NULL);
  345. } else {
  346. /* fix the index */
  347. if(idx<0)
  348. {
  349. count = xavp_count(&xname->name, NULL);
  350. idx = count + idx + 1;
  351. }
  352. avp = xavp_get_by_index(&xname->name, idx, NULL);
  353. }
  354. if(avp==NULL)
  355. return 0;
  356. if(avp->val.type!=SR_XTYPE_XAVP)
  357. return -1;
  358. if(xname->next->index.type==PVT_EXTRA) {
  359. if(idxf1==PV_IDX_ALL) {
  360. /* ignore: should iterate and set same value to all xavps
  361. * with same name?!?! */
  362. return 0;
  363. }
  364. /* fix the index */
  365. idx = idx1;
  366. if(idx<0)
  367. {
  368. count = xavp_count(&xname->next->name,
  369. &avp->val.v.xavp);
  370. idx = count + idx1 + 1;
  371. }
  372. /* set value */
  373. xavp_set_value(&xname->next->name, idx, &xval, &avp->val.v.xavp);
  374. return 0;
  375. }
  376. /* add new value in sublist */
  377. if(xavp_add_value(&xname->next->name, &xval, &avp->val.v.xavp)==NULL)
  378. return -1;
  379. return 0;
  380. }
  381. /* add new xavp with xavp list */
  382. if(xavp_add_value(&xname->next->name, &xval, &list)==NULL)
  383. return -1;
  384. /* build xavp value */
  385. memset(&xval, 0, sizeof(sr_xval_t));
  386. xval.type = SR_XTYPE_XAVP;
  387. xval.v.xavp = list;
  388. xavp_add_value(&xname->name, &xval, NULL);
  389. return 0;
  390. }
  391. char* pv_xavp_fill_ni(str *in, pv_xavp_name_t *xname)
  392. {
  393. char *p;
  394. str idx;
  395. int n;
  396. if(in->s==NULL || in->len<=0 || xname==NULL)
  397. return NULL;
  398. p = in->s;
  399. /* eat ws */
  400. while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
  401. p++;
  402. if(p>in->s+in->len || *p=='\0')
  403. goto error;
  404. xname->name.s = p;
  405. while(p < in->s + in->len)
  406. {
  407. if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r' || *p=='[')
  408. break;
  409. p++;
  410. }
  411. xname->name.len = p - xname->name.s;
  412. if(p>in->s+in->len || *p=='\0')
  413. return p;
  414. /* eat ws */
  415. while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
  416. p++;
  417. if(p>in->s+in->len || *p=='\0')
  418. return p;
  419. if(*p!='[')
  420. return p;
  421. /* there is index */
  422. p++;
  423. idx.s = p;
  424. n = 0;
  425. while(p<in->s+in->len && *p!='\0')
  426. {
  427. if(*p==']')
  428. {
  429. if(n==0)
  430. break;
  431. n--;
  432. }
  433. if(*p == '[')
  434. n++;
  435. p++;
  436. }
  437. if(p>in->s+in->len || *p=='\0')
  438. goto error;
  439. if(p==idx.s)
  440. {
  441. LM_ERR("xavp [\"%.*s\"] does not get empty index param\n",
  442. in->len, in->s);
  443. goto error;
  444. }
  445. idx.len = p - idx.s;
  446. if(pv_parse_index(&xname->index, &idx)!=0)
  447. {
  448. LM_ERR("idx \"%.*s\" has an invalid index param [%.*s]\n",
  449. in->len, in->s, idx.len, idx.s);
  450. goto error;
  451. }
  452. xname->index.type = PVT_EXTRA;
  453. p++;
  454. return p;
  455. error:
  456. return NULL;
  457. }
  458. void pv_xavp_name_destroy(pv_xavp_name_t *xname)
  459. {
  460. return;
  461. }
  462. int pv_parse_xavp_name(pv_spec_p sp, str *in)
  463. {
  464. pv_xavp_name_t *xname=NULL;
  465. char *p;
  466. str s;
  467. if(in->s==NULL || in->len<=0)
  468. return -1;
  469. xname = (pv_xavp_name_t*)pkg_malloc(sizeof(pv_xavp_name_t));
  470. if(xname==NULL)
  471. return -1;
  472. memset(xname, 0, sizeof(pv_xavp_name_t));
  473. s = *in;
  474. p = pv_xavp_fill_ni(&s, xname);
  475. if(p==NULL)
  476. goto error;
  477. if(*p!='=')
  478. goto done;
  479. p++;
  480. if(*p!='>')
  481. goto error;
  482. p++;
  483. s.len = in->len - (int)(p - in->s);
  484. s.s = p;
  485. LM_DBG("xavp sublist [%.*s] - key [%.*s]\n", xname->name.len,
  486. xname->name.s, s.len, s.s);
  487. xname->next = (pv_xavp_name_t*)pkg_malloc(sizeof(pv_xavp_name_t));
  488. if(xname->next==NULL)
  489. goto error;
  490. memset(xname->next, 0, sizeof(pv_xavp_name_t));
  491. p = pv_xavp_fill_ni(&s, xname->next);
  492. if(p==NULL)
  493. goto error;
  494. done:
  495. sp->pvp.pvn.u.dname = (void*)xname;
  496. sp->pvp.pvn.type = PV_NAME_PVAR;
  497. return 0;
  498. error:
  499. if(xname!=NULL) {
  500. pv_xavp_name_destroy(xname);
  501. pkg_free(xname);
  502. }
  503. return -1;
  504. }
  505. int pv_xavp_print(struct sip_msg* msg, char* s1, char *s2)
  506. {
  507. xavp_print_list(NULL);
  508. return 1;
  509. }
  510. #endif