diff options
Diffstat (limited to 'res/res_pjsip')
-rw-r--r-- | res/res_pjsip/include/res_pjsip_private.h | 26 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_message_filter.c | 24 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_session.c | 121 |
3 files changed, 155 insertions, 16 deletions
diff --git a/res/res_pjsip/include/res_pjsip_private.h b/res/res_pjsip/include/res_pjsip_private.h index 9fd7aed97..5ce3c6faf 100644 --- a/res/res_pjsip/include/res_pjsip_private.h +++ b/res/res_pjsip/include/res_pjsip_private.h @@ -328,6 +328,18 @@ int internal_sip_unregister_service(pjsip_module *module); /*! * \internal + * \brief Used by res_pjsip.so to register a supplement without adding a self reference + */ +void internal_sip_register_supplement(struct ast_sip_supplement *supplement); + +/*! + * \internal + * \brief Used by res_pjsip.so to unregister a supplement without removing a self reference + */ +int internal_sip_unregister_supplement(struct ast_sip_supplement *supplement); + +/*! + * \internal * \brief Used by res_pjsip.so to register an endpoint formatter without adding a self reference */ void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj); @@ -338,6 +350,20 @@ void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter */ int internal_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj); +struct ast_sip_session_supplement; + +/*! + * \internal + * \brief Used by res_pjsip.so to register a session supplement without adding a self reference + */ +void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement); + +/*! + * \internal + * \brief Used by res_pjsip.so to unregister a session supplement without removing a self reference + */ +int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement); + /*! * \internal * \brief Finds or creates contact_status for a contact diff --git a/res/res_pjsip/pjsip_message_filter.c b/res/res_pjsip/pjsip_message_filter.c index d2f9b9562..978aeb070 100644 --- a/res/res_pjsip/pjsip_message_filter.c +++ b/res/res_pjsip/pjsip_message_filter.c @@ -505,32 +505,24 @@ static pj_bool_t filter_on_rx_message(pjsip_rx_data *rdata) void ast_res_pjsip_cleanup_message_filter(void) { - ast_sip_unregister_service(&filter_module_tsx); - ast_sip_unregister_service(&filter_module_transport); - ast_sip_unregister_supplement(&filter_supplement); - ast_sip_session_unregister_supplement(&filter_session_supplement); + internal_sip_unregister_service(&filter_module_tsx); + internal_sip_unregister_service(&filter_module_transport); + internal_sip_unregister_supplement(&filter_supplement); + internal_sip_session_unregister_supplement(&filter_session_supplement); } int ast_res_pjsip_init_message_filter(void) { - if (ast_sip_session_register_supplement(&filter_session_supplement)) { - ast_log(LOG_ERROR, "Could not register message filter session supplement for outgoing requests\n"); - return -1; - } - - if (ast_sip_register_supplement(&filter_supplement)) { - ast_log(LOG_ERROR, "Could not register message filter supplement for outgoing requests\n"); - ast_res_pjsip_cleanup_message_filter(); - return -1; - } + internal_sip_session_register_supplement(&filter_session_supplement); + internal_sip_register_supplement(&filter_supplement); - if (ast_sip_register_service(&filter_module_transport)) { + if (internal_sip_register_service(&filter_module_transport)) { ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); ast_res_pjsip_cleanup_message_filter(); return -1; } - if (ast_sip_register_service(&filter_module_tsx)) { + if (internal_sip_register_service(&filter_module_tsx)) { ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); ast_res_pjsip_cleanup_message_filter(); return -1; diff --git a/res/res_pjsip/pjsip_session.c b/res/res_pjsip/pjsip_session.c new file mode 100644 index 000000000..cea72436a --- /dev/null +++ b/res/res_pjsip/pjsip_session.c @@ -0,0 +1,121 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2017, CFWare, LLC + * + * Corey Farrell <git@cfware.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +#include "asterisk.h" + +#include <pjsip.h> +#include <pjsip_ua.h> +#include <pjlib.h> + +#include "asterisk/res_pjsip.h" +#include "asterisk/res_pjsip_session.h" +#include "include/res_pjsip_private.h" +#include "asterisk/linkedlists.h" +#include "asterisk/lock.h" +#include "asterisk/module.h" + + +AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement); + +void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) +{ + struct ast_sip_session_supplement *iter; + int inserted = 0; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); + + if (!supplement->response_priority) { + supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA; + } + + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { + if (iter->priority > supplement->priority) { + AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next); + inserted = 1; + break; + } + } + AST_RWLIST_TRAVERSE_SAFE_END; + + if (!inserted) { + AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next); + } +} + +int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) +{ + internal_sip_session_register_supplement(supplement); + ast_module_ref(AST_MODULE_SELF); + + return 0; +} + +int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) +{ + struct ast_sip_session_supplement *iter; + int res = -1; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); + + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { + if (supplement == iter) { + AST_RWLIST_REMOVE_CURRENT(next); + res = 0; + break; + } + } + AST_RWLIST_TRAVERSE_SAFE_END; + + return res; +} + +void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) +{ + if (!internal_sip_session_unregister_supplement(supplement)) { + ast_module_unref(AST_MODULE_SELF); + } +} + +static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src) +{ + struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst)); + + if (!dst) { + return NULL; + } + /* Will need to revisit if shallow copy becomes an issue */ + *dst = *src; + + return dst; +} + +int ast_sip_session_add_supplements(struct ast_sip_session *session) +{ + struct ast_sip_session_supplement *iter; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); + + AST_RWLIST_TRAVERSE(&session_supplements, iter, next) { + struct ast_sip_session_supplement *copy = supplement_dup(iter); + + if (!copy) { + return -1; + } + AST_LIST_INSERT_TAIL(&session->supplements, copy, next); + } + + return 0; +} + |