linphonecall.c 197 KB
Newer Older
1 2 3

/*
linphone
4
Copyright (C) 2010  Belledonne Communications SARL
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 (simon.morlat@linphone.org)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
21
#ifdef _WIN32
22 23
#include <time.h>
#endif
24 25 26 27
#include "linphonecore.h"
#include "sipsetup.h"
#include "lpconfig.h"
#include "private.h"
28
#include "conference_private.h"
29
#include <ortp/event.h>
30
#include <ortp/b64.h>
Yann Diorcet's avatar
Yann Diorcet committed
31
#include <math.h>
32

33 34 35
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msequalizer.h"
36
#include "mediastreamer2/msfileplayer.h"
37
#include "mediastreamer2/msjpegwriter.h"
38
#include "mediastreamer2/mseventqueue.h"
39
#include "mediastreamer2/mssndcard.h"
40
#include "mediastreamer2/msrtt4103.h"
41

42
static const char *EC_STATE_STORE = ".linphone.ecstate";
43
#define EC_STATE_MAX_LEN 1048576 // 1Mo
44

Simon Morlat's avatar
Simon Morlat committed
45
static void linphone_call_stats_uninit(LinphoneCallStats *stats);
46
static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress *remote_addr);
47
static void _linphone_call_set_next_video_frame_decoded_trigger(LinphoneCall *call);
48
void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index);
Simon Morlat's avatar
Simon Morlat committed
49

50

51
MSWebCam *get_nowebcam_device(MSFactory* f){
52
#ifdef VIDEO_ENABLED
53
	return ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(f),"StaticImage: Static picture");
54 55
#else
	return NULL;
Simon Morlat's avatar
Simon Morlat committed
56
#endif
57 58
}

59

60 61
static bool_t generate_b64_crypto_key(size_t key_length, char* key_out, size_t key_out_size) {
	size_t b64_size;
62 63
	uint8_t* tmp = (uint8_t*) ms_malloc0(key_length);
	if (sal_get_random_bytes(tmp, key_length)==NULL) {
64
		ms_error("Failed to generate random key");
65
		ms_free(tmp);
66 67
		return FALSE;
	}
68

69
	b64_size = b64_encode((const char*)tmp, key_length, NULL, 0);
70 71 72 73 74 75 76 77 78 79 80
	if (b64_size == 0) {
		ms_error("Failed to get b64 result size");
		ms_free(tmp);
		return FALSE;
	}
	if (b64_size>=key_out_size){
		ms_error("Insufficient room for writing base64 SRTP key");
		ms_free(tmp);
		return FALSE;
	}
	b64_size=b64_encode((const char*)tmp, key_length, key_out, key_out_size);
81 82
	if (b64_size == 0) {
		ms_error("Failed to b64 encode key");
83
		ms_free(tmp);
84 85 86
		return FALSE;
	}
	key_out[b64_size] = '\0';
87
	ms_free(tmp);
88 89 90
	return TRUE;
}

91 92 93 94
LinphoneCore *linphone_call_get_core(const LinphoneCall *call){
	return call->core;
}

95
const char* linphone_call_get_authentication_token(LinphoneCall *call){
96
	return call->auth_token;
97 98
}

99 100 101 102 103 104 105 106
/**
 * Returns whether ZRTP authentication token is verified.
 * If not, it must be verified by users as described in ZRTP procedure.
 * Once done, the application must inform of the results with linphone_call_set_authentication_token_verified().
 * @param call the LinphoneCall
 * @return TRUE if authentication token is verifed, false otherwise.
 * @ingroup call_control
**/
107
bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){
108
	return call->auth_token_verified;
109
}
Simon Morlat's avatar
Simon Morlat committed
110

111 112 113 114 115 116
static bool_t at_least_one_stream_started(const LinphoneCall *call){
	return (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted )
		|| (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted)
		|| (call->textstream && media_stream_get_state((MediaStream *)call->textstream) == MSStreamStarted);
}

117
static bool_t linphone_call_all_streams_encrypted(const LinphoneCall *call) {
jehan's avatar
jehan committed
118 119
	int number_of_encrypted_stream = 0;
	int number_of_active_stream = 0;
120

121 122 123 124 125 126 127 128 129 130 131 132 133 134
	if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) {
		number_of_active_stream++;
		if(media_stream_secured((MediaStream *)call->audiostream))
			number_of_encrypted_stream++;
	}
	if (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
		number_of_active_stream++;
		if (media_stream_secured((MediaStream *)call->videostream))
			number_of_encrypted_stream++;
	}
	if (call->textstream && media_stream_get_state((MediaStream *)call->textstream) == MSStreamStarted) {
		number_of_active_stream++;
		if (media_stream_secured((MediaStream *)call->textstream))
			number_of_encrypted_stream++;
135
	}
136
	return number_of_active_stream>0 && number_of_active_stream==number_of_encrypted_stream;
137 138
}

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
static bool_t linphone_call_all_streams_avpf_enabled(const LinphoneCall *call) {
	int nb_active_streams = 0;
	int nb_avpf_enabled_streams = 0;
	if (call) {
		if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) {
			nb_active_streams++;
			if (media_stream_avpf_enabled((MediaStream *)call->audiostream))
				nb_avpf_enabled_streams++;
		}
		if (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
			nb_active_streams++;
			if (media_stream_avpf_enabled((MediaStream *)call->videostream))
				nb_avpf_enabled_streams++;
		}
	}
	return ((nb_active_streams > 0) && (nb_active_streams == nb_avpf_enabled_streams));
}

157 158 159
static uint16_t linphone_call_get_avpf_rr_interval(const LinphoneCall *call) {
	uint16_t rr_interval = 0;
	uint16_t stream_rr_interval;
160 161 162 163 164 165 166 167 168 169
	if (call) {
		if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) {
			stream_rr_interval = media_stream_get_avpf_rr_interval((MediaStream *)call->audiostream);
			if (stream_rr_interval > rr_interval) rr_interval = stream_rr_interval;
		}
		if (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
			stream_rr_interval = media_stream_get_avpf_rr_interval((MediaStream *)call->videostream);
			if (stream_rr_interval > rr_interval) rr_interval = stream_rr_interval;
		}
	} else {
170
		rr_interval = 5000;
171 172 173 174
	}
	return rr_interval;
}

175
static void propagate_encryption_changed(LinphoneCall *call){
176
	if (!linphone_call_all_streams_encrypted(call)) {
177
		ms_message("Some streams are not encrypted");
178
		call->current_params->media_encryption=LinphoneMediaEncryptionNone;
179
		linphone_core_notify_call_encryption_changed(call->core, call, FALSE, call->auth_token);
180
	} else {
johan's avatar
johan committed
181 182 183 184 185
		if (call->auth_token) {/* ZRTP only is using auth_token */
			call->current_params->media_encryption=LinphoneMediaEncryptionZRTP;
		} else { /* otherwise it must be DTLS as SDES doesn't go through this function */
			call->current_params->media_encryption=LinphoneMediaEncryptionDTLS;
		}
186
		ms_message("All streams are encrypted key exchanged using %s", call->current_params->media_encryption==LinphoneMediaEncryptionZRTP?"ZRTP":call->current_params->media_encryption==LinphoneMediaEncryptionDTLS?"DTLS":"Unknown mechanism");
187
		linphone_core_notify_call_encryption_changed(call->core, call, TRUE, call->auth_token);
jehan's avatar
jehan committed
188
#ifdef VIDEO_ENABLED
189 190 191
		if (call->current_params->encryption_mandatory && call->videostream && media_stream_started((MediaStream *)call->videostream)) {
			video_stream_send_vfu(call->videostream); /*nothing could have been sent yet so generating key frame*/
		}
jehan's avatar
jehan committed
192
#endif
193 194 195 196
	}
}

static void linphone_call_audiostream_encryption_changed(void *data, bool_t encrypted) {
197
	char status[255]={0};
Sylvain Berfini's avatar
Sylvain Berfini committed
198
	LinphoneCall *call;
199

Sylvain Berfini's avatar
Sylvain Berfini committed
200
	call = (LinphoneCall *)data;
201

202
	if (encrypted) {
johan's avatar
johan committed
203 204 205 206
		if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) { /* if encryption is DTLS, no status to be displayed */
			snprintf(status,sizeof(status)-1,_("Authentication token is %s"),call->auth_token);
			linphone_core_notify_display_status(call->core, status);
		}
207 208
	}

209 210 211 212 213
	propagate_encryption_changed(call);


#ifdef VIDEO_ENABLED
	// Enable video encryption
johan's avatar
johan committed
214
	if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
215 216
		const LinphoneCallParams *params=linphone_call_get_current_params(call);
		if (params->has_video) {
johan's avatar
johan committed
217 218
			ms_message("Trying to start ZRTP encryption on video stream");
			video_stream_start_zrtp(call->videostream);
219
		}
220 221 222 223 224 225 226
	}
#endif
}


static void linphone_call_audiostream_auth_token_ready(void *data, const char* auth_token, bool_t verified) {
	LinphoneCall *call=(LinphoneCall *)data;
227 228
	if (call->auth_token != NULL)
		ms_free(call->auth_token);
229

230 231
	call->auth_token=ms_strdup(auth_token);
	call->auth_token_verified=verified;
232 233 234 235

	ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified");
}

236 237 238 239 240 241 242
/**
 * Set the result of ZRTP short code verification by user.
 * If remote party also does the same, it will update the ZRTP cache so that user's verification will not be required for the two users.
 * @param call the LinphoneCall
 * @param verified whether the ZRTP SAS is verified.
 * @ingroup call_control
**/
Simon Morlat's avatar
Simon Morlat committed
243
void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified){
244 245 246
	if (call->audiostream==NULL || !media_stream_started(&call->audiostream->ms)){
		ms_error("linphone_call_set_authentication_token_verified(): No audio stream or not started");
		return;
Simon Morlat's avatar
Simon Morlat committed
247
	}
248
	if (call->audiostream->ms.sessions.zrtp_context==NULL){
Simon Morlat's avatar
Simon Morlat committed
249
		ms_error("linphone_call_set_authentication_token_verified(): No zrtp context.");
250
		return;
Simon Morlat's avatar
Simon Morlat committed
251 252
	}
	if (!call->auth_token_verified && verified){
253
		ms_zrtp_sas_verified(call->audiostream->ms.sessions.zrtp_context);
Simon Morlat's avatar
Simon Morlat committed
254
	}else if (call->auth_token_verified && !verified){
255
		ms_zrtp_sas_reset_verified(call->audiostream->ms.sessions.zrtp_context);
Simon Morlat's avatar
Simon Morlat committed
256 257 258 259
	}
	call->auth_token_verified=verified;
	propagate_encryption_changed(call);
}
260

261 262
static int get_max_codec_sample_rate(const MSList *codecs){
	int max_sample_rate=0;
263 264 265
	const MSList *it;
	for(it=codecs;it!=NULL;it=it->next){
		PayloadType *pt=(PayloadType*)it->data;
266
		int sample_rate;
267

268 269 270 271 272 273 274 275
		if( strcasecmp("G722",pt->mime_type) == 0 ){
			/* G722 spec says 8000 but the codec actually requires 16000 */
			sample_rate = 16000;
		}else sample_rate=pt->clock_rate;
		if (sample_rate>max_sample_rate) max_sample_rate=sample_rate;
	}
	return max_sample_rate;
}
276

277 278 279 280 281 282 283 284 285 286 287 288
static int find_payload_type_number(const MSList *assigned, const PayloadType *pt){
	const MSList *elem;
	const PayloadType *candidate=NULL;
	for(elem=assigned;elem!=NULL;elem=elem->next){
		const PayloadType *it=(const PayloadType*)elem->data;
		if ((strcasecmp(pt->mime_type, payload_type_get_mime(it)) == 0)
			&& (it->clock_rate==pt->clock_rate)
			&& (it->channels==pt->channels || pt->channels<=0)) {
			candidate=it;
			if ((it->recv_fmtp!=NULL && pt->recv_fmtp!=NULL && strcasecmp(it->recv_fmtp, pt->recv_fmtp)==0)
				|| (it->recv_fmtp==NULL && pt->recv_fmtp==NULL)){
				break;/*exact match*/
289
			}
290 291 292 293 294 295 296 297 298 299 300 301 302
		}
	}
	return candidate ? payload_type_get_number(candidate) : -1;
}

bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore){
	const MSList *elem;
	for (elem=l; elem!=NULL; elem=elem->next){
		const PayloadType *pt=(PayloadType*)elem->data;
		if (pt!=ignore && payload_type_get_number(pt)==number) return FALSE;
	}
	return TRUE;
}
303

304 305 306
static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList *codecs){
	MSList *elem;
	int dyn_number=lc->codecs_conf.dyn_pt;
307
	PayloadType *red = NULL, *t140 = NULL;
308

309 310 311
	for (elem=codecs; elem!=NULL; elem=elem->next){
		PayloadType *pt=(PayloadType*)elem->data;
		int number=payload_type_get_number(pt);
312

313 314 315 316 317
		/*check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer*/
		if (number!=-1 && !(pt->flags & PAYLOAD_TYPE_FROZEN_NUMBER)){
			if (!is_payload_type_number_available(codecs, number, pt)){
				ms_message("Reassigning payload type %i %s/%i because already offered.", number, pt->mime_type, pt->clock_rate);
				number=-1; /*need to be re-assigned*/
318
			}
319
		}
320

321 322 323 324 325 326 327 328 329 330 331 332
		if (number==-1){
			while(dyn_number<127){
				if (is_payload_type_number_available(codecs, dyn_number, NULL)){
					payload_type_set_number(pt, dyn_number);
					dyn_number++;
					break;
				}
				dyn_number++;
			}
			if (dyn_number==127){
				ms_error("Too many payload types configured ! codec %s/%i is disabled.", pt->mime_type, pt->clock_rate);
				payload_type_set_enable(pt, FALSE);
333
			}
334
		}
335

336
		if (strcmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) {
337 338 339
			red = pt;
		} else if (strcmp(pt->mime_type, payload_type_t140.mime_type) == 0) {
			t140 = pt;
340
		}
341
	}
342

343 344 345 346 347
	if (t140 && red) {
		int t140_payload_type_number = payload_type_get_number(t140);
		const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_type_number, t140_payload_type_number, t140_payload_type_number);
		payload_type_set_recv_fmtp(red, red_fmtp);
	}
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
}

static bool_t has_telephone_event_at_rate(const MSList *tev, int rate){
	const MSList *it;
	for(it=tev;it!=NULL;it=it->next){
		const PayloadType *pt=(PayloadType*)it->data;
		if (pt->clock_rate==rate) return TRUE;
	}
	return FALSE;
}

static MSList * create_telephone_events(LinphoneCore *lc, const MSList *codecs){
	const MSList *it;
	MSList *ret=NULL;
	for(it=codecs;it!=NULL;it=it->next){
		const PayloadType *pt=(PayloadType*)it->data;
		if (!has_telephone_event_at_rate(ret,pt->clock_rate)){
			PayloadType *tev=payload_type_clone(&payload_type_telephone_event);
			tev->clock_rate=pt->clock_rate;
			/*let it choose the number dynamically as for normal codecs*/
			payload_type_set_number(tev, -1);
			if (ret==NULL){
				/*But for first telephone-event, prefer the number that was configured in the core*/
				if (is_payload_type_number_available(codecs, lc->codecs_conf.telephone_event_pt, NULL)){
					payload_type_set_number(tev, lc->codecs_conf.telephone_event_pt);
				}
374
			}
375 376 377 378 379 380
			ret=ms_list_append(ret,tev);
		}
	}
	return ret;
}

381 382 383 384 385 386 387 388 389 390
static MSList *create_special_payload_types(LinphoneCore *lc, const MSList *codecs){
	MSList *ret=create_telephone_events(lc, codecs);
	if (linphone_core_generic_confort_noise_enabled(lc)){
		PayloadType *cn=payload_type_clone(&payload_type_cn);
		payload_type_set_number(cn, 13);
		ret=ms_list_append(ret, cn);
	}
	return ret;
}

391 392 393 394 395 396
typedef struct _CodecConstraints{
	int bandwidth_limit;
	int max_codecs;
	MSList *previously_used;
}CodecConstraints;

397
static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, SalStreamType stype, const MSList *codecs){
398 399 400 401 402 403 404
	MSList *l=NULL;
	const MSList *it;
	int nb = 0;

	for(it=codecs;it!=NULL;it=it->next){
		PayloadType *pt=(PayloadType*)it->data;
		int num;
405

Sylvain Berfini's avatar
Sylvain Berfini committed
406
		if (!payload_type_enabled(pt)) {
407
			continue;
Sylvain Berfini's avatar
Sylvain Berfini committed
408
		}
409 410 411 412 413 414 415 416 417
		if (hints->bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,hints->bandwidth_limit)){
			ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s",
					pt->mime_type,pt->clock_rate,hints->bandwidth_limit);
			continue;
		}
		if (!linphone_core_check_payload_type_usability(lc,pt)){
			continue;
		}
		pt=payload_type_clone(pt);
418

419 420 421 422 423
		/*look for a previously assigned number for this codec*/
		num=find_payload_type_number(hints->previously_used, pt);
		if (num!=-1){
			payload_type_set_number(pt,num);
			payload_type_set_flag(pt, PAYLOAD_TYPE_FROZEN_NUMBER);
424
		}
425

426 427 428
		l=ms_list_append(l, pt);
		nb++;
		if ((hints->max_codecs > 0) && (nb >= hints->max_codecs)) break;
429
	}
430 431 432 433
	if (stype==SalAudio){
		MSList *specials=create_special_payload_types(lc,l);
		l=ms_list_concat(l,specials);
	}
434
	linphone_core_assign_payload_type_numbers(lc, l);
435 436 437
	return l;
}

438
static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc, const StunCandidate *tc){
439
	int i;
440
	for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
441
		if (!sal_stream_description_active(&md->streams[i])) continue;
442
		if ((md->streams[i].type == SalAudio) && (ac->port != 0)) {
443 444
			strcpy(md->streams[i].rtp_addr,ac->addr);
			md->streams[i].rtp_port=ac->port;
445
			if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || sal_media_description_get_nb_active_streams(md)==1){
446 447
				strcpy(md->addr,ac->addr);
			}
448 449 450 451 452 453
		} else if ((md->streams[i].type == SalVideo) && (vc->port != 0)) {
			strcpy(md->streams[i].rtp_addr,vc->addr);
			md->streams[i].rtp_port=vc->port;
		} else if ((md->streams[i].type == SalText) && (tc->port != 0)) {
			strcpy(md->streams[i].rtp_addr,tc->addr);
			md->streams[i].rtp_port=tc->port;
454 455 456 457
		}
	}
}

458
static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, unsigned int tag){
459
	size_t keylen=0;
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
	crypto->tag=tag;
	crypto->algo=suite;
	switch(suite){
		case MS_AES_128_SHA1_80:
		case MS_AES_128_SHA1_32:
		case MS_AES_128_NO_AUTH:
		case MS_NO_CIPHER_SHA1_80: /*not sure for this one*/
			keylen=30;
		break;
		case MS_AES_256_SHA1_80:
		case MS_AES_256_SHA1_32:
			keylen=46;
		break;
		case MS_CRYPTO_SUITE_INVALID:
		break;
	}
johan's avatar
johan committed
476
	if (keylen==0 || !generate_b64_crypto_key(keylen, crypto->master_key, SAL_SRTP_KEY_SIZE)){
477 478 479 480 481 482
		ms_error("Could not generate SRTP key.");
		crypto->algo = 0;
		return -1;
	}
	return 0;
}
483 484
static void setup_dtls_keys(LinphoneCall *call, SalMediaDescription *md){
	int i;
485
	for(i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
486 487 488 489 490 491 492 493
		if (!sal_stream_description_active(&md->streams[i])) continue;
		/* if media encryption is set to DTLS check presence of fingerprint in the call which shall have been set at stream init but it may have failed when retrieving certificate resulting in no fingerprint present and then DTLS not usable */
		if (sal_stream_description_has_dtls(&md->streams[i]) == TRUE) {
			strncpy(md->streams[i].dtls_fingerprint, call->dtls_certificate_fingerprint, sizeof(md->streams[i].dtls_fingerprint)); /* get the self fingerprint from call(it's computed at stream init) */
			md->streams[i].dtls_role = SalDtlsRoleUnset; /* if we are offering, SDP will have actpass setup attribute when role is unset, if we are responding the result mediadescription will be set to SalDtlsRoleIsClient */
		} else {
			md->streams[i].dtls_fingerprint[0] = '\0';
			md->streams[i].dtls_role = SalDtlsRoleInvalid;
494

495 496 497 498
		}
	}

}
499 500
static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
	LinphoneCore *lc=call->core;
501
	int i,j;
502
	SalMediaDescription *old_md=call->localdesc;
503
	bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1);
504

505
	for(i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
506 507
		if (!sal_stream_description_active(&md->streams[i])) continue;
		if (sal_stream_description_has_srtp(&md->streams[i]) == TRUE) {
508
			if (keep_srtp_keys && old_md && (sal_stream_description_active(&old_md->streams[i]) == TRUE) && (sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE)) {
509 510 511 512 513 514
				int j;
				ms_message("Keeping same crypto keys.");
				for(j=0;j<SAL_CRYPTO_ALGO_MAX;++j){
					memcpy(&md->streams[i].crypto[j],&old_md->streams[i].crypto[j],sizeof(SalSrtpCryptoAlgo));
				}
			}else{
515 516 517 518
				const MSCryptoSuite *suites=linphone_core_get_srtp_crypto_suites(lc);
				for(j=0;suites!=NULL && suites[j]!=MS_CRYPTO_SUITE_INVALID && j<SAL_CRYPTO_ALGO_MAX;++j){
					setup_encryption_key(&md->streams[i].crypto[j],suites[j],j+1);
				}
519 520 521 522 523
			}
		}
	}
}

johan's avatar
johan committed
524 525 526

static void setup_zrtp_hash(LinphoneCall *call, SalMediaDescription *md) {
	int i;
johan's avatar
johan committed
527
	if (ms_zrtp_available()) { /* set the hello hash for all streams */
johan's avatar
johan committed
528 529 530 531
		for(i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
			if (!sal_stream_description_active(&md->streams[i])) continue;
			if (call->sessions[i].zrtp_context!=NULL) {
				ms_zrtp_getHelloHash(call->sessions[i].zrtp_context, md->streams[i].zrtphash, 128);
johan's avatar
johan committed
532 533 534 535 536
				if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) { /* turn on the flag to use it if ZRTP is set */
					md->streams[i].haveZrtpHash = 1;
				} else {
					md->streams[i].haveZrtpHash = 0;
				}
johan's avatar
johan committed
537 538 539 540 541 542 543
			} else {
				md->streams[i].haveZrtpHash = 0;
			}
		}
	}
}

544 545 546 547
static void setup_rtcp_fb(LinphoneCall *call, SalMediaDescription *md) {
	MSList *pt_it;
	PayloadType *pt;
	PayloadTypeAvpfParams avpf_params;
548
	LinphoneCore *lc = call->core;
549 550
	int i;

551
	for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
552
		if (!sal_stream_description_active(&md->streams[i])) continue;
553 554
		md->streams[i].rtcp_fb.generic_nack_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_fb_generic_nack_enabled", 0);
		md->streams[i].rtcp_fb.tmmbr_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_fb_tmmbr_enabled", 0);
Simon Morlat's avatar
Simon Morlat committed
555
		md->streams[i].implicit_rtcp_fb = call->params->implicit_rtcp_fb;
556

Simon Morlat's avatar
Simon Morlat committed
557
		for (pt_it = md->streams[i].payloads; pt_it != NULL; pt_it = pt_it->next) {
558
			pt = (PayloadType *)pt_it->data;
Simon Morlat's avatar
Simon Morlat committed
559 560 561 562 563 564 565 566 567

			if (call->params->avpf_enabled == FALSE && call->params->implicit_rtcp_fb == FALSE)  {
				payload_type_unset_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED);
				memset(&avpf_params, 0, sizeof(avpf_params));
			}else {
				payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED);
				avpf_params = payload_type_get_avpf_params(pt);
				avpf_params.trr_interval = call->params->avpf_rr_interval;
			}
568 569 570 571 572
			payload_type_set_avpf_params(pt, avpf_params);
		}
	}
}

573 574
static void setup_rtcp_xr(LinphoneCall *call, SalMediaDescription *md) {
	LinphoneCore *lc = call->core;
575
	int i;
576

Simon Morlat's avatar
Simon Morlat committed
577
	md->rtcp_xr.enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_enabled", 1);
578
	if (md->rtcp_xr.enabled == TRUE) {
Simon Morlat's avatar
Simon Morlat committed
579
		const char *rcvr_rtt_mode = lp_config_get_string(lc->config, "rtp", "rtcp_xr_rcvr_rtt_mode", "all");
580 581 582 583
		if (strcasecmp(rcvr_rtt_mode, "all") == 0) md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttAll;
		else if (strcasecmp(rcvr_rtt_mode, "sender") == 0) md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttSender;
		else md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttNone;
		if (md->rtcp_xr.rcvr_rtt_mode != OrtpRtcpXrRcvrRttNone) {
Simon Morlat's avatar
Simon Morlat committed
584
			md->rtcp_xr.rcvr_rtt_max_size = lp_config_get_int(lc->config, "rtp", "rtcp_xr_rcvr_rtt_max_size", 10000);
585
		}
Simon Morlat's avatar
Simon Morlat committed
586
		md->rtcp_xr.stat_summary_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_stat_summary_enabled", 1);
587
		if (md->rtcp_xr.stat_summary_enabled == TRUE) {
588
			md->rtcp_xr.stat_summary_flags = OrtpRtcpXrStatSummaryLoss | OrtpRtcpXrStatSummaryDup | OrtpRtcpXrStatSummaryJitt | OrtpRtcpXrStatSummaryTTL;
589
		}
Simon Morlat's avatar
Simon Morlat committed
590
		md->rtcp_xr.voip_metrics_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_enabled", 1);
591
	}
592
	for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
593
		if (!sal_stream_description_active(&md->streams[i])) continue;
594 595
		memcpy(&md->streams[i].rtcp_xr, &md->rtcp_xr, sizeof(md->streams[i].rtcp_xr));
	}
596 597
}

598 599 600 601 602
void linphone_call_increment_local_media_description(LinphoneCall *call){
	SalMediaDescription *md=call->localdesc;
	md->session_ver++;
}

603
void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call){
604
	LinphoneCore *lc = call->core;
605
	if (call->ice_session != NULL) {
606
		/*set this to FALSE once flexisip are updated everywhere, let's say in December 2016.*/
607 608
		bool_t use_nortpproxy = lp_config_get_int(lc->config, "sip", "ice_uses_nortpproxy", TRUE);
		_update_local_media_description_from_ice(call->localdesc, call->ice_session, use_nortpproxy);
609 610 611 612 613 614 615 616 617 618
		linphone_core_update_ice_state_in_call_stats(call);
	}
#ifdef BUILD_UPNP
	if(call->upnp_session != NULL) {
		linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
		linphone_core_update_upnp_state_in_call_stats(call);
	}
#endif  //BUILD_UPNP
}

619 620
static void transfer_already_assigned_payload_types(SalMediaDescription *old, SalMediaDescription *md){
	int i;
621
	for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
622 623 624 625 626
		md->streams[i].already_assigned_payloads=old->streams[i].already_assigned_payloads;
		old->streams[i].already_assigned_payloads=NULL;
	}
}

627
static const char *linphone_call_get_bind_ip_for_stream(LinphoneCall *call, int stream_index){
628
	const char *bind_ip = lp_config_get_string(call->core->config,"rtp","bind_address",call->af==AF_INET6 ? "::0" : "0.0.0.0");
629

630 631
	if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0'){
		if (call->dir==LinphoneCallOutgoing){
632
			/*as multicast sender, we must decide a local interface to use to send multicast, and bind to it*/
633
			bind_ip=call->media_localip;
634 635
		}
	}
636 637 638
	return bind_ip;
}

639
static const char *linphone_call_get_public_ip_for_stream(LinphoneCall *call, int stream_index){
640
	const char *public_ip=call->media_localip;
641 642

	if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0')
643 644 645 646
		public_ip=call->media_ports[stream_index].multicast_ip;
	return public_ip;
}

647 648 649 650 651 652 653 654 655 656 657 658
void linphone_call_update_biggest_desc(LinphoneCall *call, SalMediaDescription *md){
	if (call->biggestdesc==NULL || md->nb_streams>call->biggestdesc->nb_streams){
		/*we have been offered and now are ready to proceed, or we added a new stream*/
		/*store the media description to remember the mapping of calls*/
		if (call->biggestdesc){
			sal_media_description_unref(call->biggestdesc);
			call->biggestdesc=NULL;
		}
		call->biggestdesc=sal_media_description_ref(md);
	}
}

659 660
static void force_streams_dir_according_to_state(LinphoneCall *call, SalMediaDescription *md){
	int i;
661

662 663 664 665 666 667 668 669
	switch (call->state){
		case LinphoneCallPausing:
		case LinphoneCallPaused:
		break;
		default:
			return;
		break;
	}
670

671
	for (i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){
672
		SalStreamDescription *sd = &md->streams[i];
673 674 675 676 677 678
		if (sd->dir != SalStreamInactive) {
			sd->dir = SalStreamSendOnly;
			if (sd->type == SalVideo){
				if (lp_config_get_int(call->core->config, "sip", "inactive_video_on_pause", 0)) {
					sd->dir = SalStreamInactive;
				}
679 680 681
			}
		}
	}
682 683
}

684
void linphone_call_make_local_media_description(LinphoneCall *call) {
685
	MSList *l;
Simon Morlat's avatar
Simon Morlat committed
686
	SalMediaDescription *old_md=call->localdesc;
687
	int i;
688
	int max_index = 0;
689
	SalMediaDescription *md=sal_media_description_new();
690
	LinphoneAddress *addr;
691 692
	const char *subject;
	CodecConstraints codec_hints={0};
693 694
	LinphoneCallParams *params = call->params;
	LinphoneCore *lc = call->core;
695
	bool_t rtcp_mux = lp_config_get_int(lc->config, "rtp", "rtcp_mux", 0);
696

jehan's avatar
jehan committed
697
	/*multicast is only set in case of outgoing call*/
698
	if (call->dir == LinphoneCallOutgoing && linphone_call_params_audio_multicast_enabled(params)) {
699 700
		md->streams[call->main_audio_stream_index].ttl=linphone_core_get_audio_multicast_ttl(lc);
		md->streams[call->main_audio_stream_index].multicast_role = SalMulticastSender;
701
	}
jehan's avatar
jehan committed
702

703
	if (call->dir == LinphoneCallOutgoing && linphone_call_params_video_multicast_enabled(params)) {
704 705
		md->streams[call->main_video_stream_index].ttl=linphone_core_get_video_multicast_ttl(lc);
		md->streams[call->main_video_stream_index].multicast_role = SalMulticastSender;
706
	}
jehan's avatar
jehan committed
707

708
	subject=linphone_call_params_get_session_name(params);
709

710
	linphone_core_adapt_to_network(lc,call->ping_time,params);
711

712 713 714 715 716
	if (call->dest_proxy) {
		addr=linphone_address_clone(linphone_proxy_config_get_identity_address(call->dest_proxy));
	} else {
		addr=linphone_address_new(linphone_core_get_identity(lc));
	}
717

Simon Morlat's avatar
Simon Morlat committed
718 719
	md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff));
	md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff));
720
	md->nb_streams=(call->biggestdesc ? call->biggestdesc->nb_streams : 1);
721

722 723
	/*re-check local ip address each time we make a new offer, because it may change in case of network reconnection*/
	linphone_call_get_local_ip(call, call->dir == LinphoneCallOutgoing ?  call->log->to : call->log->from);
724
	strncpy(md->addr,call->media_localip,sizeof(md->addr));
jehan's avatar
jehan committed
725 726
	if (linphone_address_get_username(addr)) /*might be null in case of identity without userinfo*/
		strncpy(md->username,linphone_address_get_username(addr),sizeof(md->username));
Simon Morlat's avatar
Simon Morlat committed
727
	if (subject) strncpy(md->name,subject,sizeof(md->name));
728

729 730
	if (params->down_bw)
		md->bandwidth=params->down_bw;
731
	else md->bandwidth=linphone_core_get_download_bandwidth(lc);
732

733 734 735
	if (params->custom_sdp_attributes)
		md->custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_attributes);

736
	/*set audio capabilities */
737

738 739 740 741
    codec_hints.bandwidth_limit=params->audio_bw;
    codec_hints.max_codecs=-1;
    codec_hints.previously_used=old_md ? old_md->streams[call->main_audio_stream_index].already_assigned_payloads : NULL;
    l=make_codec_list(lc, &codec_hints, SalAudio, lc->codecs_conf.audio_codecs);
742

743
	if (params->has_audio && l != NULL) {
744 745 746 747 748 749 750 751
		strncpy(md->streams[call->main_audio_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_audio_stream_index),sizeof(md->streams[call->main_audio_stream_index].rtp_addr));
		strncpy(md->streams[call->main_audio_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_audio_stream_index),sizeof(md->streams[call->main_audio_stream_index].rtcp_addr));
		strncpy(md->streams[call->main_audio_stream_index].name,"Audio",sizeof(md->streams[call->main_audio_stream_index].name)-1);
		md->streams[call->main_audio_stream_index].rtp_port=call->media_ports[call->main_audio_stream_index].rtp_port;
		md->streams[call->main_audio_stream_index].rtcp_port=call->media_ports[call->main_audio_stream_index].rtcp_port;
		md->streams[call->main_audio_stream_index].proto=get_proto_from_call_params(params);
		md->streams[call->main_audio_stream_index].dir=get_audio_dir_from_call_params(params);
		md->streams[call->main_audio_stream_index].type=SalAudio;
752
		md->streams[call->main_audio_stream_index].rtcp_mux = rtcp_mux;
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
		if (params->down_ptime)
			md->streams[call->main_audio_stream_index].ptime=params->down_ptime;
		else
			md->streams[call->main_audio_stream_index].ptime=linphone_core_get_download_ptime(lc);
		md->streams[call->main_audio_stream_index].max_rate=get_max_codec_sample_rate(l);
		md->streams[call->main_audio_stream_index].payloads=l;
		if (call->audiostream && call->audiostream->ms.sessions.rtp_session) {
			char* me = linphone_address_as_string_uri_only(call->me);
			md->streams[call->main_audio_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->audiostream->ms.sessions.rtp_session);
			strncpy(md->streams[call->main_audio_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_audio_stream_index].rtcp_cname));
			ms_free(me);
		}
		else
			ms_warning("Cannot get audio local ssrc for call [%p]",call);
		if (call->main_audio_stream_index > max_index)
			max_index = call->main_audio_stream_index;
769 770 771
	} else {
		ms_message("Don't put audio stream on local offer for call [%p]",call);
		md->streams[call->main_audio_stream_index].dir = SalStreamInactive;
772
		if(l) l=ms_list_free_with_data(l, (void (*)(void *))payload_type_destroy);
773
	}
774 775
	if (params->custom_sdp_media_attributes[LinphoneStreamTypeAudio])
		md->streams[call->main_audio_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeAudio]);
776

777 778 779
	md->streams[call->main_video_stream_index].proto=md->streams[call->main_audio_stream_index].proto;
	md->streams[call->main_video_stream_index].dir=get_video_dir_from_call_params(params);
	md->streams[call->main_video_stream_index].type=SalVideo;
780
	md->streams[call->main_video_stream_index].rtcp_mux = rtcp_mux;
781
	strncpy(md->streams[call->main_video_stream_index].name,"Video",sizeof(md->streams[call->main_video_stream_index].name)-1);
782

783 784 785 786
	codec_hints.bandwidth_limit=0;
	codec_hints.max_codecs=-1;
	codec_hints.previously_used=old_md ? old_md->streams[call->main_video_stream_index].already_assigned_payloads : NULL;
	l=make_codec_list(lc, &codec_hints, SalVideo, lc->codecs_conf.video_codecs);
787

788
	if (params->has_video && l != NULL){
789 790 791 792
		strncpy(md->streams[call->main_video_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtp_addr));
		strncpy(md->streams[call->main_video_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtcp_addr));
		md->streams[call->main_video_stream_index].rtp_port=call->media_ports[call->main_video_stream_index].rtp_port;
		md->streams[call->main_video_stream_index].rtcp_port=call->media_ports[call->main_video_stream_index].rtcp_port;
793
		md->streams[call->main_video_stream_index].payloads=l;
794 795
		if (call->videostream && call->videostream->ms.sessions.rtp_session) {
			char* me = linphone_address_as_string_uri_only(call->me);
796 797
			md->streams[call->main_video_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->videostream->ms.sessions.rtp_session);
			strncpy(md->streams[call->main_video_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_video_stream_index].rtcp_cname));
798 799 800 801
			ms_free(me);
		}
		else
			ms_warning("Cannot get video local ssrc for call [%p]",call);
802 803
		if (call->main_video_stream_index > max_index)
			max_index = call->main_video_stream_index;
804 805
	} else {
		ms_message("Don't put video stream on local offer for call [%p]",call);
806
		md->streams[call->main_video_stream_index].dir = SalStreamInactive;
807
		if(l) l=ms_list_free_with_data(l, (void (*)(void *))payload_type_destroy);
808
	}
809 810 811
	if (params->custom_sdp_media_attributes[LinphoneStreamTypeVideo])
		md->streams[call->main_video_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeVideo]);

812
	md->streams[call->main_text_stream_index].proto=md->streams[call->main_audio_stream_index].proto;
813 814
	md->streams[call->main_text_stream_index].dir=SalStreamSendRecv;
	md->streams[call->main_text_stream_index].type=SalText;
815
	md->streams[call->main_text_stream_index].rtcp_mux = rtcp_mux;
816
	strncpy(md->streams[call->main_text_stream_index].name,"Text",sizeof(md->streams[call->main_text_stream_index].name)-1);
817 818 819
	if (params->realtimetext_enabled) {
		strncpy(md->streams[call->main_text_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtp_addr));
		strncpy(md->streams[call->main_text_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtcp_addr));
820

821 822
		md->streams[call->main_text_stream_index].rtp_port=call->media_ports[call->main_text_stream_index].rtp_port;
		md->streams[call->main_text_stream_index].rtcp_port=call->media_ports[call->main_text_stream_index].rtcp_port;
823

824 825 826 827 828 829 830 831 832 833 834 835 836
		codec_hints.bandwidth_limit=0;
		codec_hints.max_codecs=-1;
		codec_hints.previously_used=old_md ? old_md->streams[call->main_text_stream_index].already_assigned_payloads : NULL;
		l=make_codec_list(lc, &codec_hints, SalText, lc->codecs_conf.text_codecs);
		md->streams[call->main_text_stream_index].payloads=l;
		if (call->textstream && call->textstream->ms.sessions.rtp_session) {
			char* me = linphone_address_as_string_uri_only(call->me);
			md->streams[call->main_text_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->textstream->ms.sessions.rtp_session);
			strncpy(md->streams[call->main_text_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_text_stream_index].rtcp_cname));
			ms_free(me);
		}
		else
			ms_warning("Cannot get text local ssrc for call [%p]",call);
837 838
		if (call->main_text_stream_index > max_index)
			max_index = call->main_text_stream_index;
839 840
	} else {
		ms_message("Don't put text stream on local offer for call [%p]",call);
841
		md->streams[call->main_text_stream_index].dir = SalStreamInactive;