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