linphonecore.c 128 KB
Newer Older
aymeric's avatar
aymeric committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
linphone
Copyright (C) 2000  Simon MORLAT (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.
*/

#include "linphonecore.h"
smorlat's avatar
smorlat committed
21
#include "sipsetup.h"
aymeric's avatar
aymeric committed
22 23
#include "lpconfig.h"
#include "private.h"
24 25

#include <ortp/telephonyevents.h>
aymeric's avatar
aymeric committed
26
#include "mediastreamer2/mediastream.h"
27
#include "mediastreamer2/mseventqueue.h"
smorlat's avatar
smorlat committed
28
#include "mediastreamer2/msvolume.h"
29
#include "mediastreamer2/msequalizer.h"
30
#include "mediastreamer2/dtmfgen.h"
aymeric's avatar
aymeric committed
31

32
#ifdef INET6
aymeric's avatar
aymeric committed
33
#ifndef WIN32
34
#include <netdb.h>
aymeric's avatar
aymeric committed
35 36 37
#endif
#endif

smorlat's avatar
smorlat committed
38
/*#define UNSTANDART_GSM_11K 1*/
aymeric's avatar
aymeric committed
39 40

static const char *liblinphone_version=LIBLINPHONE_VERSION;
41
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
Simon Morlat's avatar
Simon Morlat committed
42 43
static void linphone_core_run_hooks(LinphoneCore *lc);
static void linphone_core_free_hooks(LinphoneCore *lc);
aymeric's avatar
aymeric committed
44 45

#include "enum.h"
46
const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
aymeric's avatar
aymeric committed
47 48 49 50 51 52
void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result);
static void toggle_video_preview(LinphoneCore *lc, bool_t val);

/* relative path where is stored local ring*/
#define LOCAL_RING "rings/oldphone.wav"
/* same for remote ring (ringback)*/
53
#define REMOTE_RING "ringback.wav"
54 55
#define HOLD_MUSIC "rings/toy-mono.wav"

aymeric's avatar
aymeric committed
56

Simon Morlat's avatar
Simon Morlat committed
57
extern SalCallbacks linphone_sal_callbacks;
aymeric's avatar
aymeric committed
58 59 60 61 62 63 64 65 66 67 68 69

void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud)
{
  obj->_func=func;
  obj->_user_data=ud;
}

int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){
	if (obj->_func!=NULL) obj->_func(lc,obj->_user_data);
	return 0;
}

70

aymeric's avatar
aymeric committed
71 72
/*prevent a gcc bug with %c*/
static size_t my_strftime(char *s, size_t max, const char  *fmt,  const struct tm *tm){
Jehan Monnier's avatar
Jehan Monnier committed
73
#if !defined(_WIN32_WCE)
aymeric's avatar
aymeric committed
74
	return strftime(s, max, fmt, tm);
Jehan Monnier's avatar
Jehan Monnier committed
75 76 77 78
#else
	return 0;
	/*FIXME*/
#endif /*_WIN32_WCE*/
aymeric's avatar
aymeric committed
79 80
}

81 82 83 84
static void set_call_log_date(LinphoneCallLog *cl, const struct tm *loctime){
	my_strftime(cl->start_date,sizeof(cl->start_date),"%c",loctime);
}

85
LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
aymeric's avatar
aymeric committed
86 87 88 89
	LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
	struct tm loctime;
	cl->dir=call->dir;
#ifdef WIN32
Jehan Monnier's avatar
Jehan Monnier committed
90
#if !defined(_WIN32_WCE)
aymeric's avatar
aymeric committed
91
	loctime=*localtime(&call->start_time);
Jehan Monnier's avatar
Jehan Monnier committed
92 93
	/*FIXME*/
#endif /*_WIN32_WCE*/
aymeric's avatar
aymeric committed
94 95 96
#else
	localtime_r(&call->start_time,&loctime);
#endif
97
	set_call_log_date(cl,&loctime);
aymeric's avatar
aymeric committed
98 99
	cl->from=from;
	cl->to=to;
100
    cl->status=LinphoneCallAborted; /*default status*/
aymeric's avatar
aymeric committed
101 102
	return cl;
}
103

104
void call_logs_write_to_config_file(LinphoneCore *lc){
105 106 107 108 109 110
	MSList *elem;
	char logsection[32];
	int i;
	char *tmp;
	LpConfig *cfg=lc->config;

111
	if (linphone_core_get_global_state (lc)==LinphoneGlobalStartup) return;
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126
	for(i=0,elem=lc->call_logs;elem!=NULL;elem=elem->next,++i){
		LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
		lp_config_set_int(cfg,logsection,"dir",cl->dir);
		lp_config_set_int(cfg,logsection,"status",cl->status);
		tmp=linphone_address_as_string(cl->from);
		lp_config_set_string(cfg,logsection,"from",tmp);
		ms_free(tmp);
		tmp=linphone_address_as_string(cl->to);
		lp_config_set_string(cfg,logsection,"to",tmp);
		ms_free(tmp);
		lp_config_set_string(cfg,logsection,"start_date",cl->start_date);
		lp_config_set_int(cfg,logsection,"duration",cl->duration);
		if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey);
127
		lp_config_set_float(cfg,logsection,"quality",cl->quality);
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
	}
	for(;i<lc->max_call_logs;++i){
		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
		lp_config_clean_section(cfg,logsection);
	}
}

static void call_logs_read_from_config_file(LinphoneCore *lc){
	char logsection[32];
	int i;
	const char *tmp;
	LpConfig *cfg=lc->config;
	for(i=0;;++i){
		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
		if (lp_config_has_section(cfg,logsection)){
			LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
			cl->dir=lp_config_get_int(cfg,logsection,"dir",0);
			cl->status=lp_config_get_int(cfg,logsection,"status",0);
			tmp=lp_config_get_string(cfg,logsection,"from",NULL);
			if (tmp) cl->from=linphone_address_new(tmp);
			tmp=lp_config_get_string(cfg,logsection,"to",NULL);
			if (tmp) cl->to=linphone_address_new(tmp);
			tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
			if (tmp) strncpy(cl->start_date,tmp,sizeof(cl->start_date));
			cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
			tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
			if (tmp) cl->refkey=ms_strdup(tmp);
155
			cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
156
			lc->call_logs=ms_list_append(lc->call_logs,cl);
157
		}else break;
158 159 160 161
	}
}


aymeric's avatar
aymeric committed
162

smorlat's avatar
smorlat committed
163 164 165 166 167 168 169
/**
 * @addtogroup call_logs
 * @{
**/

/**
 * Returns a human readable string describing the call.
170
 *
smorlat's avatar
smorlat committed
171 172
 * @note: the returned char* must be freed by the application (use ms_free()).
**/
aymeric's avatar
aymeric committed
173 174
char * linphone_call_log_to_str(LinphoneCallLog *cl){
	char *status;
175
	char *tmp;
176 177
	char *from=linphone_address_as_string (cl->from);
	char *to=linphone_address_as_string (cl->to);
aymeric's avatar
aymeric committed
178 179 180 181 182 183 184 185 186 187 188 189 190
	switch(cl->status){
		case LinphoneCallAborted:
			status=_("aborted");
			break;
		case LinphoneCallSuccess:
			status=_("completed");
			break;
		case LinphoneCallMissed:
			status=_("missed");
			break;
		default:
			status="unknown";
	}
191
	tmp=ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
aymeric's avatar
aymeric committed
192 193
			(cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"),
			cl->start_date,
194 195
			from,
			to,
aymeric's avatar
aymeric committed
196 197 198
			status,
			cl->duration/60,
			cl->duration%60);
199 200 201
	ms_free(from);
	ms_free(to);
	return tmp;
aymeric's avatar
aymeric committed
202 203
}

204 205
/**
 * Returns RTP statistics computed locally regarding the call.
206
 *
207 208 209 210 211 212 213 214 215 216 217 218 219 220
**/
const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl){
	return &cl->local_stats;
}

/**
 * Returns RTP statistics computed by remote end and sent back via RTCP.
 *
 * @note Not implemented yet.
**/
const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl){
	return &cl->remote_stats;
}

smorlat's avatar
smorlat committed
221 222 223 224 225 226 227 228
void linphone_call_log_set_user_pointer(LinphoneCallLog *cl, void *up){
	cl->user_pointer=up;
}

void *linphone_call_log_get_user_pointer(const LinphoneCallLog *cl){
	return cl->user_pointer;
}

smorlat's avatar
smorlat committed
229 230


231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
/**
 * Associate a persistent reference key to the call log.
 *
 * The reference key can be for example an id to an external database.
 * It is stored in the config file, thus can survive to process exits/restarts.
 *
**/
void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey){
	if (cl->refkey!=NULL){
		ms_free(cl->refkey);
		cl->refkey=NULL;
	}
	if (refkey) cl->refkey=ms_strdup(refkey);
}

/**
 * Get the persistent reference key associated to the call log.
 *
 * The reference key can be for example an id to an external database.
 * It is stored in the config file, thus can survive to process exits/restarts.
 *
**/
const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl){
	return cl->refkey;
}

smorlat's avatar
smorlat committed
257 258
/** @} */

aymeric's avatar
aymeric committed
259
void linphone_call_log_destroy(LinphoneCallLog *cl){
260 261 262
	if (cl->from!=NULL) linphone_address_destroy(cl->from);
	if (cl->to!=NULL) linphone_address_destroy(cl->to);
	if (cl->refkey!=NULL) ms_free(cl->refkey);
aymeric's avatar
aymeric committed
263 264 265
	ms_free(cl);
}

266 267 268 269 270 271 272 273 274 275 276 277
/**
 * Returns TRUE if the LinphoneCall asked to autoanswer
 *
**/
bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call){
	//return TRUE if the unique(for the moment) incoming call asked to be autoanswered
	if(call)
		return sal_call_autoanswer_asked(call->op);
	else
		return FALSE;
}

278 279
int linphone_core_get_current_call_duration(const LinphoneCore *lc){
	LinphoneCall *call=linphone_core_get_current_call((LinphoneCore *)lc);
280 281
	if (call)  return linphone_call_get_duration(call);
	return -1;
282 283 284 285
}

const LinphoneAddress *linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc){
	LinphoneCall *call=linphone_core_get_current_call(lc);
Simon Morlat's avatar
Simon Morlat committed
286
	if (call==NULL) return NULL;
287
	return linphone_call_get_remote_address(call);
smorlat's avatar
smorlat committed
288 289
}

290 291 292 293 294 295
/**
 * Enable logs in supplied FILE*.
 *
 * @ingroup misc
 *
 * @param file a C FILE* where to fprintf logs. If null stdout is used.
296
 *
297
**/
aymeric's avatar
aymeric committed
298 299 300 301 302 303
void linphone_core_enable_logs(FILE *file){
	if (file==NULL) file=stdout;
	ortp_set_log_file(file);
	ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
}

304 305 306 307 308 309 310
/**
 * Enable logs through the user's supplied log callback.
 *
 * @ingroup misc
 *
 * @param logfunc The address of a OrtpLogFunc callback whose protoype is
 *            	  typedef void (*OrtpLogFunc)(OrtpLogLevel lev, const char *fmt, va_list args);
311
 *
312
**/
aymeric's avatar
aymeric committed
313 314 315 316 317
void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){
	ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
	ortp_set_log_handler(logfunc);
}

318 319 320 321 322
/**
 * Entirely disable logging.
 *
 * @ingroup misc
**/
aymeric's avatar
aymeric committed
323 324 325 326 327
void linphone_core_disable_logs(){
	ortp_set_log_level_mask(ORTP_ERROR|ORTP_FATAL);
}


328
static void net_config_read (LinphoneCore *lc)
aymeric's avatar
aymeric committed
329 330 331 332 333
{
	int tmp;
	const char *tmpstr;
	LpConfig *config=lc->config;

334
	lc->net_conf.nat_address_ip = NULL;
aymeric's avatar
aymeric committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348
	tmp=lp_config_get_int(config,"net","download_bw",0);
	linphone_core_set_download_bandwidth(lc,tmp);
	tmp=lp_config_get_int(config,"net","upload_bw",0);
	linphone_core_set_upload_bandwidth(lc,tmp);
	linphone_core_set_stun_server(lc,lp_config_get_string(config,"net","stun_server",NULL));
	tmpstr=lp_config_get_string(lc->config,"net","nat_address",NULL);
	if (tmpstr!=NULL && (strlen(tmpstr)<1)) tmpstr=NULL;
	linphone_core_set_nat_address(lc,tmpstr);
	tmp=lp_config_get_int(lc->config,"net","firewall_policy",0);
	linphone_core_set_firewall_policy(lc,tmp);
	tmp=lp_config_get_int(lc->config,"net","nat_sdp_only",0);
	lc->net_conf.nat_sdp_only=tmp;
	tmp=lp_config_get_int(lc->config,"net","mtu",0);
	linphone_core_set_mtu(lc,tmp);
jehan's avatar
jehan committed
349 350 351
	tmp=lp_config_get_int(lc->config,"net","download_ptime",0);
	linphone_core_set_download_ptime(lc,tmp);

aymeric's avatar
aymeric committed
352 353
}

354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
static void build_sound_devices_table(LinphoneCore *lc){
	const char **devices;
	const char **old;
	int ndev;
	int i;
	const MSList *elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get());
	ndev=ms_list_size(elem);
	devices=ms_malloc((ndev+1)*sizeof(const char *));
	for (i=0;elem!=NULL;elem=elem->next,i++){
		devices[i]=ms_snd_card_get_string_id((MSSndCard *)elem->data);
	}
	devices[ndev]=NULL;
	old=lc->sound_conf.cards;
	lc->sound_conf.cards=devices;
	if (old!=NULL) ms_free(old);
}
aymeric's avatar
aymeric committed
370

371
static void sound_config_read(LinphoneCore *lc)
aymeric's avatar
aymeric committed
372
{
373
	int tmp;
aymeric's avatar
aymeric committed
374 375
	const char *tmpbuf;
	const char *devid;
376
	float gain=0;
377
#ifdef __linux
aymeric's avatar
aymeric committed
378 379 380 381 382 383 384 385
	/*alsadev let the user use custom alsa device within linphone*/
	devid=lp_config_get_string(lc->config,"sound","alsadev",NULL);
	if (devid){
		MSSndCard *card=ms_alsa_card_new_custom(devid,devid);
		ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
	}
#endif
	/* retrieve all sound devices */
386 387
	build_sound_devices_table(lc);

aymeric's avatar
aymeric committed
388 389
	devid=lp_config_get_string(lc->config,"sound","playback_dev_id",NULL);
	linphone_core_set_playback_device(lc,devid);
390

aymeric's avatar
aymeric committed
391 392
	devid=lp_config_get_string(lc->config,"sound","ringer_dev_id",NULL);
	linphone_core_set_ringer_device(lc,devid);
393

aymeric's avatar
aymeric committed
394 395
	devid=lp_config_get_string(lc->config,"sound","capture_dev_id",NULL);
	linphone_core_set_capture_device(lc,devid);
396

aymeric's avatar
aymeric committed
397 398 399 400 401 402 403 404 405 406
/*
	tmp=lp_config_get_int(lc->config,"sound","play_lev",80);
	linphone_core_set_play_level(lc,tmp);
	tmp=lp_config_get_int(lc->config,"sound","ring_lev",80);
	linphone_core_set_ring_level(lc,tmp);
	tmp=lp_config_get_int(lc->config,"sound","rec_lev",80);
	linphone_core_set_rec_level(lc,tmp);
	tmpbuf=lp_config_get_string(lc->config,"sound","source","m");
	linphone_core_set_sound_source(lc,tmpbuf[0]);
*/
407

aymeric's avatar
aymeric committed
408 409
	tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING;
	tmpbuf=lp_config_get_string(lc->config,"sound","local_ring",tmpbuf);
Jehan Monnier's avatar
Jehan Monnier committed
410
	if (ortp_file_exist(tmpbuf)==-1) {
411
		ms_warning("%s does not exist",tmpbuf);
aymeric's avatar
aymeric committed
412 413 414 415 416 417 418
		tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING;
	}
	if (strstr(tmpbuf,".wav")==NULL){
		/* it currently uses old sound files, so replace them */
		tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING;
	}
	linphone_core_set_ring(lc,tmpbuf);
419

420
	tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING;
aymeric's avatar
aymeric committed
421
	tmpbuf=lp_config_get_string(lc->config,"sound","remote_ring",tmpbuf);
Jehan Monnier's avatar
Jehan Monnier committed
422
	if (ortp_file_exist(tmpbuf)==-1){
423
		tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING;
aymeric's avatar
aymeric committed
424 425 426
	}
	if (strstr(tmpbuf,".wav")==NULL){
		/* it currently uses old sound files, so replace them */
427
		tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING;
aymeric's avatar
aymeric committed
428
	}
429
	linphone_core_set_ringback(lc,tmpbuf);
430 431

	linphone_core_set_play_file(lc,lp_config_get_string(lc->config,"sound","hold_music",PACKAGE_SOUND_DIR "/" HOLD_MUSIC));
aymeric's avatar
aymeric committed
432 433
	check_sound_device(lc);
	lc->sound_conf.latency=0;
434 435
#if !defined(TARGET_OS_IPHONE) && !defined(ANDROID)
    tmp=TRUE;
436
#else
437 438 439 440
    tmp=FALSE;
#endif
    tmp=lp_config_get_int(lc->config,"sound","echocancellation",tmp);
	linphone_core_enable_echo_cancellation(lc,tmp);
smorlat's avatar
smorlat committed
441 442
	linphone_core_enable_echo_limiter(lc,
		lp_config_get_int(lc->config,"sound","echolimiter",0));
443 444
	linphone_core_enable_agc(lc,
		lp_config_get_int(lc->config,"sound","agc",0));
445

446 447
	gain=lp_config_get_float(lc->config,"sound","playback_gain_db",0);
	linphone_core_set_playback_gain_db (lc,gain);
448 449

	linphone_core_set_remote_ringback_tone (lc,lp_config_get_string(lc->config,"sound","ringback_tone",NULL));
aymeric's avatar
aymeric committed
450 451
}

452
static void sip_config_read(LinphoneCore *lc)
aymeric's avatar
aymeric committed
453 454 455
{
	char *contact;
	const char *tmpstr;
456
	LCSipTransports tr;
aymeric's avatar
aymeric committed
457 458
	int i,tmp;
	int ipv6;
459

460 461
	tmp=lp_config_get_int(lc->config,"sip","use_info",0);
	linphone_core_set_use_info_for_dtmf(lc,tmp);
aymeric's avatar
aymeric committed
462

463 464 465
	if (lp_config_get_int(lc->config,"sip","use_session_timers",0)==1){
		sal_use_session_timers(lc->sal,200);
	}
aymeric's avatar
aymeric committed
466

467
	sal_use_rport(lc->sal,lp_config_get_int(lc->config,"sip","use_rport",1));
468
	sal_use_101(lc->sal,lp_config_get_int(lc->config,"sip","use_101",1));
469
	sal_reuse_authorization(lc->sal, lp_config_get_int(lc->config,"sip","reuse_authorization",0));
470

471 472
	tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
	linphone_core_set_use_rfc2833_for_dtmf(lc,tmp);
473

aymeric's avatar
aymeric committed
474 475 476 477 478
	ipv6=lp_config_get_int(lc->config,"sip","use_ipv6",-1);
	if (ipv6==-1){
		ipv6=0;
	}
	linphone_core_enable_ipv6(lc,ipv6);
479
	memset(&tr,0,sizeof(tr));
jehan's avatar
jehan committed
480 481 482 483 484 485 486 487 488 489
	if (lp_config_get_int(lc->config,"sip","sip_random_port",0)) {
		tr.udp_port=(0xDFF&+random())+1024;
	} else {
		tr.udp_port=lp_config_get_int(lc->config,"sip","sip_port",5060);
	}
	if (lp_config_get_int(lc->config,"sip","sip_tcp_random_port",0)) {
		tr.tcp_port=(0xDFF&+random())+1024;
	} else {
		tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",0);
	}
Pierre-Eric's avatar
Pierre-Eric committed
490 491 492 493 494
	if (lp_config_get_int(lc->config,"sip","sip_tls_random_port",0)) {
		tr.tls_port=(0xDFF&+random())+1024;
	} else {
		tr.tls_port=lp_config_get_int(lc->config,"sip","sip_tls_port",0);
	}
495 496
	/*start listening on ports*/
 	linphone_core_set_sip_transports(lc,&tr);
497

aymeric's avatar
aymeric committed
498 499
	tmpstr=lp_config_get_string(lc->config,"sip","contact",NULL);
	if (tmpstr==NULL || linphone_core_set_primary_contact(lc,tmpstr)==-1) {
smorlat's avatar
smorlat committed
500 501
		const char *hostname=NULL;
		const char *username=NULL;
502
#ifdef HAVE_GETENV
smorlat's avatar
smorlat committed
503 504
		hostname=getenv("HOST");
		username=getenv("USER");
aymeric's avatar
aymeric committed
505
		if (hostname==NULL) hostname=getenv("HOSTNAME");
506
#endif /*HAVE_GETENV*/
aymeric's avatar
aymeric committed
507 508 509 510 511 512 513 514 515 516
		if (hostname==NULL)
			hostname="unknown-host";
		if (username==NULL){
			username="toto";
		}
		contact=ortp_strdup_printf("sip:%s@%s",username,hostname);
		linphone_core_set_primary_contact(lc,contact);
		ms_free(contact);
	}

517 518
	sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs"));

aymeric's avatar
aymeric committed
519 520
	tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1);
	linphone_core_set_guess_hostname(lc,tmp);
521 522


aymeric's avatar
aymeric committed
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
	tmp=lp_config_get_int(lc->config,"sip","inc_timeout",15);
	linphone_core_set_inc_timeout(lc,tmp);

	/* get proxies config */
	for(i=0;; i++){
		LinphoneProxyConfig *cfg=linphone_proxy_config_new_from_config_file(lc->config,i);
		if (cfg!=NULL){
			linphone_core_add_proxy_config(lc,cfg);
		}else{
			break;
		}
	}
	/* get the default proxy */
	tmp=lp_config_get_int(lc->config,"sip","default_proxy",-1);
	linphone_core_set_default_proxy_index(lc,tmp);
538

aymeric's avatar
aymeric committed
539 540 541 542 543
	/* read authentication information */
	for(i=0;; i++){
		LinphoneAuthInfo *ai=linphone_auth_info_new_from_config_file(lc->config,i);
		if (ai!=NULL){
			linphone_core_add_auth_info(lc,ai);
Simon Morlat's avatar
Simon Morlat committed
544
			linphone_auth_info_destroy(ai);
aymeric's avatar
aymeric committed
545 546 547 548
		}else{
			break;
		}
	}
549

550
	/*for tuning or test*/
aymeric's avatar
aymeric committed
551
	lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
552
	lc->sip_conf.register_only_when_network_is_up=
553
		lp_config_get_int(lc->config,"sip","register_only_when_network_is_up",1);
554
	lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1);
jehan's avatar
jehan committed
555
	lc->sip_conf.auto_net_state_mon=lp_config_get_int(lc->config,"sip","auto_net_state_mon",1);
556 557
	lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
	sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
Simon Morlat's avatar
Simon Morlat committed
558
	sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
559
	sal_use_double_registrations(lc->sal,lp_config_get_int(lc->config,"sip","use_double_registrations",1));
aymeric's avatar
aymeric committed
560 561
}

562
static void rtp_config_read(LinphoneCore *lc)
aymeric's avatar
aymeric committed
563 564 565 566
{
	int port;
	int jitt_comp;
	int nortp_timeout;
Simon Morlat's avatar
Simon Morlat committed
567 568
	bool_t rtp_no_xmit_on_audio_mute;

aymeric's avatar
aymeric committed
569 570
	port=lp_config_get_int(lc->config,"rtp","audio_rtp_port",7078);
	linphone_core_set_audio_port(lc,port);
571

aymeric's avatar
aymeric committed
572 573 574
	port=lp_config_get_int(lc->config,"rtp","video_rtp_port",9078);
	if (port==0) port=9078;
	linphone_core_set_video_port(lc,port);
575

aymeric's avatar
aymeric committed
576
	jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
577
	linphone_core_set_audio_jittcomp(lc,jitt_comp);
aymeric's avatar
aymeric committed
578
	jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60);
579 580
	if (jitt_comp==0) jitt_comp=60;
	lc->rtp_conf.video_jitt_comp=jitt_comp;
aymeric's avatar
aymeric committed
581
	nortp_timeout=lp_config_get_int(lc->config,"rtp","nortp_timeout",30);
582
	linphone_core_set_nortp_timeout(lc,nortp_timeout);
Simon Morlat's avatar
Simon Morlat committed
583
	rtp_no_xmit_on_audio_mute=lp_config_get_int(lc->config,"rtp","rtp_no_xmit_on_audio_mute",FALSE);
584
	linphone_core_set_rtp_no_xmit_on_audio_mute(lc,rtp_no_xmit_on_audio_mute);
aymeric's avatar
aymeric committed
585 586
}

587 588 589 590 591 592 593 594
static PayloadType * find_payload(RtpProfile *prof, const char *mime_type, int clock_rate, const char *recv_fmtp){
	PayloadType *candidate=NULL;
	int i;
	PayloadType *it;
	for(i=0;i<127;++i){
		it=rtp_profile_get_payload(prof,i);
		if (it!=NULL && strcasecmp(mime_type,it->mime_type)==0
			&& (clock_rate==it->clock_rate || clock_rate<=0) ){
595
			if ( (recv_fmtp && it->recv_fmtp && strstr(recv_fmtp,it->recv_fmtp)!=NULL) ||
596 597
				(recv_fmtp==NULL && it->recv_fmtp==NULL) ){
				/*exact match*/
598
				if (recv_fmtp) payload_type_set_recv_fmtp(it,recv_fmtp);
599
				return it;
600 601 602 603 604
			}else {
				if (candidate){
					if (it->recv_fmtp==NULL) candidate=it;
				}else candidate=it;
			}
605 606
		}
	}
607 608 609
	if (candidate && recv_fmtp){
		payload_type_set_recv_fmtp(candidate,recv_fmtp);
	}
610 611
	return candidate;
}
aymeric's avatar
aymeric committed
612

613
static bool_t get_codec(LpConfig *config, const char* type, int index, PayloadType **ret){
aymeric's avatar
aymeric committed
614 615 616 617
	char codeckey[50];
	const char *mime,*fmtp;
	int rate,enabled;
	PayloadType *pt;
618

619
	*ret=NULL;
aymeric's avatar
aymeric committed
620 621
	snprintf(codeckey,50,"%s_%i",type,index);
	mime=lp_config_get_string(config,codeckey,"mime",NULL);
622
	if (mime==NULL || strlen(mime)==0 ) return FALSE;
623

aymeric's avatar
aymeric committed
624 625 626
	rate=lp_config_get_int(config,codeckey,"rate",8000);
	fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL);
	enabled=lp_config_get_int(config,codeckey,"enabled",1);
627 628
	pt=find_payload(&av_profile,mime,rate,fmtp);
	if (pt && enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED;
aymeric's avatar
aymeric committed
629
	//ms_message("Found codec %s/%i",pt->mime_type,pt->clock_rate);
630 631 632 633 634 635
	if (pt==NULL) ms_warning("Ignoring codec config %s/%i with fmtp=%s because unsupported",
	    		mime,rate,fmtp ? fmtp : "");
	*ret=pt;
	return TRUE;
}

636
#define RANK_END 10000
637 638
static const char *codec_pref_order[]={
	"speex",
639 640
	"iLBC",
	"amr",
641 642 643
	"gsm",
	"pcmu",
	"pcma",
Simon Morlat's avatar
Simon Morlat committed
644
	"VP8-DRAFT-0-3-2",
645 646 647 648 649 650 651 652 653 654
	"H264",
	"MP4V-ES",
	"H263-1998",
	NULL,
};

static int find_codec_rank(const char *mime){
	int i;
	for(i=0;codec_pref_order[i]!=NULL;++i){
		if (strcasecmp(codec_pref_order[i],mime)==0)
655
			return i;
656
	}
657
	return RANK_END;
658 659 660 661 662 663 664 665
}

static int codec_compare(const PayloadType *a, const PayloadType *b){
	int ra,rb;
	ra=find_codec_rank(a->mime_type);
	rb=find_codec_rank(b->mime_type);
	if (ra>rb) return 1;
	if (ra<rb) return -1;
666
	return 0;
667 668
}

669 670 671 672 673 674 675
static MSList *add_missing_codecs(SalStreamType mtype, MSList *l){
	int i;
	for(i=0;i<127;++i){
		PayloadType *pt=rtp_profile_get_payload(&av_profile,i);
		if (pt){
			if (mtype==SalVideo && pt->type!=PAYLOAD_VIDEO)
				pt=NULL;
676
			else if (mtype==SalAudio && (pt->type!=PAYLOAD_AUDIO_PACKETIZED
677 678 679 680 681
			    && pt->type!=PAYLOAD_AUDIO_CONTINUOUS)){
				pt=NULL;
			}
			if (pt && ms_filter_codec_supported(pt->mime_type)){
				if (ms_list_find(l,pt)==NULL){
682 683
					/*unranked codecs are disabled by default*/
					if (find_codec_rank(pt->mime_type)!=RANK_END){
684 685
						payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED);
					}
686 687
					ms_message("Adding new codec %s/%i with fmtp %s",
					    pt->mime_type,pt->clock_rate,pt->recv_fmtp ? pt->recv_fmtp : "");
688
					l=ms_list_insert_sorted(l,pt,(int (*)(const void *, const void *))codec_compare);
689 690 691 692 693
				}
			}
		}
	}
	return l;
aymeric's avatar
aymeric committed
694 695
}

696 697
static MSList *codec_append_if_new(MSList *l, PayloadType *pt){
	MSList *elem;
698
	for (elem=l;elem!=NULL;elem=elem->next){
699 700 701 702 703 704 705 706
		PayloadType *ept=(PayloadType*)elem->data;
		if (pt==ept)
			return l;
	}
	l=ms_list_append(l,pt);
	return l;
}

707
static void codecs_config_read(LinphoneCore *lc)
aymeric's avatar
aymeric committed
708 709 710 711 712
{
	int i;
	PayloadType *pt;
	MSList *audio_codecs=NULL;
	MSList *video_codecs=NULL;
713 714 715 716
	for (i=0;get_codec(lc->config,"audio_codec",i,&pt);i++){
		if (pt){
			if (!ms_filter_codec_supported(pt->mime_type)){
				ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
717
			}else audio_codecs=codec_append_if_new(audio_codecs,pt);
718
		}
aymeric's avatar
aymeric committed
719
	}
720 721 722 723 724
	audio_codecs=add_missing_codecs(SalAudio,audio_codecs);
	for (i=0;get_codec(lc->config,"video_codec",i,&pt);i++){
		if (pt){
			if (!ms_filter_codec_supported(pt->mime_type)){
				ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
725
			}else video_codecs=codec_append_if_new(video_codecs,(void *)pt);
726
		}
aymeric's avatar
aymeric committed
727
	}
728
	video_codecs=add_missing_codecs(SalVideo,video_codecs);
aymeric's avatar
aymeric committed
729 730
	linphone_core_set_audio_codecs(lc,audio_codecs);
	linphone_core_set_video_codecs(lc,video_codecs);
731
	linphone_core_update_allocated_audio_bandwidth(lc);
aymeric's avatar
aymeric committed
732 733
}

734
static void video_config_read(LinphoneCore *lc){
Simon Morlat's avatar
Simon Morlat committed
735
	int capture, display, self_view;
aymeric's avatar
aymeric committed
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
	const char *str;
	int ndev;
	const char **devices;
	const MSList *elem;
	int i;

	/* retrieve all video devices */
	elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get());
	ndev=ms_list_size(elem);
	devices=ms_malloc((ndev+1)*sizeof(const char *));
	for (i=0;elem!=NULL;elem=elem->next,i++){
		devices[i]=ms_web_cam_get_string_id((MSWebCam *)elem->data);
	}
	devices[ndev]=NULL;
	lc->video_conf.cams=devices;

	str=lp_config_get_string(lc->config,"video","device",NULL);
	if (str && str[0]==0) str=NULL;
	linphone_core_set_video_device(lc,str);
755

smorlat's avatar
smorlat committed
756 757 758
	linphone_core_set_preferred_video_size_by_name(lc,
		lp_config_get_string(lc->config,"video","size","cif"));

759 760 761
	capture=lp_config_get_int(lc->config,"video","capture",1);
	display=lp_config_get_int(lc->config,"video","display",1);
	self_view=lp_config_get_int(lc->config,"video","self_view",1);
762 763 764
	lc->video_conf.displaytype=lp_config_get_string(lc->config,"video","displaytype",NULL);
	if(lc->video_conf.displaytype)
		ms_message("we are using a specific display:%s\n",lc->video_conf.displaytype);
aymeric's avatar
aymeric committed
765 766
#ifdef VIDEO_ENABLED
	linphone_core_enable_video(lc,capture,display);
Simon Morlat's avatar
Simon Morlat committed
767
	linphone_core_enable_self_view(lc,self_view);
aymeric's avatar
aymeric committed
768 769 770
#endif
}

771
static void ui_config_read(LinphoneCore *lc)
aymeric's avatar
aymeric committed
772 773 774 775 776 777
{
	LinphoneFriend *lf;
	int i;
	for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){
		linphone_core_add_friend(lc,lf);
	}
778
	call_logs_read_from_config_file(lc);
aymeric's avatar
aymeric committed
779 780
}

781 782
/*
static void autoreplier_config_init(LinphoneCore *lc)
aymeric's avatar
aymeric committed
783 784 785 786 787 788 789 790 791
{
	autoreplier_config_t *config=&lc->autoreplier_conf;
	config->enabled=lp_config_get_int(lc->config,"autoreplier","enabled",0);
	config->after_seconds=lp_config_get_int(lc->config,"autoreplier","after_seconds",6);
	config->max_users=lp_config_get_int(lc->config,"autoreplier","max_users",1);
	config->max_rec_time=lp_config_get_int(lc->config,"autoreplier","max_rec_time",60);
	config->max_rec_msg=lp_config_get_int(lc->config,"autoreplier","max_rec_msg",10);
	config->message=lp_config_get_string(lc->config,"autoreplier","message",NULL);
}
792
*/
aymeric's avatar
aymeric committed
793

794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
/**
 * Enable adaptive rate control (experimental feature, audio-only).
 *
 * Adaptive rate control consists in using RTCP feedback provided information to dynamically
 * control the output bitrate of the encoders, so that we can adapt to the network conditions and
 * available bandwidth.
**/
void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled){
	lp_config_set_int(lc->config,"net","adaptive_rate_control",(int)enabled);
}

/**
 * Returns whether adaptive rate control is enabled.
 *
 * See linphone_core_enable_adaptive_rate_control().
**/
bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){
	return lp_config_get_int(lc->config,"net","adaptive_rate_control",FALSE);
}

814 815 816 817 818 819 820 821 822 823 824 825 826 827
/**
 * Sets maximum available download bandwidth
 *
 * @ingroup media_parameters
 *
 * This is IP bandwidth, in kbit/s.
 * This information is used signaled to other parties during
 * calls (within SDP messages) so that the remote end can have
 * sufficient knowledge to properly configure its audio & video
 * codec output bitrate to not overflow available bandwidth.
 *
 * @param lc the LinphoneCore object
 * @param bw the bandwidth in kbits/s, 0 for infinite
 */
aymeric's avatar
aymeric committed
828 829 830 831
void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
	lc->net_conf.download_bw=bw;
}

832 833 834 835 836 837 838 839 840 841 842 843 844
/**
 * Sets maximum available upload bandwidth
 *
 * @ingroup media_parameters
 *
 * This is IP bandwidth, in kbit/s.
 * This information is used by liblinphone together with remote
 * side available bandwidth signaled in SDP messages to properly
 * configure audio & video codec's output bitrate.
 *
 * @param lc the LinphoneCore object
 * @param bw the bandwidth in kbits/s, 0 for infinite
 */
aymeric's avatar
aymeric committed
845 846 847 848
void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){
	lc->net_conf.upload_bw=bw;
}

849 850 851 852 853 854 855 856
/**
 * Retrieve the maximum available download bandwidth.
 *
 * @ingroup media_parameters
 *
 * This value was set by linphone_core_set_download_bandwidth().
 *
**/
aymeric's avatar
aymeric committed
857 858 859 860
int linphone_core_get_download_bandwidth(const LinphoneCore *lc){
	return lc->net_conf.download_bw;
}

861 862 863 864 865 866 867 868
/**
 * Retrieve the maximum available upload bandwidth.
 *
 * @ingroup media_parameters
 *
 * This value was set by linphone_core_set_upload_bandwidth().
 *
**/
aymeric's avatar
aymeric committed
869 870 871
int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){
	return lc->net_conf.upload_bw;
}
jehan's avatar
jehan committed
872
/**
873
 * Set audio packetization time linphone expects to receive from peer
jehan's avatar
jehan committed
874 875
 */
void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) {
876
	lc->net_conf.down_ptime=ptime;
jehan's avatar
jehan committed
877
}
878

879 880 881 882
/**
 * Get audio packetization time linphone expects to receive from peer
 */
int linphone_core_get_download_ptime(LinphoneCore *lc) {
883
	return lc->net_conf.down_ptime;
jehan's avatar
jehan committed
884 885
}

886 887 888 889 890 891
/**
 * Set audio packetization time linphone will send (in absence of requirement from peer)
 * A value of 0 stands for the current codec default packetization time.
 *
**/
void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){
892
	lp_config_set_int(lc->config,"rtp","upload_ptime",ptime);
893 894 895 896 897 898 899 900
}

/**
 * Set audio packetization time linphone will send (in absence of requirement from peer)
 * A value of 0 stands for the current codec default packetization time.
 *
**/
int linphone_core_get_upload_ptime(LinphoneCore *lc){
901
	return lp_config_get_int(lc->config,"rtp","upload_ptime",0);
902 903 904
}


aymeric's avatar
aymeric committed
905

906 907 908 909 910 911
/**
 * Returns liblinphone's version as a string.
 *
 * @ingroup misc
 *
**/
aymeric's avatar
aymeric committed
912 913 914 915
const char * linphone_core_get_version(void){
	return liblinphone_version;
}

916
static void linphone_core_assign_payload_type(LinphoneCore *lc, PayloadType *const_pt, int number, const char *recv_fmtp){
917 918
	PayloadType *pt;
	pt=payload_type_clone(const_pt);
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
	if (number==-1){
		/*look for a free number */
		MSList *elem;
		int i;
		for(i=lc->dyn_pt;i<=127;++i){
			bool_t already_assigned=FALSE;
			for(elem=lc->payload_types;elem!=NULL;elem=elem->next){
				PayloadType *it=(PayloadType*)elem->data;
				if (payload_type_get_number(it)==i){
					already_assigned=TRUE;
					break;
				}
			}
			if (!already_assigned){
				number=i;
				lc->dyn_pt=i+1;
				break;
			}
		}
		if (number==-1){
			ms_fatal("FIXME: too many codecs, no more free numbers.");
		}
	}
	ms_message("assigning %s/%i payload type number %i",pt->mime_type,pt->clock_rate,number);
943
	payload_type_set_number(pt,number);
944 945
	if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp);
	rtp_profile_set_payload(&av_profile,number,pt);
946
	lc->payload_types=ms_list_append(lc->payload_types,pt);
947 948
}

949 950 951 952
static void linphone_core_free_payload_types(LinphoneCore *lc){
	ms_list_for_each(lc->payload_types,(void (*)(void*))payload_type_destroy);
	ms_list_free(lc->payload_types);
	lc->payload_types=NULL;
953
}
954

955
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message){
Simon Morlat's avatar
Simon Morlat committed
956
	lc->state=gstate;
957 958 959 960
	if (lc->vtable.global_state_changed){
		lc->vtable.global_state_changed(lc,gstate,message);
	}
}
961 962 963 964
static void misc_config_read (LinphoneCore *lc) {
	LpConfig *config=lc->config;
    lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",15);
}
965

966
static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path,
967
    const char *factory_config_path, void * userdata)
aymeric's avatar
aymeric committed
968 969 970
{
	memset (lc, 0, sizeof (LinphoneCore));
	lc->data=userdata;
971
	lc->ringstream_autorelease=TRUE;
972

aymeric's avatar
aymeric committed
973 974
	memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable));

975
	linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
aymeric's avatar
aymeric committed
976
	ortp_init();
977 978 979 980 981 982 983 984
	lc->dyn_pt=96;
	linphone_core_assign_payload_type(lc,&payload_type_pcmu8000,0,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_gsm,3,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_pcma8000,8,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_speex_nb,110,"vbr=on");
	linphone_core_assign_payload_type(lc,&payload_type_speex_wb,111,"vbr=on");
	linphone_core_assign_payload_type(lc,&payload_type_speex_uwb,112,"vbr=on");
	linphone_core_assign_payload_type(lc,&payload_type_telephone_event,101,"0-11");
985

986 987 988 989 990 991 992 993
#if defined(ANDROID) || defined (__IPHONE_OS_VERSION_MIN_REQUIRED)
	/*shorten the DNS lookup time and send more retransmissions on mobiles:
	 - to workaround potential packet losses
	 - to avoid hanging for 30 seconds when the network doesn't work despite the phone thinks it does.
	 */
	_linphone_core_configure_resolver();
#endif

994 995 996 997 998
#ifdef ENABLE_NONSTANDARD_GSM
	{
		PayloadType *pt;
		pt=payload_type_clone(&payload_type_gsm);
		pt->clock_rate=11025;
999
		linphone_core_assign_payload_type(lc,pt,-1,NULL);
1000
		pt->clock_rate=22050;
1001 1002
		linphone_core_assign_payload_type(lc,pt,-1,NULL);
		payload_type_destroy(pt);
1003
	}
aymeric's avatar
aymeric committed
1004 1005
#endif

1006
#ifdef VIDEO_ENABLED
1007 1008 1009 1010 1011 1012 1013
	linphone_core_assign_payload_type(lc,&payload_type_h263,34,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_h263_1998,98,"CIF=1;QCIF=1");
	linphone_core_assign_payload_type(lc,&payload_type_mp4v,99,"profile-level-id=3");
	linphone_core_assign_payload_type(lc,&payload_type_h264,102,"profile-level-id=428014");
	linphone_core_assign_payload_type(lc,&payload_type_vp8,103,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL);
1014
	/* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */
1015
	/* linphone_core_assign_payload_type(&payload_type_h264,-1,"packetization-mode=1;profile-level-id=428014");*/
1016 1017
#endif

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
	/*add all payload type for which we don't care about the number */
	linphone_core_assign_payload_type(lc,&payload_type_ilbc,-1,"mode=30");
	linphone_core_assign_payload_type(lc,&payload_type_amr,-1,"octet-align=1");
	linphone_core_assign_payload_type(lc,&payload_type_lpc1015,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_g726_16,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_g726_24,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_g726_32,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_g726_40,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_16,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_24,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_32,-1,NULL);
	linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_40,-1,NULL);

aymeric's avatar
aymeric committed
1031
	ms_init();
1032