dlg_var.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /**
  2. * $Id$
  3. *
  4. * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
  5. * Copyright (C) 2011 Carsten Bock, [email protected]
  6. *
  7. * This file is part of kamailio, a free SIP server.
  8. *
  9. * openser is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * openser is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include "../../route.h"
  24. #include "dlg_var.h"
  25. #include "dlg_hash.h"
  26. #include "dlg_profile.h"
  27. #include "dlg_db_handler.h"
  28. dlg_ctx_t _dlg_ctx;
  29. extern int spiral_detected;
  30. /*! global variable table, in case the dialog does not exist yet */
  31. struct dlg_var * var_table = 0;
  32. /*! ID of the current message */
  33. int msg_id;
  34. int dlg_cfg_cb(struct sip_msg *foo, unsigned int flags, void *bar)
  35. {
  36. memset(&_dlg_ctx, 0, sizeof(dlg_ctx_t));
  37. return 1;
  38. }
  39. static inline struct dlg_var *new_dlg_var(str *key, str *val)
  40. {
  41. struct dlg_var *var;
  42. var =(struct dlg_var*)shm_malloc(sizeof(struct dlg_var));
  43. if (var==NULL) {
  44. LM_ERR("no more shm mem\n");
  45. return NULL;
  46. }
  47. var->next = NULL;
  48. var->vflags = DLG_FLAG_NEW;
  49. /* set key */
  50. var->key.len = key->len;
  51. var->key.s = (char*)shm_malloc(var->key.len);
  52. if (var->key.s==NULL) {
  53. shm_free(var);
  54. LM_ERR("no more shm mem\n");
  55. return NULL;
  56. }
  57. memcpy(var->key.s, key->s, key->len);
  58. /* set value */
  59. var->value.len = val->len;
  60. var->value.s = (char*)shm_malloc(var->value.len);
  61. if (var->value.s==NULL) {
  62. shm_free(var->key.s);
  63. shm_free(var);
  64. LM_ERR("no more shm mem\n");
  65. return NULL;
  66. }
  67. memcpy(var->value.s, val->s, val->len);
  68. return var;
  69. }
  70. /*! Delete the current var-list */
  71. void free_local_varlist() {
  72. struct dlg_var *var;
  73. while (var_table) {
  74. var = var_table;
  75. var_table = var_table->next;
  76. shm_free(var->key.s);
  77. shm_free(var->value.s);
  78. shm_free(var);
  79. }
  80. }
  81. /*! Retrieve the local var-list pointer */
  82. struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointer) {
  83. struct dlg_var *var;
  84. /* New list, delete the old one */
  85. if (msg->id != msg_id) {
  86. free_local_varlist();
  87. msg_id = msg->id;
  88. }
  89. var = var_table;
  90. if (clear_pointer)
  91. var_table = NULL;
  92. return var;
  93. }
  94. /* Adds, updates and deletes dialog variables */
  95. int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val, int new)
  96. {
  97. struct dlg_var * var = NULL;
  98. struct dlg_var * it;
  99. struct dlg_var * it_prev;
  100. struct dlg_var ** var_list;
  101. if (dlg)
  102. var_list = &dlg->vars;
  103. else
  104. var_list = &var_table;
  105. if ( val && (var=new_dlg_var(key, val))==NULL) {
  106. LM_ERR("failed to create new dialog variable\n");
  107. return -1;
  108. }
  109. /* iterate the list */
  110. for( it_prev=NULL, it=*var_list ; it ; it_prev=it,it=it->next) {
  111. if (key->len==it->key.len && memcmp(key->s,it->key.s,key->len)==0
  112. && (it->vflags & DLG_FLAG_DEL) == 0) {
  113. /* found -> replace or delete it */
  114. if (val==NULL) {
  115. /* delete it */
  116. if (it_prev) it_prev->next = it->next;
  117. else *var_list = it->next;
  118. /* Set the delete-flag for the current var: */
  119. it->vflags &= DLG_FLAG_DEL;
  120. } else {
  121. /* replace the current it with var and free the it */
  122. var->next = it->next;
  123. /* Take the previous vflags: */
  124. var->vflags = it->vflags & DLG_FLAG_CHANGED;
  125. if (it_prev) it_prev->next = var;
  126. else *var_list = var;
  127. }
  128. /* Free this var: */
  129. shm_free(it->key.s);
  130. shm_free(it->value.s);
  131. shm_free(it);
  132. return 0;
  133. }
  134. }
  135. /* not found: */
  136. if (!var) {
  137. LM_ERR("dialog variable <%.*s> does not exist in variable list\n", key->len, key->s);
  138. return -1;
  139. }
  140. /* insert a new one at the beginning of the list */
  141. var->next = *var_list;
  142. *var_list = var;
  143. return 0;
  144. }
  145. str * get_dlg_variable_unsafe(struct dlg_cell *dlg, str *key)
  146. {
  147. struct dlg_var *var, *var_list;
  148. if (dlg)
  149. var_list = dlg->vars;
  150. else
  151. var_list = var_table;
  152. /* iterate the list */
  153. for(var=var_list ; var ; var=var->next) {
  154. if (key->len==var->key.len && memcmp(key->s,var->key.s,key->len)==0
  155. && (var->vflags & DLG_FLAG_DEL) == 0) {
  156. return &var->value;
  157. }
  158. }
  159. return NULL;
  160. }
  161. int pv_parse_dialog_var_name(pv_spec_p sp, str *in)
  162. {
  163. if(in==NULL || in->s==NULL || sp==NULL)
  164. return -1;
  165. sp->pvp.pvn.type = PV_NAME_INTSTR;
  166. sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
  167. sp->pvp.pvn.u.isname.name.s = *in;
  168. return 0;
  169. }
  170. /*! Internal debugging function: Prints the list of dialogs */
  171. void print_lists(struct dlg_cell *dlg) {
  172. struct dlg_var *varlist;
  173. varlist = var_table;
  174. LM_DBG("Internal var-list (%p):\n", varlist);
  175. while (varlist) {
  176. LM_DBG("%.*s=%.*s (flags %i)\n",
  177. varlist->key.len, varlist->key.s,
  178. varlist->value.len, varlist->value.s,
  179. varlist->vflags);
  180. varlist = varlist->next;
  181. }
  182. if (dlg) {
  183. varlist = dlg->vars;
  184. LM_DBG("Dialog var-list (%p):\n", varlist);
  185. while (varlist) {
  186. LM_DBG("%.*s=%.*s (flags %i)\n",
  187. varlist->key.len, varlist->key.s,
  188. varlist->value.len, varlist->value.s,
  189. varlist->vflags);
  190. varlist = varlist->next;
  191. }
  192. }
  193. }
  194. str * api_get_dlg_variable(str *callid, str *ftag, str *ttag, str *key) {
  195. struct dlg_cell *dlg;
  196. unsigned int dir = DLG_DIR_NONE;
  197. dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count!
  198. if (!dlg) {
  199. LM_ERR("Asked to tear down non existent dialog\n");
  200. return NULL;
  201. }
  202. unref_dlg(dlg, 1);
  203. return get_dlg_variable(dlg, key);
  204. }
  205. str * get_dlg_variable(struct dlg_cell *dlg, str *key)
  206. {
  207. str* var = NULL;
  208. if( !dlg || !key || key->len > strlen(key->s))
  209. {
  210. LM_ERR("BUG - bad parameters\n");
  211. return NULL;
  212. }
  213. dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
  214. var = get_dlg_variable_unsafe( dlg, key);
  215. dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  216. return var;
  217. }
  218. int api_set_dlg_variable(str *callid, str *ftag, str *ttag, str *key, str *val) {
  219. struct dlg_cell *dlg;
  220. unsigned int dir = DLG_DIR_NONE;
  221. dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count!
  222. if (!dlg) {
  223. LM_ERR("Asked to tear down non existent dialog\n");
  224. return -1;
  225. }
  226. unref_dlg(dlg, 1);
  227. return set_dlg_variable(dlg, key, val);
  228. }
  229. int set_dlg_variable(struct dlg_cell *dlg, str *key, str *val)
  230. {
  231. if( !dlg || !key || key->len > strlen(key->s) || (val && val->len > strlen(val->s)))
  232. {
  233. LM_ERR("BUG - bad parameters\n");
  234. return -1;
  235. }
  236. dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
  237. if( !val)
  238. {
  239. if (set_dlg_variable_unsafe(dlg, key, NULL, 1)!=0) {
  240. LM_ERR("failed to delete dialog variable <%.*s>\n", key->len,key->s);
  241. goto error;
  242. }
  243. } else {
  244. if (set_dlg_variable_unsafe(dlg, key, val, 1)!=0) {
  245. LM_ERR("failed to store dialog values <%.*s>\n",key->len,key->s);
  246. goto error;
  247. }
  248. }
  249. dlg->dflags &= DLG_FLAG_CHANGED_VARS;
  250. dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  251. if ( dlg_db_mode==DB_MODE_REALTIME )
  252. update_dialog_dbinfo(dlg);
  253. print_lists(dlg);
  254. return 0;
  255. error:
  256. dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  257. return -1;
  258. }
  259. int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
  260. {
  261. struct dlg_cell *dlg;
  262. str * value;
  263. if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL) {
  264. LM_CRIT("BUG - bad parameters\n");
  265. return -1;
  266. }
  267. /* Retrieve the current dialog */
  268. dlg=get_current_dialog( msg);
  269. if (dlg) {
  270. /* Lock the dialog */
  271. dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
  272. } else {
  273. /* Verify the local list */
  274. get_local_varlist_pointer(msg, 0);
  275. }
  276. value = get_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s);
  277. print_lists(dlg);
  278. /* unlock dialog */
  279. if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  280. if (value)
  281. return pv_get_strval(msg, param, res, value);
  282. return 0;
  283. }
  284. int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val)
  285. {
  286. struct dlg_cell *dlg;
  287. /* Retrieve the current dialog */
  288. dlg=get_current_dialog( msg);
  289. if (dlg) {
  290. /* Lock the dialog */
  291. dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
  292. } else {
  293. /* Verify the local list */
  294. get_local_varlist_pointer(msg, 0);
  295. }
  296. if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL ) {
  297. LM_CRIT("BUG - bad parameters\n");
  298. return -1;
  299. }
  300. if (val==NULL || val->flags&(PV_VAL_NONE|PV_VAL_NULL|PV_VAL_EMPTY)) {
  301. /* if NULL, remove the value */
  302. if (set_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s, NULL, 1)!=0) {
  303. LM_ERR("failed to delete dialog variable <%.*s>\n", param->pvn.u.isname.name.s.len,param->pvn.u.isname.name.s.s);
  304. /* unlock dialog */
  305. if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  306. return -1;
  307. }
  308. } else {
  309. /* if value, must be string */
  310. if ( !(val->flags&PV_VAL_STR)) {
  311. LM_ERR("non-string values are not supported\n");
  312. /* unlock dialog */
  313. if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  314. return -1;
  315. }
  316. if (set_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s, &val->rs, 1)!=0) {
  317. LM_ERR("failed to store dialog values <%.*s>\n",param->pvn.u.isname.name.s.len,param->pvn.u.isname.name.s.s);
  318. /* unlock dialog */
  319. if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  320. return -1;
  321. }
  322. }
  323. /* unlock dialog */
  324. if (dlg) {
  325. dlg->dflags &= DLG_FLAG_CHANGED_VARS;
  326. dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
  327. if ( dlg_db_mode==DB_MODE_REALTIME )
  328. update_dialog_dbinfo(dlg);
  329. }
  330. print_lists(dlg);
  331. return 0;
  332. }
  333. int pv_get_dlg_ctx(struct sip_msg *msg, pv_param_t *param,
  334. pv_value_t *res)
  335. {
  336. if(param==NULL)
  337. return -1;
  338. switch(param->pvn.u.isname.name.n)
  339. {
  340. case 1:
  341. return pv_get_uintval(msg, param, res,
  342. (unsigned int)_dlg_ctx.flags);
  343. case 2:
  344. return pv_get_uintval(msg, param, res,
  345. (unsigned int)_dlg_ctx.timeout);
  346. case 3:
  347. return pv_get_uintval(msg, param, res,
  348. (unsigned int)_dlg_ctx.to_bye);
  349. case 4:
  350. return pv_get_uintval(msg, param, res,
  351. (unsigned int)_dlg_ctx.to_route);
  352. case 5:
  353. _dlg_ctx.set = (_dlg_ctx.dlg==NULL)?0:1;
  354. return pv_get_uintval(msg, param, res,
  355. (unsigned int)_dlg_ctx.set);
  356. case 6:
  357. return pv_get_uintval(msg, param, res,
  358. (unsigned int)_dlg_ctx.dir);
  359. default:
  360. return pv_get_uintval(msg, param, res,
  361. (unsigned int)_dlg_ctx.on);
  362. }
  363. return 0;
  364. }
  365. int pv_set_dlg_ctx(struct sip_msg* msg, pv_param_t *param,
  366. int op, pv_value_t *val)
  367. {
  368. int n;
  369. char *rtp;
  370. if(param==NULL)
  371. return -1;
  372. if(val==NULL)
  373. n = 0;
  374. else
  375. n = val->ri;
  376. switch(param->pvn.u.isname.name.n)
  377. {
  378. case 1:
  379. _dlg_ctx.flags = n;
  380. break;
  381. case 2:
  382. _dlg_ctx.timeout = n;
  383. break;
  384. case 3:
  385. _dlg_ctx.to_bye = n;
  386. break;
  387. case 4:
  388. if(val->flags&PV_VAL_STR) {
  389. if(val->rs.s[val->rs.len]=='\0'
  390. && val->rs.len<DLG_TOROUTE_SIZE) {
  391. _dlg_ctx.to_route = route_lookup(&main_rt, val->rs.s);
  392. strcpy(_dlg_ctx.to_route_name, val->rs.s);
  393. } else _dlg_ctx.to_route = 0;
  394. } else {
  395. if(n!=0) {
  396. rtp = int2str(n, NULL);
  397. _dlg_ctx.to_route = route_lookup(&main_rt, rtp);
  398. strcpy(_dlg_ctx.to_route_name, rtp);
  399. } else _dlg_ctx.to_route = 0;
  400. }
  401. if(_dlg_ctx.to_route <0) _dlg_ctx.to_route = 0;
  402. break;
  403. default:
  404. _dlg_ctx.on = n;
  405. break;
  406. }
  407. return 0;
  408. }
  409. int pv_parse_dlg_ctx_name(pv_spec_p sp, str *in)
  410. {
  411. if(sp==NULL || in==NULL || in->len<=0)
  412. return -1;
  413. switch(in->len)
  414. {
  415. case 2:
  416. if(strncmp(in->s, "on", 2)==0)
  417. sp->pvp.pvn.u.isname.name.n = 0;
  418. else goto error;
  419. break;
  420. case 3:
  421. if(strncmp(in->s, "set", 3)==0)
  422. sp->pvp.pvn.u.isname.name.n = 5;
  423. else if(strncmp(in->s, "dir", 3)==0)
  424. sp->pvp.pvn.u.isname.name.n = 6;
  425. else goto error;
  426. break;
  427. case 5:
  428. if(strncmp(in->s, "flags", 6)==0)
  429. sp->pvp.pvn.u.isname.name.n = 1;
  430. else goto error;
  431. break;
  432. case 7:
  433. if(strncmp(in->s, "timeout", 7)==0)
  434. sp->pvp.pvn.u.isname.name.n = 2;
  435. else goto error;
  436. break;
  437. case 11:
  438. if(strncmp(in->s, "timeout_bye", 11)==0)
  439. sp->pvp.pvn.u.isname.name.n = 3;
  440. else goto error;
  441. break;
  442. case 13:
  443. if(strncmp(in->s, "timeout_route", 13)==0)
  444. sp->pvp.pvn.u.isname.name.n = 4;
  445. else goto error;
  446. break;
  447. default:
  448. goto error;
  449. }
  450. sp->pvp.pvn.type = PV_NAME_INTSTR;
  451. sp->pvp.pvn.u.isname.type = 0;
  452. return 0;
  453. error:
  454. LM_ERR("unknown PV name %.*s\n", in->len, in->s);
  455. return -1;
  456. }
  457. int pv_get_dlg(struct sip_msg *msg, pv_param_t *param,
  458. pv_value_t *res)
  459. {
  460. if(param==NULL)
  461. return -1;
  462. if(_dlg_ctx.dlg == NULL)
  463. return pv_get_null(msg, param, res);
  464. switch(param->pvn.u.isname.name.n)
  465. {
  466. case 1:
  467. return pv_get_uintval(msg, param, res,
  468. (unsigned int)_dlg_ctx.dlg->h_id);
  469. case 2:
  470. return pv_get_uintval(msg, param, res,
  471. (unsigned int)_dlg_ctx.dlg->state);
  472. /*
  473. case 3:
  474. if(_dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].s==NULL
  475. || _dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].len<=0)
  476. return pv_get_null(msg, param, res);
  477. return pv_get_strval(msg, param, res,
  478. &_dlg_ctx.dlg->route_set[DLG_CALLEE_LEG]);
  479. case 4:
  480. return pv_get_uintval(msg, param, res,
  481. (unsigned int)_dlg_ctx.dlg->dflags);
  482. case 5:
  483. return pv_get_uintval(msg, param, res,
  484. (unsigned int)_dlg_ctx.dlg->sflags);
  485. case 6:
  486. if(_dlg_ctx.dlg->callid.s==NULL
  487. || _dlg_ctx.dlg->callid.len<=0)
  488. return pv_get_null(msg, param, res);
  489. return pv_get_strval(msg, param, res,
  490. &_dlg_ctx.dlg->callid);
  491. case 7:
  492. if(_dlg_ctx.dlg->to_uri.s==NULL
  493. || _dlg_ctx.dlg->to_uri.len<=0)
  494. return pv_get_null(msg, param, res);
  495. return pv_get_strval(msg, param, res,
  496. &_dlg_ctx.dlg->to_uri);
  497. case 8:
  498. if(_dlg_ctx.dlg->tag[DLG_CALLEE_LEG].s==NULL
  499. || _dlg_ctx.dlg->tag[DLG_CALLEE_LEG].len<=0)
  500. return pv_get_null(msg, param, res);
  501. return pv_get_strval(msg, param, res,
  502. &_dlg_ctx.dlg->tag[DLG_CALLEE_LEG]);
  503. case 9:
  504. return pv_get_uintval(msg, param, res,
  505. (unsigned int)_dlg_ctx.dlg->toroute);
  506. case 10:
  507. if(_dlg_ctx.dlg->cseq[DLG_CALLEE_LEG].s==NULL
  508. || _dlg_ctx.dlg->cseq[DLG_CALLEE_LEG].len<=0)
  509. return pv_get_null(msg, param, res);
  510. return pv_get_strval(msg, param, res,
  511. &_dlg_ctx.dlg->cseq[DLG_CALLEE_LEG]);
  512. case 11:
  513. if(_dlg_ctx.dlg->route_set[DLG_CALLER_LEG].s==NULL
  514. || _dlg_ctx.dlg->route_set[DLG_CALLER_LEG].len<=0)
  515. return pv_get_null(msg, param, res);
  516. return pv_get_strval(msg, param, res,
  517. &_dlg_ctx.dlg->route_set[DLG_CALLER_LEG]);
  518. case 12:
  519. if(_dlg_ctx.dlg->from_uri.s==NULL
  520. || _dlg_ctx.dlg->from_uri.len<=0)
  521. return pv_get_null(msg, param, res);
  522. return pv_get_strval(msg, param, res,
  523. &_dlg_ctx.dlg->from_uri);
  524. case 13:
  525. if(_dlg_ctx.dlg->tag[DLG_CALLER_LEG].s==NULL
  526. || _dlg_ctx.dlg->tag[DLG_CALLER_LEG].len<=0)
  527. return pv_get_null(msg, param, res);
  528. return pv_get_strval(msg, param, res,
  529. &_dlg_ctx.dlg->tag[DLG_CALLER_LEG]);
  530. case 14:
  531. return pv_get_uintval(msg, param, res,
  532. (unsigned int)_dlg_ctx.dlg->lifetime);
  533. case 15:
  534. return pv_get_uintval(msg, param, res,
  535. (unsigned int)_dlg_ctx.dlg->start_ts);
  536. case 16:
  537. if(_dlg_ctx.dlg->cseq[DLG_CALLER_LEG].s==NULL
  538. || _dlg_ctx.dlg->cseq[DLG_CALLER_LEG].len<=0)
  539. return pv_get_null(msg, param, res);
  540. return pv_get_strval(msg, param, res,
  541. &_dlg_ctx.dlg->cseq[DLG_CALLER_LEG]);
  542. case 17:
  543. if(_dlg_ctx.dlg->contact[DLG_CALLEE_LEG].s==NULL
  544. || _dlg_ctx.dlg->contact[DLG_CALLEE_LEG].len<=0)
  545. return pv_get_null(msg, param, res);
  546. return pv_get_strval(msg, param, res,
  547. &_dlg_ctx.dlg->contact[DLG_CALLEE_LEG]);
  548. case 18:
  549. if(_dlg_ctx.dlg->bind_addr[DLG_CALLEE_LEG]==NULL)
  550. return pv_get_null(msg, param, res);
  551. return pv_get_strval(msg, param, res,
  552. &_dlg_ctx.dlg->bind_addr[DLG_CALLEE_LEG]->sock_str);
  553. case 19:
  554. if(_dlg_ctx.dlg->contact[DLG_CALLER_LEG].s==NULL
  555. || _dlg_ctx.dlg->contact[DLG_CALLER_LEG].len<=0)
  556. return pv_get_null(msg, param, res);
  557. return pv_get_strval(msg, param, res,
  558. &_dlg_ctx.dlg->contact[DLG_CALLER_LEG]);
  559. case 20:
  560. if(_dlg_ctx.dlg->bind_addr[DLG_CALLER_LEG]==NULL)
  561. return pv_get_null(msg, param, res);
  562. return pv_get_strval(msg, param, res,
  563. &_dlg_ctx.dlg->bind_addr[DLG_CALLER_LEG]->sock_str);
  564. case 21:
  565. return pv_get_uintval(msg, param, res,
  566. (unsigned int)_dlg_ctx.dlg->h_entry);
  567. */
  568. default:
  569. return pv_get_uintval(msg, param, res,
  570. (unsigned int)_dlg_ctx.dlg->ref);
  571. }
  572. return 0;
  573. }
  574. int pv_parse_dlg_name(pv_spec_p sp, str *in)
  575. {
  576. if(sp==NULL || in==NULL || in->len<=0)
  577. return -1;
  578. switch(in->len)
  579. {
  580. case 3:
  581. if(strncmp(in->s, "ref", 3)==0)
  582. sp->pvp.pvn.u.isname.name.n = 0;
  583. else goto error;
  584. break;
  585. case 4:
  586. if(strncmp(in->s, "h_id", 4)==0)
  587. sp->pvp.pvn.u.isname.name.n = 1;
  588. else goto error;
  589. break;
  590. case 5:
  591. if(strncmp(in->s, "state", 5)==0)
  592. sp->pvp.pvn.u.isname.name.n = 2;
  593. else if(strncmp(in->s, "to_rs", 5)==0)
  594. sp->pvp.pvn.u.isname.name.n = 3;
  595. else goto error;
  596. break;
  597. case 6:
  598. if(strncmp(in->s, "dflags", 6)==0)
  599. sp->pvp.pvn.u.isname.name.n = 4;
  600. else if(strncmp(in->s, "sflags", 6)==0)
  601. sp->pvp.pvn.u.isname.name.n = 5;
  602. else if(strncmp(in->s, "callid", 6)==0)
  603. sp->pvp.pvn.u.isname.name.n = 6;
  604. else if(strncmp(in->s, "to_uri", 6)==0)
  605. sp->pvp.pvn.u.isname.name.n = 7;
  606. else if(strncmp(in->s, "to_tag", 6)==0)
  607. sp->pvp.pvn.u.isname.name.n = 8;
  608. else goto error;
  609. break;
  610. case 7:
  611. if(strncmp(in->s, "toroute", 7)==0)
  612. sp->pvp.pvn.u.isname.name.n = 9;
  613. else if(strncmp(in->s, "to_cseq", 7)==0)
  614. sp->pvp.pvn.u.isname.name.n = 10;
  615. else if(strncmp(in->s, "from_rs", 7)==0)
  616. sp->pvp.pvn.u.isname.name.n = 11;
  617. else if(strncmp(in->s, "h_entry", 7)==0)
  618. sp->pvp.pvn.u.isname.name.n = 21;
  619. else goto error;
  620. break;
  621. case 8:
  622. if(strncmp(in->s, "from_uri", 8)==0)
  623. sp->pvp.pvn.u.isname.name.n = 12;
  624. else if(strncmp(in->s, "from_tag", 8)==0)
  625. sp->pvp.pvn.u.isname.name.n = 13;
  626. else if(strncmp(in->s, "lifetime", 8)==0)
  627. sp->pvp.pvn.u.isname.name.n = 14;
  628. else if(strncmp(in->s, "start_ts", 8)==0)
  629. sp->pvp.pvn.u.isname.name.n = 15;
  630. else goto error;
  631. break;
  632. case 9:
  633. if(strncmp(in->s, "from_cseq", 9)==0)
  634. sp->pvp.pvn.u.isname.name.n = 16;
  635. else goto error;
  636. break;
  637. case 10:
  638. if(strncmp(in->s, "to_contact", 10)==0)
  639. sp->pvp.pvn.u.isname.name.n = 17;
  640. else goto error;
  641. break;
  642. case 11:
  643. if(strncmp(in->s, "to_bindaddr", 11)==0)
  644. sp->pvp.pvn.u.isname.name.n = 18;
  645. else goto error;
  646. break;
  647. case 12:
  648. if(strncmp(in->s, "from_contact", 12)==0)
  649. sp->pvp.pvn.u.isname.name.n = 19;
  650. else goto error;
  651. break;
  652. case 13:
  653. if(strncmp(in->s, "from_bindaddr", 20)==0)
  654. sp->pvp.pvn.u.isname.name.n = 2;
  655. else goto error;
  656. break;
  657. default:
  658. goto error;
  659. }
  660. sp->pvp.pvn.type = PV_NAME_INTSTR;
  661. sp->pvp.pvn.u.isname.type = 0;
  662. return 0;
  663. error:
  664. LM_ERR("unknown PV name %.*s\n", in->len, in->s);
  665. return -1;
  666. }
  667. void dlg_set_ctx_dialog(struct dlg_cell *dlg)
  668. {
  669. _dlg_ctx.dlg = dlg;
  670. }
  671. struct dlg_cell* dlg_get_ctx_dialog(void)
  672. {
  673. return _dlg_ctx.dlg;
  674. }
  675. dlg_ctx_t* dlg_get_dlg_ctx(void)
  676. {
  677. return &_dlg_ctx;
  678. }
  679. int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar)
  680. {
  681. spiral_detected = -1;
  682. return 0;
  683. }