pjsip_session.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2017, CFWare, LLC
  5. *
  6. * Corey Farrell <git@cfware.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. #include "asterisk.h"
  19. #include <pjsip.h>
  20. #include <pjsip_ua.h>
  21. #include <pjlib.h>
  22. #include "asterisk/res_pjsip.h"
  23. #include "asterisk/res_pjsip_session.h"
  24. #include "include/res_pjsip_private.h"
  25. #include "asterisk/linkedlists.h"
  26. #include "asterisk/lock.h"
  27. #include "asterisk/module.h"
  28. AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement);
  29. void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)
  30. {
  31. struct ast_sip_session_supplement *iter;
  32. int inserted = 0;
  33. SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
  34. if (!supplement->response_priority) {
  35. supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA;
  36. }
  37. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
  38. if (iter->priority > supplement->priority) {
  39. AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next);
  40. inserted = 1;
  41. break;
  42. }
  43. }
  44. AST_RWLIST_TRAVERSE_SAFE_END;
  45. if (!inserted) {
  46. AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next);
  47. }
  48. }
  49. int ast_sip_session_register_supplement_with_module(struct ast_module *module, struct ast_sip_session_supplement *supplement)
  50. {
  51. internal_sip_session_register_supplement(supplement);
  52. internal_res_pjsip_ref();
  53. ast_module_shutdown_ref(module);
  54. return 0;
  55. }
  56. int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
  57. {
  58. struct ast_sip_session_supplement *iter;
  59. int res = -1;
  60. SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
  61. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
  62. if (supplement == iter) {
  63. AST_RWLIST_REMOVE_CURRENT(next);
  64. res = 0;
  65. break;
  66. }
  67. }
  68. AST_RWLIST_TRAVERSE_SAFE_END;
  69. return res;
  70. }
  71. void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
  72. {
  73. if (!internal_sip_session_unregister_supplement(supplement)) {
  74. internal_res_pjsip_unref();
  75. }
  76. }
  77. static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src)
  78. {
  79. struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst));
  80. if (!dst) {
  81. return NULL;
  82. }
  83. /* Will need to revisit if shallow copy becomes an issue */
  84. *dst = *src;
  85. return dst;
  86. }
  87. int ast_sip_session_add_supplements(struct ast_sip_session *session)
  88. {
  89. struct ast_sip_session_supplement *iter;
  90. SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
  91. AST_RWLIST_TRAVERSE(&session_supplements, iter, next) {
  92. struct ast_sip_session_supplement *copy = supplement_dup(iter);
  93. if (!copy) {
  94. return -1;
  95. }
  96. AST_LIST_INSERT_TAIL(&session->supplements, copy, next);
  97. }
  98. return 0;
  99. }
  100. /* This stub is for ABI compatibility. */
  101. #undef ast_sip_session_register_supplement
  102. int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement);
  103. int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)
  104. {
  105. return ast_sip_session_register_supplement_with_module(NULL, supplement);
  106. }