CLI: Create ast_cli_completion_add function.
[asterisk/asterisk.git] / main / sdp_options.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2017, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.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 "asterisk/utils.h"
22 #include "asterisk/sdp_options.h"
23
24 #include "sdp_private.h"
25
26 #define DEFAULT_DTMF AST_SDP_DTMF_NONE
27 #define DEFAULT_ICE AST_SDP_ICE_DISABLED
28 #define DEFAULT_IMPL AST_SDP_IMPL_STRING
29 #define DEFAULT_ENCRYPTION AST_SDP_ENCRYPTION_DISABLED
30 #define DEFAULT_MAX_STREAMS 16  /* Set to match our PJPROJECT PJMEDIA_MAX_SDP_MEDIA. */
31
32 #define DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(field, assert_on_null) \
33 void ast_sdp_options_set_##field(struct ast_sdp_options *options, const char *value) \
34 { \
35         ast_assert(options != NULL); \
36         if ((assert_on_null)) ast_assert(!ast_strlen_zero(value)); \
37         if (!strcmp(value, options->field)) return; \
38         ast_string_field_set(options, field, value); \
39 } \
40 const char *ast_sdp_options_get_##field(const struct ast_sdp_options *options) \
41 { \
42         ast_assert(options != NULL); \
43         return options->field; \
44 } \
45
46 #define DEFINE_GETTERS_SETTERS_FOR(type, field) \
47 void ast_sdp_options_set_##field(struct ast_sdp_options *options, type value) \
48 { \
49         ast_assert(options != NULL); \
50         options->field = value; \
51 } \
52 type ast_sdp_options_get_##field(const struct ast_sdp_options *options) \
53 { \
54         ast_assert(options != NULL); \
55         return options->field; \
56 } \
57
58 DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(media_address, 0);
59 DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(interface_address, 0);
60 DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(sdpowner, 0);
61 DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(sdpsession, 0);
62 DEFINE_STRINGFIELD_GETTERS_SETTERS_FOR(rtp_engine, 0);
63
64 DEFINE_GETTERS_SETTERS_FOR(void *, state_context);
65 DEFINE_GETTERS_SETTERS_FOR(ast_sdp_answerer_modify_cb, answerer_modify_cb);
66 DEFINE_GETTERS_SETTERS_FOR(ast_sdp_offerer_modify_cb, offerer_modify_cb);
67 DEFINE_GETTERS_SETTERS_FOR(ast_sdp_offerer_config_cb, offerer_config_cb);
68 DEFINE_GETTERS_SETTERS_FOR(ast_sdp_preapply_cb, preapply_cb);
69 DEFINE_GETTERS_SETTERS_FOR(ast_sdp_postapply_cb, postapply_cb);
70 DEFINE_GETTERS_SETTERS_FOR(unsigned int, rtp_symmetric);
71 DEFINE_GETTERS_SETTERS_FOR(unsigned int, udptl_symmetric);
72 DEFINE_GETTERS_SETTERS_FOR(enum ast_t38_ec_modes, udptl_error_correction);
73 DEFINE_GETTERS_SETTERS_FOR(unsigned int, udptl_far_max_datagram);
74 DEFINE_GETTERS_SETTERS_FOR(unsigned int, rtp_ipv6);
75 DEFINE_GETTERS_SETTERS_FOR(unsigned int, g726_non_standard);
76 DEFINE_GETTERS_SETTERS_FOR(unsigned int, rtcp_mux);
77 DEFINE_GETTERS_SETTERS_FOR(unsigned int, tos_audio);
78 DEFINE_GETTERS_SETTERS_FOR(unsigned int, cos_audio);
79 DEFINE_GETTERS_SETTERS_FOR(unsigned int, tos_video);
80 DEFINE_GETTERS_SETTERS_FOR(unsigned int, cos_video);
81 DEFINE_GETTERS_SETTERS_FOR(unsigned int, max_streams);
82 DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_dtmf, dtmf);
83 DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_ice, ice);
84 DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_impl, impl);
85 DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_encryption, encryption);
86 DEFINE_GETTERS_SETTERS_FOR(unsigned int, ssrc);
87
88 struct ast_sched_context *ast_sdp_options_get_sched_type(const struct ast_sdp_options *options, enum ast_media_type type)
89 {
90         struct ast_sched_context *sched = NULL;
91
92         switch (type) {
93         case AST_MEDIA_TYPE_AUDIO:
94         case AST_MEDIA_TYPE_VIDEO:
95         case AST_MEDIA_TYPE_IMAGE:
96         case AST_MEDIA_TYPE_TEXT:
97                 sched = options->sched[type];
98                 break;
99         case AST_MEDIA_TYPE_UNKNOWN:
100         case AST_MEDIA_TYPE_END:
101                 break;
102         }
103         return sched;
104 }
105
106 void ast_sdp_options_set_sched_type(struct ast_sdp_options *options, enum ast_media_type type, struct ast_sched_context *sched)
107 {
108         switch (type) {
109         case AST_MEDIA_TYPE_AUDIO:
110         case AST_MEDIA_TYPE_VIDEO:
111         case AST_MEDIA_TYPE_IMAGE:
112         case AST_MEDIA_TYPE_TEXT:
113                 options->sched[type] = sched;
114                 break;
115         case AST_MEDIA_TYPE_UNKNOWN:
116         case AST_MEDIA_TYPE_END:
117                 break;
118         }
119 }
120
121 struct ast_format_cap *ast_sdp_options_get_format_cap_type(const struct ast_sdp_options *options,
122         enum ast_media_type type)
123 {
124         struct ast_format_cap *cap = NULL;
125
126         switch (type) {
127         case AST_MEDIA_TYPE_AUDIO:
128         case AST_MEDIA_TYPE_VIDEO:
129         case AST_MEDIA_TYPE_IMAGE:
130         case AST_MEDIA_TYPE_TEXT:
131                 cap = options->caps[type];
132                 break;
133         case AST_MEDIA_TYPE_UNKNOWN:
134         case AST_MEDIA_TYPE_END:
135                 break;
136         }
137         return cap;
138 }
139
140 void ast_sdp_options_set_format_cap_type(struct ast_sdp_options *options,
141         enum ast_media_type type, struct ast_format_cap *cap)
142 {
143         switch (type) {
144         case AST_MEDIA_TYPE_AUDIO:
145         case AST_MEDIA_TYPE_VIDEO:
146         case AST_MEDIA_TYPE_IMAGE:
147         case AST_MEDIA_TYPE_TEXT:
148                 ao2_cleanup(options->caps[type]);
149                 options->caps[type] = NULL;
150                 if (cap && !ast_format_cap_empty(cap)) {
151                         ao2_ref(cap, +1);
152                         options->caps[type] = cap;
153                 }
154                 break;
155         case AST_MEDIA_TYPE_UNKNOWN:
156         case AST_MEDIA_TYPE_END:
157                 break;
158         }
159 }
160
161 void ast_sdp_options_set_format_caps(struct ast_sdp_options *options,
162         struct ast_format_cap *cap)
163 {
164         enum ast_media_type type;
165
166         for (type = AST_MEDIA_TYPE_UNKNOWN; type < AST_MEDIA_TYPE_END; ++type) {
167                 ao2_cleanup(options->caps[type]);
168                 options->caps[type] = NULL;
169         }
170
171         if (!cap || ast_format_cap_empty(cap)) {
172                 return;
173         }
174
175         for (type = AST_MEDIA_TYPE_UNKNOWN + 1; type < AST_MEDIA_TYPE_END; ++type) {
176                 struct ast_format_cap *type_cap;
177
178                 type_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
179                 if (!type_cap) {
180                         continue;
181                 }
182
183                 ast_format_cap_set_framing(type_cap, ast_format_cap_get_framing(cap));
184                 if (ast_format_cap_append_from_cap(type_cap, cap, type)
185                         || ast_format_cap_empty(type_cap)) {
186                         ao2_ref(type_cap, -1);
187                         continue;
188                 }
189
190                 /* This takes the allocation reference */
191                 options->caps[type] = type_cap;
192         }
193 }
194
195 static void set_defaults(struct ast_sdp_options *options)
196 {
197         options->dtmf = DEFAULT_DTMF;
198         options->ice = DEFAULT_ICE;
199         options->impl = DEFAULT_IMPL;
200         options->encryption = DEFAULT_ENCRYPTION;
201         options->max_streams = DEFAULT_MAX_STREAMS;
202 }
203
204 struct ast_sdp_options *ast_sdp_options_alloc(void)
205 {
206         struct ast_sdp_options *options;
207
208         options = ast_calloc(1, sizeof(*options));
209         if (!options) {
210                 return NULL;
211         }
212
213         if (ast_string_field_init(options, 256)) {
214                 ast_free(options);
215                 return NULL;
216         }
217
218         set_defaults(options);
219         return options;
220 }
221
222 void ast_sdp_options_free(struct ast_sdp_options *options)
223 {
224         enum ast_media_type type;
225
226         if (!options) {
227                 return;
228         }
229
230         for (type = AST_MEDIA_TYPE_UNKNOWN; type < AST_MEDIA_TYPE_END; ++type) {
231                 ao2_cleanup(options->caps[type]);
232         }
233         ast_string_field_free_memory(options);
234         ast_free(options);
235 }