dlg_hash.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*
  2. * Copyright (C) 2006 Voice System SRL
  3. * Copyright (C) 2011 Carsten Bock, [email protected]
  4. *
  5. * This file is part of Kamailio, a free SIP server.
  6. *
  7. * Kamailio is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. * Kamailio is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * History:
  22. * --------
  23. * 2006-04-14 initial version (bogdan)
  24. * 2006-11-28 Added num_100s and num_200s to dlg_cell, to aid in adding
  25. * statistics tracking of the number of early, and active dialogs.
  26. * (Jeffrey Magder - SOMA Networks)
  27. * 2007-03-06 syncronized state machine added for dialog state. New tranzition
  28. * design based on events; removed num_1xx and num_2xx (bogdan)
  29. * 2007-07-06 added flags, cseq, contact, route_set and bind_addr
  30. * to struct dlg_cell in order to store these information into db
  31. * (ancuta)
  32. * 2008-04-17 added new dialog flag to avoid state tranzitions from DELETED to
  33. * CONFIRMED_NA due delayed "200 OK" (bogdan)
  34. * 2010-09 Add dlg_out structure to cater for forked calls and early dialog termination (richard and jason)
  35. */
  36. /*!
  37. * \file
  38. * \brief Functions and definitions related to dialog creation and searching
  39. * \ingroup dialog
  40. * Module: \ref dialog
  41. */
  42. #ifndef _DIALOG_DLG_HASH_H_
  43. #define _DIALOG_DLG_HASH_H_
  44. #include "../../locking.h"
  45. #include "../../lib/kmi/mi.h"
  46. #include "dlg_timer.h"
  47. #include "dlg_cb.h"
  48. #include "../../modules/tm/tm_load.h"
  49. /* states of a dialog */
  50. #define DLG_STATE_UNCONFIRMED 1 /*!< unconfirmed dialog */
  51. #define DLG_STATE_EARLY 2 /*!< early dialog */
  52. #define DLG_STATE_CONFIRMED 4 /*!< confirmed dialog */
  53. #define DLG_STATE_DELETED 5 /*!< deleted dialog */
  54. #define DLG_STATE_CONCURRENTLY_CONFIRMED 6 /*!< confirmed concurrent dailogs */
  55. /* events for dialog processing */
  56. #define DLG_EVENT_TDEL 1 /*!< transaction was destroyed */
  57. #define DLG_EVENT_RPL1xx 2 /*!< 1xx request */
  58. #define DLG_EVENT_RPL2xx 3 /*!< 2xx request */
  59. #define DLG_EVENT_RPL3xx 4 /*!< 3xx request */
  60. #define DLG_EVENT_REQPRACK 5 /*!< PRACK request */
  61. #define DLG_EVENT_REQACK 6 /*!< ACK request */
  62. #define DLG_EVENT_REQBYE 7 /*!< BYE request */
  63. #define DLG_EVENT_REQ 8 /*!< other requests */
  64. /* dialog flags */
  65. #define DLG_FLAG_NEW (1<<0) /*!< new dialog */
  66. #define DLG_FLAG_CHANGED (1<<1) /*!< dialog was changed */
  67. #define DLG_FLAG_HASBYE (1<<2) /*!< bye was received */
  68. #define DLG_FLAG_TOBYE (1<<3) /*!< flag from dialog context */
  69. #define DLG_FLAG_CALLERBYE (1<<4) /*!< bye from caller */
  70. #define DLG_FLAG_CALLEEBYE (1<<5) /*!< bye from callee */
  71. #define DLG_FLAG_LOCALDLG (1<<6) /*!< local dialog, unused */
  72. #define DLG_FLAG_CHANGED_VARS (1<<7) /*!< dialog-variables changed */
  73. /* dialog-variable flags (in addition to dialog-flags) */
  74. #define DLG_FLAG_DEL (1<<8) /*!< delete this var */
  75. #define DLG_FLAG_INSERTED (1<<9) /*!< DLG already written to DB - could have been put in by early media or confirmed */
  76. #define DLG_CALLER_LEG 0 /*!< attribute that belongs to a caller leg */
  77. #define DLG_CALLEE_LEG 1 /*!< attribute that belongs to a callee leg */
  78. #define DLG_DIR_NONE 0 /*!< dialog has no direction */
  79. #define DLG_DIR_DOWNSTREAM 1 /*!< dialog has downstream direction */
  80. #define DLG_DIR_UPSTREAM 2 /*!< dialog has upstream direction */
  81. /*! entries in the main dialog table */
  82. struct dlg_entry_out {
  83. struct dlg_cell_out *first; /*!< dialog list */
  84. struct dlg_cell_out *last; /*!< optimisation, end of the dialog list */
  85. unsigned int count; /*! number of out entries in the linked list */
  86. };
  87. /*! entries in the dialog list */
  88. struct dlg_cell {
  89. volatile int ref; /*!< reference counter */
  90. struct dlg_cell *next; /*!< next entry in the list */
  91. struct dlg_cell *prev; /*!< previous entry in the list */
  92. unsigned int h_id; /*!< id of the hash table entry */
  93. unsigned int h_entry; /*!< number of hash entry */
  94. str did;
  95. str callid; /*!< callid from SIP message */
  96. str from_tag; /*!< from tags of caller*/
  97. str from_uri; /*!< from uri from SIP message */
  98. str first_req_cseq; /*!< CSEQ of caller*/
  99. str req_uri; /*!< r-uri from SIP message */
  100. str caller_contact; /*!< contact of caller*/
  101. str caller_route_set; /*!< route set of caller*/
  102. struct socket_info * caller_bind_addr; /*! binded address of caller*/
  103. unsigned int state; /*!< dialog state */
  104. unsigned int start_ts; /*!< start time (absolute UNIX ts)*/
  105. unsigned int lifetime; /*!< dialog lifetime */
  106. unsigned int toroute; /*!< index of route that is executed on timeout */
  107. str toroute_name; /*!< name of route that is executed on timeout */
  108. unsigned int dflags; /*!< internal dialog flags */
  109. unsigned int sflags; /*!< script dialog flags */
  110. struct dlg_tl tl; /*!< dialog timer list */
  111. struct dlg_head_cbl cbs; /*!< dialog callbacks */
  112. struct dlg_profile_link *profile_links; /*!< dialog profiles */
  113. struct dlg_var *vars; /*!< dialog variables */
  114. struct dlg_entry_out dlg_entry_out; /*!< list of dialog_out entries */
  115. struct cell *transaction; /*!< ptr to associated transaction for this dialog TM module cell ptr */
  116. gen_lock_t *dlg_out_entries_lock; /*!< lock for dialog_out linked list */
  117. unsigned int from_rr_nb; /*!< information from record routing */
  118. };
  119. struct dlg_cell_out {
  120. struct dlg_cell_out *next; /*!< next entry in the list */
  121. struct dlg_cell_out *prev; /*!< previous entry in the list */
  122. unsigned int h_id; /*!< id of the hash table entry */
  123. unsigned int h_entry; /*!< number of hash entry */
  124. str did;
  125. str to_uri; /*!< to uri */
  126. str to_tag; /*!< to tags of callee*/
  127. str caller_cseq; /*!< CSEQ of caller*/
  128. str callee_cseq; /*!< CSEQ of callee*/
  129. str callee_contact; /*!< contact of callee*/
  130. str callee_route_set; /*!< route set of caller*/
  131. struct socket_info * callee_bind_addr; /*! binded address of caller*/
  132. unsigned int dflags; /*!< internal dialog flags */
  133. unsigned int deleted;
  134. };
  135. /*! entries in the main dialog table */
  136. struct dlg_entry {
  137. struct dlg_cell *first; /*!< dialog list */
  138. struct dlg_cell *last; /*!< optimisation, end of the dialog list */
  139. unsigned int next_id; /*!< next id */
  140. unsigned int lock_idx; /*!< lock index */
  141. };
  142. /*! main dialog table */
  143. struct dlg_table {
  144. unsigned int size; /*!< size of the dialog table */
  145. struct dlg_entry *entries; /*!< dialog hash table */
  146. unsigned int locks_no; /*!< number of locks */
  147. gen_lock_set_t *locks; /*!< lock table */
  148. };
  149. /*! global dialog table */
  150. extern struct dlg_table *d_table;
  151. /*! point to the current dialog */
  152. extern struct dlg_cell *current_dlg_pointer;
  153. /*!
  154. * \brief Set a dialog lock
  155. * \param _table dialog table
  156. * \param _entry locked entry
  157. */
  158. #define dlg_lock(_table, _entry) \
  159. lock_set_get( (_table)->locks, (_entry)->lock_idx);
  160. /*!
  161. * \brief Release a dialog lock
  162. * \param _table dialog table
  163. * \param _entry locked entry
  164. */
  165. #define dlg_unlock(_table, _entry) \
  166. lock_set_release( (_table)->locks, (_entry)->lock_idx);
  167. /*!
  168. * \brief Unlink a dialog from the list without locking
  169. * \see unref_dlg_unsafe
  170. * \param d_entry unlinked entry
  171. * \param dlg unlinked dialog
  172. */
  173. static inline void unlink_unsafe_dlg(struct dlg_entry *d_entry, struct dlg_cell *dlg) {
  174. if (dlg->next)
  175. dlg->next->prev = dlg->prev;
  176. else
  177. d_entry->last = dlg->prev;
  178. if (dlg->prev)
  179. dlg->prev->next = dlg->next;
  180. else
  181. d_entry->first = dlg->next;
  182. dlg->next = dlg->prev = 0;
  183. return;
  184. }
  185. /*!
  186. * \brief Destroy a dialog, run callbacks and free memory
  187. * \param dlg destroyed dialog
  188. */
  189. inline void destroy_dlg(struct dlg_cell *dlg);
  190. /*!
  191. * \brief Initialize the global dialog table
  192. * \param size size of the table
  193. * \return 0 on success, -1 on failure
  194. */
  195. int init_dlg_table(unsigned int size);
  196. /*!
  197. * \brief Destroy the global dialog table
  198. */
  199. void destroy_dlg_table(void);
  200. void free_dlg_out_cell(struct dlg_cell_out *dlg_out);
  201. /*!
  202. * \brief Create a new dialog structure for a SIP dialog
  203. * \param callid dialog callid
  204. * \param from_uri dialog from uri
  205. * \param to_uri dialog to uri
  206. * \param from_tag dialog from tag
  207. * \param req_uri dialog r-uri
  208. * \return created dialog structure on success, NULL otherwise
  209. */
  210. struct dlg_cell* build_new_dlg(str *callid, str *from_uri,
  211. str *from_tag, str *req_uri);
  212. /*!
  213. * \brief Set the leg information for an existing dialog
  214. * \param dlg dialog
  215. * \param tag from tag or to tag
  216. * \param rr record-routing information
  217. * \param contact caller or callee contact
  218. * \param cseq CSEQ of caller or callee
  219. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  220. * \return 0 on success, -1 on failure
  221. */
  222. int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact,
  223. str *cseq, struct socket_info *bind_addr, unsigned int leg);
  224. /*!
  225. * \brief Update or set the CSEQ for an existing dialog
  226. * \param dlg dialog
  227. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  228. * \param cseq CSEQ of caller or callee
  229. * \return 0 on success, -1 on failure
  230. */
  231. int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq, str *to_tag);
  232. /*!
  233. * \brief Update or set the contact for an existing dialog
  234. * \param dlg dialog
  235. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  236. * \param contact CONTACT of caller or callee
  237. * \return 0 on success, -1 on failure
  238. */
  239. int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *contact, str *to_tag);
  240. /*!
  241. * \brief Set time-out route
  242. * \param dlg dialog
  243. * \param route name of route
  244. * \return 0 on success, -1 on failure
  245. */
  246. int dlg_set_toroute(struct dlg_cell *dlg, str *route);
  247. /*!
  248. * \brief Lookup a dialog in the global list
  249. *
  250. * Note that the caller is responsible for decrementing (or reusing)
  251. * the reference counter by one again iff a dialog has been found.
  252. * \param h_entry number of the hash table entry
  253. * \param h_id id of the hash table entry
  254. * \return dialog structure on success, NULL on failure
  255. */
  256. struct dlg_cell* lookup_dlg(unsigned int h_entry, unsigned int h_id);
  257. /*!
  258. * \brief Get dialog that correspond to CallId, From Tag and To Tag
  259. *
  260. * Get dialog that correspond to CallId, From Tag and To Tag.
  261. * See RFC 3261, paragraph 4. Overview of Operation:
  262. * "The combination of the To tag, From tag, and Call-ID completely
  263. * defines a peer-to-peer SIP relationship between [two UAs] and is
  264. * referred to as a dialog."
  265. * Note that the caller is responsible for decrementing (or reusing)
  266. * the reference counter by one again iff a dialog has been found.
  267. * \param callid callid
  268. * \param ftag from tag
  269. * \param ttag to tag
  270. * \param dir direction
  271. * \return dialog structure on success, NULL on failure
  272. */
  273. struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
  274. /*!
  275. * \brief Link a dialog structure
  276. * \param dlg dialog
  277. * \param n extra increments for the reference counter
  278. */
  279. void link_dlg(struct dlg_cell *dlg, int n);
  280. void link_dlg_out(struct dlg_cell *dlg, struct dlg_cell_out *dlg_out, int n);
  281. /*!
  282. * \brief Unreference a dialog with locking
  283. * \see unref_dlg_unsafe
  284. * \param dlg dialog
  285. * \param cnt decrement for the reference counter
  286. */
  287. void unref_dlg(struct dlg_cell *dlg, unsigned int cnt);
  288. /*!
  289. * \brief Refefence a dialog with locking
  290. * \see ref_dlg_unsafe
  291. * \param dlg dialog
  292. * \param cnt increment for the reference counter
  293. */
  294. void ref_dlg(struct dlg_cell *dlg, unsigned int cnt);
  295. /*!
  296. * \brief Update a dialog state according a event and the old state
  297. *
  298. * This functions implement the main state machine that update a dialog
  299. * state according a processed event and the current state. If necessary
  300. * it will delete the processed dialog. The old and new state are also
  301. * saved for reference.
  302. * \param dlg updated dialog
  303. * \param event current event
  304. * \param old_state old dialog state
  305. * \param new_state new dialog state
  306. * \param unref set to 1 when the dialog was deleted, 0 otherwise
  307. */
  308. void next_state_dlg(struct dlg_cell *dlg, int event,
  309. int *old_state, int *new_state, int *unref, str *to_tag);
  310. /*!
  311. * \brief Output all dialogs via the MI interface
  312. * \param cmd_tree MI root node
  313. * \param param unused
  314. * \return a mi node with the dialog information, or NULL on failure
  315. */
  316. struct mi_root * mi_print_dlgs(struct mi_root *cmd, void *param);
  317. /*!
  318. * \brief Print a dialog context via the MI interface
  319. * \param cmd_tree MI command tree
  320. * \param param unused
  321. * \return mi node with the dialog information, or NULL on failure
  322. */
  323. struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd, void *param);
  324. /*!
  325. * \brief Terminate selected dialogs via the MI interface
  326. * \param cmd_tree MI command tree
  327. * \param param unused
  328. * \return mi node with the dialog information, or NULL on failure
  329. */
  330. struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param);
  331. /*!
  332. * \brief Check if a dialog structure matches to a SIP message dialog
  333. * \param dlg dialog structure
  334. * \param callid SIP message Call-ID
  335. * \param ftag SIP message from tag
  336. * \param ttag SIP message to tag
  337. * \param dir direction of the message, if DLG_DIR_NONE it will set
  338. * \return 1 if dialog structure and message content matches, 0 otherwise
  339. */
  340. static inline int match_dialog(struct dlg_cell *dlg, str *callid,
  341. str *ftag, str *ttag, unsigned int *dir) {
  342. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  343. struct dlg_cell_out *dlg_out;
  344. if (d_entry_out->first == 0) {
  345. //there are no dialog out entries yet
  346. if (*dir == DLG_DIR_DOWNSTREAM) {
  347. if (dlg->callid.len == callid->len &&
  348. dlg->from_tag.len == ftag->len &&
  349. strncmp(dlg->callid.s, callid->s, callid->len) == 0 &&
  350. strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) {
  351. return 1;
  352. }
  353. } else if (*dir == DLG_DIR_UPSTREAM) {
  354. if (dlg->callid.len == callid->len &&
  355. dlg->from_tag.len == ttag->len &&
  356. strncmp(dlg->callid.s, callid->s, callid->len) == 0 &&
  357. strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) {
  358. return 1;
  359. }
  360. } else {
  361. if (dlg->callid.len != callid->len) {
  362. return 0;
  363. }
  364. if (dlg->from_tag.len == ttag->len &&
  365. strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 &&
  366. strncmp(dlg->callid.s, callid->s, callid->len) == 0) {
  367. *dir = DLG_DIR_UPSTREAM;
  368. return 1;
  369. } else if (dlg->from_tag.len == ftag->len &&
  370. strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 &&
  371. strncmp(dlg->callid.s, callid->s, callid->len) == 0) {
  372. *dir = DLG_DIR_DOWNSTREAM;
  373. return 1;
  374. }
  375. LM_DBG("No match found\n");
  376. }
  377. } else {
  378. //there is a dialog out entry
  379. if (*dir == DLG_DIR_DOWNSTREAM) {
  380. if (dlg->callid.len == callid->len &&
  381. dlg->from_tag.len == ftag->len &&
  382. strncmp(dlg->callid.s, callid->s, callid->len) == 0 &&
  383. strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) {
  384. //now need to scroll thought d_out_entries to see if to_tag matches!
  385. dlg_out = d_entry_out->first;
  386. while (dlg_out) {
  387. if (dlg_out->to_tag.len == ttag->len &&
  388. memcmp(dlg_out->to_tag.s, ttag->s, dlg_out->to_tag.len) == 0) {
  389. return 1;
  390. }
  391. dlg_out = dlg_out->next;
  392. }
  393. }
  394. } else if (*dir == DLG_DIR_UPSTREAM) {
  395. if (dlg->callid.len == callid->len &&
  396. dlg->from_tag.len == ttag->len &&
  397. strncmp(dlg->callid.s, callid->s, callid->len) == 0 &&
  398. strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) {
  399. dlg_out = d_entry_out->first;
  400. while (dlg_out) {
  401. if (dlg_out->to_tag.len == ftag->len &&
  402. memcmp(dlg_out->to_tag.s, ftag->s, dlg_out->to_tag.len) == 0) {
  403. return 1;
  404. }
  405. dlg_out = dlg_out->next;
  406. }
  407. }
  408. } else {
  409. if (dlg->callid.len != callid->len) {
  410. LM_DBG("no match cid: %d %d", dlg->callid.len, callid->len);
  411. return 0;
  412. }
  413. LM_DBG("p: %p ft[%.*s] tt [%.*s]", d_entry_out->first,
  414. dlg->from_tag.len, dlg->from_tag.s,
  415. ttag->len, ttag->s);
  416. if (dlg->from_tag.len == ttag->len &&
  417. strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 &&
  418. strncmp(dlg->callid.s, callid->s, callid->len) == 0) {
  419. //now need to scroll thought d_out_entries to see if to_tag matches!
  420. dlg_out = d_entry_out->first;
  421. while (dlg_out) {
  422. LM_DBG("dout: tt[%.*s]",
  423. dlg_out->to_tag.len, dlg_out->to_tag.s);
  424. if (dlg_out->to_tag.len == ftag->len &&
  425. memcmp(dlg_out->to_tag.s, ftag->s, dlg_out->to_tag.len) == 0) {
  426. *dir = DLG_DIR_UPSTREAM;
  427. return 1;
  428. }
  429. dlg_out = dlg_out->next;
  430. }
  431. } else if (dlg->from_tag.len == ftag->len &&
  432. strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 &&
  433. strncmp(dlg->callid.s, callid->s, callid->len) == 0) {
  434. //now need to scroll thought d_out_entries to see if to_tag matches!
  435. dlg_out = d_entry_out->first;
  436. while (dlg_out) {
  437. LM_DBG("dout: tt[%.*s]",
  438. dlg_out->to_tag.len, dlg_out->to_tag.s);
  439. if (dlg_out->to_tag.len == ttag->len &&
  440. memcmp(dlg_out->to_tag.s, ttag->s, dlg_out->to_tag.len) == 0) {
  441. *dir = DLG_DIR_DOWNSTREAM;
  442. return 1;
  443. }
  444. dlg_out = dlg_out->next;
  445. }
  446. }
  447. else
  448. LM_DBG("no match tags: ");
  449. }
  450. }
  451. return 0;
  452. }
  453. /*!
  454. * \brief Check if a downstream dialog structure matches a SIP message dialog
  455. * \param dlg dialog structure
  456. * \param callid SIP message callid
  457. * \param ftag SIP message from tag
  458. * \return 1 if dialog structure matches the SIP dialog, 0 otherwise
  459. */
  460. static inline int match_downstream_dialog(struct dlg_cell *dlg, str *callid, str *ftag) {
  461. if (dlg == NULL || callid == NULL)
  462. return 0;
  463. if (ftag == NULL) {
  464. if (dlg->callid.len != callid->len ||
  465. strncmp(dlg->callid.s, callid->s, callid->len) != 0)
  466. return 0;
  467. } else {
  468. if (dlg->callid.len != callid->len ||
  469. dlg->from_tag.len != ftag->len ||
  470. strncmp(dlg->callid.s, callid->s, callid->len) != 0 ||
  471. strncmp(dlg->from_tag.s, ftag->s, ftag->len) != 0)
  472. return 0;
  473. }
  474. return 1;
  475. }
  476. /*!
  477. * \brief Output a dialog via the MI interface
  478. * \param rpl MI node that should be filled
  479. * \param dlg printed dialog
  480. * \param with_context if 1 then the dialog context will be also printed
  481. * \return 0 on success, -1 on failure
  482. */
  483. int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context);
  484. /*!
  485. * \brief Create a new dialog out structure for a SIP dialog
  486. * \param to_tag - dialog to_tag
  487. * \return created dlg_out structure on success, NULL otherwise
  488. */
  489. struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str *to_uri, str* to_tag);
  490. /*!
  491. * \brief Remove all dlg_out entries from dlg structure expect that identified as dlg_do_not_remove
  492. * \param dlg_out cell - struture to not remove
  493. * \param mark_only - 1 then only mark for delection, if 0 then delete
  494. * \return void
  495. */
  496. void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, struct dlg_cell *dlg, int only_mark);
  497. /*!
  498. * \brief Remove dlg_out entry identified by to_tag from dlg structure
  499. * \param dlg structure
  500. * \param dlg_out to_tag
  501. * \return void
  502. */
  503. void dlg_remove_dlg_out_tag(struct dlg_cell *dlg, str *to_tag);
  504. /*!
  505. * \brief Takes the did of the dialog and appends an "x" to it to make a different did for concurrent calls
  506. * \param dlg_cell - dlg_cell whose did we use
  507. * \param new_did - empty container for new_did
  508. * \return void
  509. */
  510. void create_concurrent_did(struct dlg_cell *dlg, str *new_did);
  511. /*!
  512. * \brief Update the did of the dlg_out structure
  513. * \param dlg_cell_out - structure to update
  514. * \param new_did - new did to use
  515. * \return 1 success, 0 failure
  516. */
  517. int update_dlg_out_did(struct dlg_cell_out *dlg_out, str *new_did);
  518. /*!
  519. * \brief Update the did of the dlg structure
  520. * \param dlg_cell - structure to update
  521. * \param new_did - new did to use
  522. * \return 1 success, 0 failure
  523. */
  524. int update_dlg_did(struct dlg_cell *dlg, str *new_did);
  525. time_t api_get_dlg_expires(str *callid, str *ftag, str *ttag);
  526. char* state_to_char(unsigned int state);
  527. #endif