AST-2018-005: res_pjsip_transport_management: Move to core
[asterisk/asterisk.git] / res / res_pjsip / pjsip_session.c
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
19 #include "asterisk.h"
20
21 #include <pjsip.h>
22 #include <pjsip_ua.h>
23 #include <pjlib.h>
24
25 #include "asterisk/res_pjsip.h"
26 #include "asterisk/res_pjsip_session.h"
27 #include "include/res_pjsip_private.h"
28 #include "asterisk/linkedlists.h"
29 #include "asterisk/lock.h"
30 #include "asterisk/module.h"
31
32
33 AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement);
34
35 void ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)
36 {
37         struct ast_sip_session_supplement *iter;
38         int inserted = 0;
39         SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
40
41         if (!supplement->response_priority) {
42                 supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA;
43         }
44
45         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
46                 if (iter->priority > supplement->priority) {
47                         AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next);
48                         inserted = 1;
49                         break;
50                 }
51         }
52         AST_RWLIST_TRAVERSE_SAFE_END;
53
54         if (!inserted) {
55                 AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next);
56         }
57 }
58
59 void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
60 {
61         struct ast_sip_session_supplement *iter;
62         SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
63
64         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
65                 if (supplement == iter) {
66                         AST_RWLIST_REMOVE_CURRENT(next);
67                         break;
68                 }
69         }
70         AST_RWLIST_TRAVERSE_SAFE_END;
71 }
72
73 static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src)
74 {
75         struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst));
76
77         if (!dst) {
78                 return NULL;
79         }
80         /* Will need to revisit if shallow copy becomes an issue */
81         *dst = *src;
82
83         return dst;
84 }
85
86 int ast_sip_session_add_supplements(struct ast_sip_session *session)
87 {
88         struct ast_sip_session_supplement *iter;
89         SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
90
91         AST_RWLIST_TRAVERSE(&session_supplements, iter, next) {
92                 struct ast_sip_session_supplement *copy = supplement_dup(iter);
93
94                 if (!copy) {
95                         return -1;
96                 }
97                 AST_LIST_INSERT_TAIL(&session->supplements, copy, next);
98         }
99
100         return 0;
101 }