mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
371 lines
13 KiB
Objective-C
371 lines
13 KiB
Objective-C
//
|
|
// LinphoneCoreSettingsStore.m
|
|
// linphone
|
|
//
|
|
// Created by Pierre-Eric Pelloux-Prayer on 22/05/12.
|
|
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
|
//
|
|
|
|
#import "LinphoneCoreSettingsStore.h"
|
|
|
|
#include "lpconfig.h"
|
|
|
|
|
|
struct codec_name_pref_table{
|
|
const char *name;
|
|
int rate;
|
|
NSString *prefname;
|
|
};
|
|
|
|
struct codec_name_pref_table codec_pref_table[]={
|
|
{ "speex", 8000, @"speex_8k_preference" },
|
|
{ "speex", 16000, @"speex_16k_preference" },
|
|
{ "silk", 24000, @"silk_24k_preference" },
|
|
{ "silk", 16000, @"silk_16k_preference" },
|
|
{ "amr", 8000, @"amr_8k_preference" },
|
|
{ "ilbc", 8000, @"ilbc_preference"},
|
|
{ "pcmu", 8000, @"pcmu_preference"},
|
|
{ "pcma", 8000, @"pcma_preference"},
|
|
{ "g722", 8000, @"g722_preference"},
|
|
{ "g729", 8000, @"g729_preference"},
|
|
{ "mp4v-es", 90000, @"mp4v-es_preference"},
|
|
{ "h264", 90000, @"h264_preference"},
|
|
{ "vp8", 90000, @"vp8_preference"},
|
|
{ NULL,0,Nil }
|
|
};
|
|
|
|
static NSString *getPrefForCodec(const char *name, int rate){
|
|
int i;
|
|
for(i=0;codec_pref_table[i].name!=NULL;++i){
|
|
if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate)
|
|
return codec_pref_table[i].prefname;
|
|
}
|
|
return Nil;
|
|
}
|
|
|
|
@implementation LinphoneCoreSettingsStore
|
|
|
|
-(id) init{
|
|
self = [super init];
|
|
if (self){
|
|
dict=[[NSMutableDictionary alloc] init];
|
|
[self transformLinphoneCoreToKeys];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
-(void) dealloc{
|
|
[super dealloc];
|
|
[dict release];
|
|
}
|
|
|
|
-(void) transformKeysToLinphoneCore{
|
|
//LinphoneCore *lc=[LinphoneManager getLc];
|
|
|
|
}
|
|
|
|
- (void) setString:(const char*)value forKey:(NSString*)key{
|
|
id obj=Nil;
|
|
if (value) obj=[[NSString alloc] initWithCString:value encoding:[NSString defaultCStringEncoding] ];
|
|
[self setObject: obj forKey:key];
|
|
}
|
|
|
|
- (NSString*) stringForKey:(NSString*) key{
|
|
return [self objectForKey: key];
|
|
}
|
|
|
|
-(void) transformCodecsToKeys: (const MSList *)codecs{
|
|
LinphoneCore *lc=[LinphoneManager getLc];
|
|
const MSList *elem=codecs;
|
|
for(;elem!=NULL;elem=elem->next){
|
|
PayloadType *pt=(PayloadType*)elem->data;
|
|
NSString *pref=getPrefForCodec(pt->mime_type,pt->clock_rate);
|
|
if (pref){
|
|
[self setBool: linphone_core_payload_type_enabled(lc,pt) forKey: pref];
|
|
}else{
|
|
ms_warning("Codec %s/%i supported by core is not shown in iOS app config view.",
|
|
pt->mime_type,pt->clock_rate);
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void) transformLinphoneCoreToKeys{
|
|
LinphoneCore *lc=[LinphoneManager getLc];
|
|
LinphoneProxyConfig *cfg=NULL;
|
|
linphone_core_get_default_proxy(lc,&cfg);
|
|
if (cfg){
|
|
const char *identity=linphone_proxy_config_get_identity(cfg);
|
|
LinphoneAddress *addr=linphone_address_new(identity);
|
|
if (addr){
|
|
const char *proxy=linphone_proxy_config_get_addr(cfg);
|
|
LinphoneAddress *proxy_addr=linphone_address_new(proxy);
|
|
const char *port=linphone_address_get_port(proxy_addr);
|
|
|
|
[self setString: linphone_address_get_username(addr) forKey:@"username_preference"];
|
|
[self setString: linphone_address_get_domain(addr) forKey:@"domain_preference"];
|
|
if (strcmp(linphone_address_get_domain(addr),linphone_address_get_domain(proxy_addr))!=0
|
|
|| port!=NULL){
|
|
char tmp[256]={0};
|
|
if (port!=NULL) {
|
|
snprintf(tmp,sizeof(tmp)-1,"%s:%s",linphone_address_get_domain(proxy_addr),port);
|
|
}else snprintf(tmp,sizeof(tmp)-1,"%s",linphone_address_get_domain(proxy_addr));
|
|
[self setString: tmp forKey:@"proxy_preference"];
|
|
}
|
|
linphone_address_destroy(addr);
|
|
linphone_address_destroy(proxy_addr);
|
|
|
|
[self setBool: (linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"];
|
|
|
|
}
|
|
}
|
|
{
|
|
LCSipTransports tp;
|
|
const char *tname="udp";
|
|
linphone_core_get_sip_transports(lc, &tp);
|
|
if (tp.udp_port>0) tname="udp";
|
|
else if (tp.tcp_port>0) tname="tcp";
|
|
else if (tp.tls_port>0) tname="tls";
|
|
[self setString: tname forKey:@"transport_preference"];
|
|
}
|
|
{
|
|
LinphoneAuthInfo *ai;
|
|
const MSList *elem=linphone_core_get_auth_info_list(lc);
|
|
if (elem && (ai=(LinphoneAuthInfo*)elem->data)){
|
|
[self setString: linphone_auth_info_get_passwd(ai) forKey:@"password_preference"];
|
|
}
|
|
}
|
|
{
|
|
[self setString: linphone_core_get_stun_server(lc) forKey:@"stun_preference"];
|
|
}
|
|
|
|
{
|
|
[self transformCodecsToKeys: linphone_core_get_audio_codecs(lc)];
|
|
[self transformCodecsToKeys: linphone_core_get_video_codecs(lc)];
|
|
}
|
|
|
|
{
|
|
LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc);
|
|
const char *val;
|
|
switch(menc){
|
|
LinphoneMediaEncryptionSRTP:
|
|
val="SRTP";
|
|
break;
|
|
LinphoneMediaEncryptionZRTP:
|
|
val="ZRTP";
|
|
break;
|
|
default:
|
|
val="None";
|
|
}
|
|
[self setString:val forKey:@"media_encryption_preference"];
|
|
}
|
|
|
|
[self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","debugenable_preference",0) forKey:@"debugenable_preference"];
|
|
[self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","check_config_disable_preference",0) forKey:@"check_config_disable_preference"];
|
|
[self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","wifi_only_preference",0) forKey:@"wifi_only_preference"];
|
|
[self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","backgroundmode_preference",TRUE) forKey:@"backgroundmode_preference"];
|
|
[self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","start_at_boot_preference",TRUE) forKey:@"disable_autoboot_preference"];
|
|
|
|
if (linphone_core_tunnel_available()){
|
|
/*FIXME: enhance linphonecore API to handle tunnel more easily in applications */
|
|
LinphoneTunnel *tun=linphone_core_get_tunnel(lc);
|
|
//[self setString: linphone_tunnel_get_servers(tun) forKey:tunnel_address_preference];
|
|
//[self setInteger: blabla forKey:tunnel_port_preference];
|
|
//[self setString: forKey:@"tunnel_enabled_preference"];
|
|
}
|
|
{
|
|
const LinphoneVideoPolicy *pol;
|
|
[self setBool: linphone_core_video_enabled(lc) forKey:@"enable_video_preference"];
|
|
pol=linphone_core_get_video_policy(lc);
|
|
[self setBool:(pol->automatically_accept && pol->automatically_initiate) forKey:@"start_video_preference"];
|
|
}
|
|
}
|
|
|
|
-(void) setObject:(id)value forKey:(NSString *)key {
|
|
[dict setValue:value forKey:key];
|
|
NSString *changed_value=[[NSString alloc] initWithFormat:@"%@_changed", key];
|
|
[dict setValue:[NSNumber numberWithBool:TRUE] forKey:changed_value];
|
|
[changed_value release];
|
|
}
|
|
|
|
- (id)objectForKey:(NSString*)key {
|
|
return [dict valueForKey:key];
|
|
}
|
|
|
|
- (BOOL)synchronize {
|
|
LinphoneCore *lc=[LinphoneManager getLc];
|
|
LinphoneManager* lLinphoneMgr = [LinphoneManager instance];
|
|
|
|
NSLog(@"Called in SettingsStore synchronize");
|
|
if ([self boolForKey:@"username_preference_changed"])
|
|
NSLog(@"username_preference_changed !!");
|
|
return YES;
|
|
/* unregister before modifying any settings */
|
|
{
|
|
LinphoneProxyConfig* proxyCfg;
|
|
linphone_core_get_default_proxy(lc, &proxyCfg);
|
|
|
|
if (proxyCfg) {
|
|
// this will force unregister WITHOUT destorying the proxyCfg object
|
|
linphone_proxy_config_edit(proxyCfg);
|
|
|
|
int i=0;
|
|
while (linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationNone &&
|
|
linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationCleared &&
|
|
linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationFailed &&
|
|
i++<40 ) {
|
|
linphone_core_iterate(lc);
|
|
usleep(10000);
|
|
}
|
|
}
|
|
}
|
|
|
|
NSString* transport = [self stringForKey:@"transport_preference"];
|
|
|
|
LCSipTransports transportValue;
|
|
if (transport!=nil) {
|
|
if (linphone_core_get_sip_transports(lc, &transportValue)) {
|
|
ms_error("cannot get current transport");
|
|
}
|
|
// Only one port can be set at one time, the others's value is 0
|
|
if ([transport isEqualToString:@"tcp"]) {
|
|
if (transportValue.tcp_port == 0) transportValue.tcp_port=transportValue.udp_port + transportValue.tls_port;
|
|
transportValue.udp_port=0;
|
|
transportValue.tls_port=0;
|
|
} else if ([transport isEqualToString:@"udp"]){
|
|
if (transportValue.udp_port == 0) transportValue.udp_port=transportValue.tcp_port + transportValue.tls_port;
|
|
transportValue.tcp_port=0;
|
|
transportValue.tls_port=0;
|
|
} else if ([transport isEqualToString:@"tls"]){
|
|
if (transportValue.tls_port == 0) transportValue.tls_port=transportValue.udp_port + transportValue.tcp_port;
|
|
transportValue.tcp_port=0;
|
|
transportValue.udp_port=0;
|
|
} else {
|
|
ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
|
}
|
|
if (linphone_core_set_sip_transports(lc, &transportValue)) {
|
|
ms_error("cannot set transport");
|
|
}
|
|
}
|
|
|
|
|
|
//configure sip account
|
|
|
|
//mandatory parameters
|
|
|
|
NSString* username = [self stringForKey:@"username_preference"];
|
|
NSString* domain = [self stringForKey:@"domain_preference"];
|
|
NSString* accountPassword = [self stringForKey:@"password_preference"];
|
|
bool isOutboundProxy= [self boolForKey:@"outbound_proxy_preference"];
|
|
|
|
|
|
//clear auth info list
|
|
linphone_core_clear_all_auth_info(lc);
|
|
//clear existing proxy config
|
|
linphone_core_clear_proxy_config(lc);
|
|
if (username && [username length] >0 && domain && [domain length]>0) {
|
|
const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]];
|
|
const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]];
|
|
|
|
NSString* proxyAddress = [[NSUserDefaults standardUserDefaults] stringForKey:@"proxy_preference"];
|
|
if ((!proxyAddress || [proxyAddress length] <1 ) && domain) {
|
|
proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ;
|
|
} else {
|
|
proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ;
|
|
}
|
|
|
|
const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]];
|
|
|
|
NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"];
|
|
bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"];
|
|
//possible valid config detected
|
|
LinphoneProxyConfig* proxyCfg;
|
|
proxyCfg = linphone_proxy_config_new();
|
|
|
|
// add username password
|
|
LinphoneAddress *from = linphone_address_new(identity);
|
|
LinphoneAuthInfo *info;
|
|
if (from !=0){
|
|
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL);
|
|
linphone_core_add_auth_info(lc,info);
|
|
}
|
|
linphone_address_destroy(from);
|
|
|
|
// configure proxy entries
|
|
linphone_proxy_config_set_identity(proxyCfg,identity);
|
|
linphone_proxy_config_set_server_addr(proxyCfg,proxy);
|
|
linphone_proxy_config_enable_register(proxyCfg,true);
|
|
BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"];
|
|
|
|
if (isWifiOnly && lLinphoneMgr.connectivity == wwan) {
|
|
linphone_proxy_config_expires(proxyCfg, 0);
|
|
} else {
|
|
linphone_proxy_config_expires(proxyCfg, lLinphoneMgr.defaultExpires);
|
|
}
|
|
|
|
if (isOutboundProxy)
|
|
linphone_proxy_config_set_route(proxyCfg,proxy);
|
|
|
|
if ([prefix length]>0) {
|
|
linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
|
}
|
|
linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00);
|
|
|
|
linphone_core_add_proxy_config(lc,proxyCfg);
|
|
//set to default proxy
|
|
linphone_core_set_default_proxy(lc,proxyCfg);
|
|
|
|
}
|
|
|
|
//Configure Codecs
|
|
|
|
PayloadType *pt;
|
|
const MSList *elem;
|
|
//disable all codecs
|
|
for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){
|
|
pt=(PayloadType*)elem->data;
|
|
linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]);
|
|
}
|
|
for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){
|
|
pt=(PayloadType*)elem->data;
|
|
linphone_core_enable_payload_type(lc,pt,[self boolForKey: getPrefForCodec(pt->mime_type,pt->clock_rate)]);
|
|
}
|
|
|
|
bool enableVideo = [self boolForKey:@"enable_video_preference"];
|
|
linphone_core_enable_video(lc, enableVideo, enableVideo);
|
|
|
|
NSString *menc = [self stringForKey:@"media_encryption_preference"];
|
|
if (menc && [menc compare:@"SRTP"])
|
|
linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP);
|
|
else if (menc && [menc compare:@"ZRTP"])
|
|
linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP);
|
|
else linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone);
|
|
|
|
NSString* stun_server = [self stringForKey:@"stun_preference"];
|
|
if ([stun_server length]>0){
|
|
linphone_core_set_stun_server(lc,[stun_server cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
|
linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun);
|
|
}else{
|
|
linphone_core_set_stun_server(lc, NULL);
|
|
linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall);
|
|
}
|
|
|
|
LinphoneVideoPolicy policy;
|
|
policy.automatically_accept = [self boolForKey:@"start_video_preference"];;
|
|
policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
|
|
linphone_core_set_video_policy(lc, &policy);
|
|
|
|
UIDevice* device = [UIDevice currentDevice];
|
|
bool backgroundSupported = false;
|
|
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
|
|
backgroundSupported = [device isMultitaskingSupported];
|
|
BOOL isbackgroundModeEnabled;
|
|
if (backgroundSupported) {
|
|
isbackgroundModeEnabled = [self boolForKey:@"backgroundmode_preference"];
|
|
} else {
|
|
isbackgroundModeEnabled=false;
|
|
}
|
|
lp_config_set_int(linphone_core_get_config(lc),"app","backgroundmode_preference",backgroundSupported);
|
|
return YES;
|
|
}
|
|
|
|
@end
|