1 /*
2 linphone
3 Copyright (C) 2010-2014 Belledonne Communications SARL
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include "linphone/call_params.h"
21 #include "private.h"
22
23
24 /*******************************************************************************
25 * Internal functions *
26 ******************************************************************************/
27
get_proto_from_call_params(const LinphoneCallParams * params)28 SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params) {
29 if ((params->media_encryption == LinphoneMediaEncryptionSRTP) && params->avpf_enabled) return SalProtoRtpSavpf;
30 if (params->media_encryption == LinphoneMediaEncryptionSRTP) return SalProtoRtpSavp;
31 if ((params->media_encryption == LinphoneMediaEncryptionDTLS) && params->avpf_enabled) return SalProtoUdpTlsRtpSavpf;
32 if (params->media_encryption == LinphoneMediaEncryptionDTLS) return SalProtoUdpTlsRtpSavp;
33 if (params->avpf_enabled) return SalProtoRtpAvpf;
34 return SalProtoRtpAvp;
35 }
36
sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir)37 SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir) {
38 switch (cpdir) {
39 case LinphoneMediaDirectionInactive:
40 return SalStreamInactive;
41 case LinphoneMediaDirectionSendOnly:
42 return SalStreamSendOnly;
43 case LinphoneMediaDirectionRecvOnly:
44 return SalStreamRecvOnly;
45 case LinphoneMediaDirectionSendRecv:
46 return SalStreamSendRecv;
47 case LinphoneMediaDirectionInvalid:
48 ms_error("LinphoneMediaDirectionInvalid shall not be used.");
49 return SalStreamInactive;
50 }
51 return SalStreamSendRecv;
52 }
53
media_direction_from_sal_stream_dir(SalStreamDir dir)54 LinphoneMediaDirection media_direction_from_sal_stream_dir(SalStreamDir dir){
55 switch (dir) {
56 case SalStreamInactive:
57 return LinphoneMediaDirectionInactive;
58 case SalStreamSendOnly:
59 return LinphoneMediaDirectionSendOnly;
60 case SalStreamRecvOnly:
61 return LinphoneMediaDirectionRecvOnly;
62 case SalStreamSendRecv:
63 return LinphoneMediaDirectionSendRecv;
64 }
65 return LinphoneMediaDirectionSendRecv;
66 }
67
get_audio_dir_from_call_params(const LinphoneCallParams * params)68 SalStreamDir get_audio_dir_from_call_params(const LinphoneCallParams *params) {
69 return sal_dir_from_call_params_dir(linphone_call_params_get_audio_direction(params));
70 }
71
get_video_dir_from_call_params(const LinphoneCallParams * params)72 SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params) {
73 return sal_dir_from_call_params_dir(linphone_call_params_get_video_direction(params));
74 }
75
linphone_call_params_set_custom_headers(LinphoneCallParams * params,const SalCustomHeader * ch)76 void linphone_call_params_set_custom_headers(LinphoneCallParams *params, const SalCustomHeader *ch){
77 if (params->custom_headers){
78 sal_custom_header_free(params->custom_headers);
79 params->custom_headers = NULL;
80 }
81 if (ch){
82 params->custom_headers = sal_custom_header_clone(ch);
83 }
84 }
85
linphone_call_params_set_custom_sdp_attributes(LinphoneCallParams * params,const SalCustomSdpAttribute * csa)86 void linphone_call_params_set_custom_sdp_attributes(LinphoneCallParams *params, const SalCustomSdpAttribute *csa) {
87 if (params->custom_sdp_attributes) {
88 sal_custom_sdp_attribute_free(params->custom_sdp_attributes);
89 params->custom_sdp_attributes = NULL;
90 }
91 if (csa) {
92 params->custom_sdp_attributes = sal_custom_sdp_attribute_clone(csa);
93 }
94 }
95
linphone_call_params_set_custom_sdp_media_attributes(LinphoneCallParams * params,LinphoneStreamType type,const SalCustomSdpAttribute * csa)96 void linphone_call_params_set_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type, const SalCustomSdpAttribute *csa) {
97 if (params->custom_sdp_media_attributes[type]) {
98 sal_custom_sdp_attribute_free(params->custom_sdp_media_attributes[type]);
99 params->custom_sdp_media_attributes[type] = NULL;
100 }
101 if (csa) {
102 params->custom_sdp_media_attributes[type] = sal_custom_sdp_attribute_clone(csa);
103 }
104 }
105
106
107 /*******************************************************************************
108 * Public functions *
109 ******************************************************************************/
110
linphone_call_params_add_custom_header(LinphoneCallParams * params,const char * header_name,const char * header_value)111 void linphone_call_params_add_custom_header(LinphoneCallParams *params, const char *header_name, const char *header_value){
112 params->custom_headers=sal_custom_header_append(params->custom_headers,header_name,header_value);
113 }
114
linphone_call_params_add_custom_sdp_attribute(LinphoneCallParams * params,const char * attribute_name,const char * attribute_value)115 void linphone_call_params_add_custom_sdp_attribute(LinphoneCallParams *params, const char *attribute_name, const char *attribute_value) {
116 params->custom_sdp_attributes = sal_custom_sdp_attribute_append(params->custom_sdp_attributes, attribute_name, attribute_value);
117 }
118
linphone_call_params_add_custom_sdp_media_attribute(LinphoneCallParams * params,LinphoneStreamType type,const char * attribute_name,const char * attribute_value)119 void linphone_call_params_add_custom_sdp_media_attribute(LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name, const char *attribute_value) {
120 params->custom_sdp_media_attributes[type] = sal_custom_sdp_attribute_append(params->custom_sdp_media_attributes[type], attribute_name, attribute_value);
121 }
122
linphone_call_params_clear_custom_sdp_attributes(LinphoneCallParams * params)123 void linphone_call_params_clear_custom_sdp_attributes(LinphoneCallParams *params) {
124 linphone_call_params_set_custom_sdp_attributes(params, NULL);
125 }
126
linphone_call_params_clear_custom_sdp_media_attributes(LinphoneCallParams * params,LinphoneStreamType type)127 void linphone_call_params_clear_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type) {
128 linphone_call_params_set_custom_sdp_media_attributes(params, type, NULL);
129 }
130
linphone_call_params_copy(const LinphoneCallParams * cp)131 LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){
132 return (LinphoneCallParams *)belle_sip_object_clone((const belle_sip_object_t *)cp);
133 }
134
linphone_call_params_early_media_sending_enabled(const LinphoneCallParams * cp)135 bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp){
136 return cp->real_early_media;
137 }
138
linphone_call_params_enable_early_media_sending(LinphoneCallParams * cp,bool_t enabled)139 void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled){
140 cp->real_early_media=enabled;
141 }
142
linphone_call_params_enable_low_bandwidth(LinphoneCallParams * cp,bool_t enabled)143 void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled){
144 cp->low_bandwidth=enabled;
145 }
146
linphone_call_params_enable_audio(LinphoneCallParams * cp,bool_t enabled)147 void linphone_call_params_enable_audio(LinphoneCallParams *cp, bool_t enabled){
148 cp->has_audio=enabled;
149 if (enabled && cp->audio_dir==LinphoneMediaDirectionInactive)
150 cp->audio_dir=LinphoneMediaDirectionSendRecv;
151 }
152
linphone_call_params_enable_realtime_text(LinphoneCallParams * params,bool_t yesno)153 LinphoneStatus linphone_call_params_enable_realtime_text(LinphoneCallParams *params, bool_t yesno) {
154 params->realtimetext_enabled=yesno;
155 return 0;
156 }
157
linphone_call_params_enable_video(LinphoneCallParams * cp,bool_t enabled)158 void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
159 cp->has_video=enabled;
160 if (enabled && cp->video_dir==LinphoneMediaDirectionInactive)
161 cp->video_dir=LinphoneMediaDirectionSendRecv;
162 }
163
linphone_call_params_get_custom_header(const LinphoneCallParams * params,const char * header_name)164 const char *linphone_call_params_get_custom_header(const LinphoneCallParams *params, const char *header_name){
165 return sal_custom_header_find(params->custom_headers,header_name);
166 }
167
linphone_call_params_get_custom_sdp_attribute(const LinphoneCallParams * params,const char * attribute_name)168 const char * linphone_call_params_get_custom_sdp_attribute(const LinphoneCallParams *params, const char *attribute_name) {
169 return sal_custom_sdp_attribute_find(params->custom_sdp_attributes, attribute_name);
170 }
171
linphone_call_params_get_custom_sdp_media_attribute(const LinphoneCallParams * params,LinphoneStreamType type,const char * attribute_name)172 const char * linphone_call_params_get_custom_sdp_media_attribute(const LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name) {
173 return sal_custom_sdp_attribute_find(params->custom_sdp_media_attributes[type], attribute_name);
174 }
175
linphone_call_params_get_local_conference_mode(const LinphoneCallParams * cp)176 bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp){
177 return cp->in_conference;
178 }
179
linphone_call_params_get_media_encryption(const LinphoneCallParams * cp)180 LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp) {
181 return cp->media_encryption;
182 }
183
linphone_call_params_get_privacy(const LinphoneCallParams * params)184 LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params) {
185 return params->privacy;
186 }
187
linphone_call_params_get_received_framerate(const LinphoneCallParams * cp)188 float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp){
189 return cp->received_fps;
190 }
191
linphone_call_params_get_received_video_size(const LinphoneCallParams * cp)192 MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp) {
193 return cp->recv_vsize;
194 }
195
linphone_call_params_get_received_video_definition(const LinphoneCallParams * cp)196 const LinphoneVideoDefinition * linphone_call_params_get_received_video_definition(const LinphoneCallParams *cp) {
197 return cp->recv_vdef;
198 }
199
linphone_call_params_get_record_file(const LinphoneCallParams * cp)200 const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp){
201 return cp->record_file;
202 }
203
linphone_call_params_get_rtp_profile(const LinphoneCallParams * cp)204 const char * linphone_call_params_get_rtp_profile(const LinphoneCallParams *cp) {
205 return sal_media_proto_to_string(get_proto_from_call_params(cp));
206 }
207
linphone_call_params_get_sent_framerate(const LinphoneCallParams * cp)208 float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp){
209 return cp->sent_fps;
210 }
211
linphone_call_params_get_sent_video_size(const LinphoneCallParams * cp)212 MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp) {
213 return cp->sent_vsize;
214 }
215
linphone_call_params_get_sent_video_definition(const LinphoneCallParams * cp)216 const LinphoneVideoDefinition * linphone_call_params_get_sent_video_definition(const LinphoneCallParams *cp) {
217 return cp->sent_vdef;
218 }
219
linphone_call_params_get_session_name(const LinphoneCallParams * cp)220 const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp){
221 return cp->session_name;
222 }
223
linphone_call_params_get_used_audio_payload_type(const LinphoneCallParams * cp)224 LinphonePayloadType *linphone_call_params_get_used_audio_payload_type(const LinphoneCallParams *cp) {
225 return cp->audio_codec ? linphone_payload_type_new(NULL, cp->audio_codec) : NULL;
226 }
227
linphone_call_params_get_used_video_payload_type(const LinphoneCallParams * cp)228 LinphonePayloadType *linphone_call_params_get_used_video_payload_type(const LinphoneCallParams *cp) {
229 return cp->video_codec ? linphone_payload_type_new(NULL, cp->video_codec) : NULL;
230 }
231
linphone_call_params_get_used_text_payload_type(const LinphoneCallParams * cp)232 LinphonePayloadType *linphone_call_params_get_used_text_payload_type(const LinphoneCallParams *cp) {
233 return cp->text_codec ? linphone_payload_type_new(NULL, cp->text_codec) : NULL;
234 }
235
linphone_call_params_get_used_audio_codec(const LinphoneCallParams * cp)236 const OrtpPayloadType *linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) {
237 return cp->audio_codec;
238 }
239
linphone_call_params_get_used_video_codec(const LinphoneCallParams * cp)240 const OrtpPayloadType *linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) {
241 return cp->video_codec;
242 }
243
linphone_call_params_get_used_text_codec(const LinphoneCallParams * cp)244 const OrtpPayloadType *linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp) {
245 return cp->text_codec;
246 }
247
248
linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams * cp)249 bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp) {
250 return cp->low_bandwidth;
251 }
252
linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams * cp,int bandwidth)253 void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bandwidth){
254 cp->audio_bw=bandwidth;
255 }
256
linphone_call_params_set_media_encryption(LinphoneCallParams * cp,LinphoneMediaEncryption e)257 void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption e) {
258 cp->media_encryption = e;
259 }
260
linphone_call_params_set_privacy(LinphoneCallParams * params,LinphonePrivacyMask privacy)261 void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy) {
262 params->privacy=privacy;
263 }
264
linphone_call_params_set_record_file(LinphoneCallParams * cp,const char * path)265 void linphone_call_params_set_record_file(LinphoneCallParams *cp, const char *path){
266 if (cp->record_file){
267 ms_free(cp->record_file);
268 cp->record_file=NULL;
269 }
270 if (path) cp->record_file=ms_strdup(path);
271 }
272
linphone_call_params_set_session_name(LinphoneCallParams * cp,const char * name)273 void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name){
274 if (cp->session_name){
275 ms_free(cp->session_name);
276 cp->session_name=NULL;
277 }
278 if (name) cp->session_name=ms_strdup(name);
279 }
280
linphone_call_params_audio_enabled(const LinphoneCallParams * cp)281 bool_t linphone_call_params_audio_enabled(const LinphoneCallParams *cp){
282 return cp->has_audio;
283 }
284
linphone_call_params_realtime_text_enabled(const LinphoneCallParams * params)285 bool_t linphone_call_params_realtime_text_enabled(const LinphoneCallParams *params) {
286 return params->realtimetext_enabled;
287 }
288
linphone_call_params_video_enabled(const LinphoneCallParams * cp)289 bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
290 return cp->has_video;
291 }
292
linphone_call_params_get_audio_direction(const LinphoneCallParams * cp)293 LinphoneMediaDirection linphone_call_params_get_audio_direction(const LinphoneCallParams *cp) {
294 return cp->audio_dir;
295 }
296
linphone_call_params_get_video_direction(const LinphoneCallParams * cp)297 LinphoneMediaDirection linphone_call_params_get_video_direction(const LinphoneCallParams *cp) {
298 return cp->video_dir;
299 }
300
linphone_call_params_set_audio_direction(LinphoneCallParams * cp,LinphoneMediaDirection dir)301 void linphone_call_params_set_audio_direction(LinphoneCallParams *cp,LinphoneMediaDirection dir) {
302 cp->audio_dir=dir;
303 }
304
linphone_call_params_set_video_direction(LinphoneCallParams * cp,LinphoneMediaDirection dir)305 void linphone_call_params_set_video_direction(LinphoneCallParams *cp,LinphoneMediaDirection dir) {
306 cp->video_dir=dir;
307 }
308
309
310 /*******************************************************************************
311 * Reference and user data handling functions *
312 ******************************************************************************/
313
linphone_call_params_get_user_data(const LinphoneCallParams * cp)314 void *linphone_call_params_get_user_data(const LinphoneCallParams *cp) {
315 return cp->user_data;
316 }
317
linphone_call_params_set_user_data(LinphoneCallParams * cp,void * ud)318 void linphone_call_params_set_user_data(LinphoneCallParams *cp, void *ud) {
319 cp->user_data = ud;
320 }
321
linphone_call_params_ref(LinphoneCallParams * cp)322 LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp) {
323 belle_sip_object_ref(cp);
324 return cp;
325 }
326
linphone_call_params_unref(LinphoneCallParams * cp)327 void linphone_call_params_unref(LinphoneCallParams *cp) {
328 belle_sip_object_unref(cp);
329 }
330
linphone_call_params_enable_audio_multicast(LinphoneCallParams * params,bool_t yesno)331 void linphone_call_params_enable_audio_multicast(LinphoneCallParams *params, bool_t yesno) {
332 params->audio_multicast_enabled=yesno;
333 }
334
linphone_call_params_audio_multicast_enabled(const LinphoneCallParams * params)335 bool_t linphone_call_params_audio_multicast_enabled(const LinphoneCallParams *params) {
336 return params->audio_multicast_enabled;
337 }
338
linphone_call_params_enable_video_multicast(LinphoneCallParams * params,bool_t yesno)339 void linphone_call_params_enable_video_multicast(LinphoneCallParams *params, bool_t yesno) {
340 params->video_multicast_enabled=yesno;
341 }
linphone_call_params_video_multicast_enabled(const LinphoneCallParams * params)342 bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *params) {
343 return params->video_multicast_enabled;
344 }
345
346 /*******************************************************************************
347 * Constructor and destructor functions *
348 ******************************************************************************/
349
_linphone_call_params_uninit(LinphoneCallParams * cp)350 static void _linphone_call_params_uninit(LinphoneCallParams *cp){
351 unsigned int i;
352 if (cp->record_file) ms_free(cp->record_file);
353 if (cp->custom_headers) sal_custom_header_free(cp->custom_headers);
354 if (cp->custom_sdp_attributes) sal_custom_sdp_attribute_free(cp->custom_sdp_attributes);
355 for (i = 0; i < (unsigned int)LinphoneStreamTypeUnknown; i++) {
356 if (cp->custom_sdp_media_attributes[i]) sal_custom_sdp_attribute_free(cp->custom_sdp_media_attributes[i]);
357 }
358 if (cp->session_name) ms_free(cp->session_name);
359 if (cp->sent_vdef != NULL) linphone_video_definition_unref(cp->sent_vdef);
360 if (cp->recv_vdef != NULL) linphone_video_definition_unref(cp->recv_vdef);
361 }
362
_linphone_call_params_clone(LinphoneCallParams * dst,const LinphoneCallParams * src)363 static void _linphone_call_params_clone(LinphoneCallParams *dst, const LinphoneCallParams *src) {
364 unsigned int i;
365
366 /*
367 * Save the belle_sip_object_t part, copy the entire structure and restore the belle_sip_object_t part
368 */
369 belle_sip_object_t tmp = dst->base;
370 memcpy(dst, src, sizeof(LinphoneCallParams));
371 dst->base = tmp;
372
373 if (src->sent_vdef) dst->sent_vdef = linphone_video_definition_ref(src->sent_vdef);
374 if (src->recv_vdef) dst->recv_vdef = linphone_video_definition_ref(src->recv_vdef);
375 if (src->record_file) dst->record_file=ms_strdup(src->record_file);
376 if (src->session_name) dst->session_name=ms_strdup(src->session_name);
377 /*
378 * The management of the custom headers is not optimal. We copy everything while ref counting would be more efficient.
379 */
380 if (src->custom_headers) dst->custom_headers=sal_custom_header_clone(src->custom_headers);
381 if (src->custom_sdp_attributes) dst->custom_sdp_attributes = sal_custom_sdp_attribute_clone(src->custom_sdp_attributes);
382 for (i = 0; i < (unsigned int)LinphoneStreamTypeUnknown; i++) {
383 if (src->custom_sdp_media_attributes[i]) dst->custom_sdp_media_attributes[i] = sal_custom_sdp_attribute_clone(src->custom_sdp_media_attributes[i]);
384 }
385 }
386
linphone_call_params_new(void)387 LinphoneCallParams * linphone_call_params_new(void) {
388 LinphoneCallParams *cp=belle_sip_object_new(LinphoneCallParams);
389 cp->audio_dir=LinphoneMediaDirectionSendRecv;
390 cp->video_dir=LinphoneMediaDirectionSendRecv;
391 cp->has_audio=TRUE;
392 cp->realtimetext_enabled = FALSE;
393 return cp;
394 }
395
396 /* DEPRECATED */
linphone_call_params_destroy(LinphoneCallParams * cp)397 void linphone_call_params_destroy(LinphoneCallParams *cp) {
398 linphone_call_params_unref(cp);
399 }
400
401 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallParams);
402
403 BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallParams, belle_sip_object_t,
404 (belle_sip_object_destroy_t)_linphone_call_params_uninit,
405 (belle_sip_object_clone_t)_linphone_call_params_clone, // clone
406 NULL, // marshal
407 FALSE
408 );
409