mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Merge branch 'master' into dev_group_chat
This commit is contained in:
commit
de83815249
12 changed files with 269 additions and 284 deletions
|
|
@ -95,9 +95,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
- (void)update {
|
||||
const LinphoneAddress *addr = linphone_call_get_remote_address(_call);
|
||||
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
|
||||
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr withAddressLabel:_addressLabel];
|
||||
char *uri = linphone_address_as_string_uri_only(addr);
|
||||
_addressLabel.text = [NSString stringWithUTF8String:uri];
|
||||
ms_free(uri);
|
||||
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:YES withRoundedRadius:YES];
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
|
||||
const LinphoneAddress *addr = linphone_call_get_remote_address(call);
|
||||
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
|
||||
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr withAddressLabel:_addressLabel];
|
||||
char *uri = linphone_address_as_string_uri_only(addr);
|
||||
_addressLabel.text = [NSString stringWithUTF8String:uri];
|
||||
ms_free(uri);
|
||||
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,27 @@
|
|||
|
||||
@property(nonatomic, strong) NSMutableDictionary *contacts;
|
||||
@property(nonatomic, strong) NSDictionary *allContacts;
|
||||
@property(nonatomic, strong) NSArray *sortedKeys;
|
||||
@property(nonatomic, strong) NSArray *sortedAddresses;
|
||||
@end
|
||||
|
||||
@implementation ChatConversationCreateTableView
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
_allContacts =
|
||||
[[NSDictionary alloc] initWithDictionary:LinphoneManager.instance.fastAddressBook.addressBookMap];
|
||||
|
||||
self.allContacts = [[NSMutableDictionary alloc] initWithDictionary:LinphoneManager.instance.fastAddressBook.addressBookMap];
|
||||
self.sortedKeys = [[LinphoneManager.instance.fastAddressBook.addressBookMap allKeys] sortedArrayUsingSelector: @selector(compare:)];
|
||||
self.sortedAddresses = [[LinphoneManager.instance.fastAddressBook.addressBookMap allKeys] sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
|
||||
Contact* first = [_allContacts objectForKey:a];
|
||||
Contact* second = [_allContacts objectForKey:b];
|
||||
|
||||
if([[first.firstName lowercaseString] compare:[second.firstName lowercaseString]] == NSOrderedSame)
|
||||
return [[first.lastName lowercaseString] compare:[second.lastName lowercaseString]];
|
||||
else
|
||||
return [[first.firstName lowercaseString] compare:[second.firstName lowercaseString]];
|
||||
}];
|
||||
|
||||
if(_notFirstTime) {
|
||||
for(NSString *addr in _contactsGroup) {
|
||||
[_collectionView registerClass:UIChatCreateCollectionViewCell.class forCellWithReuseIdentifier:addr];
|
||||
|
|
@ -33,6 +46,7 @@
|
|||
_contacts = [[NSMutableDictionary alloc] initWithCapacity:_allContacts.count];
|
||||
_contactsGroup = [[NSMutableArray alloc] init];
|
||||
_allFilter = TRUE;
|
||||
|
||||
[_searchBar setText:@""];
|
||||
[self searchBar:_searchBar textDidChange:_searchBar.text];
|
||||
self.tableView.accessibilityIdentifier = @"Suggested addresses";
|
||||
|
|
@ -77,7 +91,7 @@
|
|||
else
|
||||
_contacts = [[NSMutableDictionary alloc] initWithCapacity:_allContacts.count];
|
||||
|
||||
[_allContacts enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
|
||||
for (NSString* key in _sortedAddresses){
|
||||
NSString *address = (NSString *)key;
|
||||
NSString *name = [FastAddressBook displayNameForContact:value];
|
||||
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:address];
|
||||
|
|
@ -90,7 +104,8 @@
|
|||
|| ([address.lowercaseString containsSubstring:filter.lowercaseString]))
|
||||
&& add)
|
||||
[_contacts setObject:name forKey:address];
|
||||
}];
|
||||
}
|
||||
|
||||
// also add current entry, if not listed
|
||||
NSString *nsuri = filter.lowercaseString;
|
||||
LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:nsuri];
|
||||
|
|
@ -122,15 +137,21 @@
|
|||
if (cell == nil) {
|
||||
cell = [[UIChatCreateCell alloc] initWithIdentifier:kCellId];
|
||||
}
|
||||
|
||||
cell.displayNameLabel.text = [_contacts.allValues objectAtIndex:indexPath.row];
|
||||
NSString *key = [_contacts.allKeys objectAtIndex:indexPath.row];
|
||||
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:key];
|
||||
Boolean linphoneContact = [FastAddressBook contactHasValidSipDomain:contact]
|
||||
|| (contact.friend && linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(contact.friend)) == LinphonePresenceBasicStatusOpen);
|
||||
cell.linphoneImage.hidden = !linphoneContact;
|
||||
cell.addressLabel.text = key;
|
||||
LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:[_sortedAddresses objectAtIndex:indexPath.row]];
|
||||
cell.displayNameLabel.text = [_contacts objectForKey:[_sortedAddresses objectAtIndex:indexPath.row]];
|
||||
if (addr) {
|
||||
cell.addressLabel.text = [NSString stringWithUTF8String:linphone_address_as_string(addr)];
|
||||
} else {
|
||||
cell.addressLabel.text = [_contacts.allKeys objectAtIndex:indexPath.row];
|
||||
}
|
||||
cell.selectedImage.hidden = ![_contactsGroup containsObject:cell.addressLabel.text];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
if ([_person respondsToSelector:NSSelectorFromString( CNInstantMessageAddressUsernameKey)] || [_person respondsToSelector:NSSelectorFromString(CNContactInstantMessageAddressesKey)]) {
|
||||
if (_person.instantMessageAddresses != NULL) {
|
||||
for (CNLabeledValue<CNInstantMessageAddress *> *sipAddr in _person.instantMessageAddresses) {
|
||||
[_sipAddresses addObject:sipAddr.value.username];
|
||||
NSString *username = sipAddr.value.username;
|
||||
if (username)
|
||||
[_sipAddresses addObject:username];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,8 +204,7 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
[_videoCameraSwitch setHidden:TRUE];
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
} @catch (NSException *exception) {
|
||||
if ([exception.name isEqualToString:@"LinphoneCoreException"]) {
|
||||
LOGE(@"Core already destroyed");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -144,10 +144,9 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog);
|
||||
_addContactButton.hidden = ([FastAddressBook getContactWithAddress:addr] != nil);
|
||||
[ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr];
|
||||
[ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr withAddressLabel:_addressLabel];
|
||||
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
|
||||
char *addrURI = linphone_address_as_string_uri_only(addr);
|
||||
_addressLabel.text = [NSString stringWithUTF8String:addrURI];
|
||||
ms_free(addrURI);
|
||||
|
||||
[_tableView loadDataForAddress:(callLog ? linphone_call_log_get_remote_address(callLog) : NULL)];
|
||||
|
|
|
|||
|
|
@ -651,11 +651,10 @@
|
|||
}
|
||||
|
||||
- (BOOL)synchronize {
|
||||
//@try {
|
||||
@try {
|
||||
LinphoneManager *lm = LinphoneManager.instance;
|
||||
|
||||
LinphoneManager *lm = LinphoneManager.instance;
|
||||
// root section
|
||||
{
|
||||
// root section
|
||||
BOOL account_changed = NO;
|
||||
for (NSString *key in self->changedDict) {
|
||||
if ([key hasPrefix:@"account_"] && [self valueChangedForKey:key]) {
|
||||
|
|
@ -676,10 +675,8 @@
|
|||
|
||||
bool enableAutoAnswer = [self boolForKey:@"enable_auto_answer_preference"];
|
||||
[LinphoneManager.instance lpConfigSetBool:enableAutoAnswer forKey:@"auto_answer"];
|
||||
}
|
||||
|
||||
// audio section
|
||||
{
|
||||
// audio section
|
||||
[self synchronizeCodecs:linphone_core_get_audio_codecs(LC)];
|
||||
|
||||
float playback_gain = [self floatForKey:@"playback_gain_preference"];
|
||||
|
|
@ -701,256 +698,222 @@
|
|||
[LinphoneManager.instance configureVbrCodecs];
|
||||
|
||||
NSString *au_device = @"AU: Audio Unit Receiver";
|
||||
if (!voice_processing) {
|
||||
if (!voice_processing)
|
||||
au_device = @"AU: Audio Unit NoVoiceProc";
|
||||
}
|
||||
|
||||
linphone_core_set_capture_device(LC, [au_device UTF8String]);
|
||||
linphone_core_set_playback_device(LC, [au_device UTF8String]);
|
||||
}
|
||||
|
||||
// video section
|
||||
{
|
||||
[self synchronizeCodecs:linphone_core_get_video_codecs(LC)];
|
||||
[self synchronizeCodecs:linphone_core_get_video_codecs(LC)];
|
||||
|
||||
LinphoneVideoPolicy policy;
|
||||
policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
|
||||
policy.automatically_accept = [self boolForKey:@"accept_video_preference"];
|
||||
linphone_core_set_video_policy(LC, &policy);
|
||||
linphone_core_enable_self_view(LC, [self boolForKey:@"self_video_preference"]);
|
||||
BOOL preview_preference = IPAD && [self boolForKey:@"preview_preference"];
|
||||
[lm lpConfigSetInt:preview_preference forKey:@"preview_preference"];
|
||||
LinphoneVideoPolicy policy;
|
||||
policy.automatically_initiate = [self boolForKey:@"start_video_preference"];
|
||||
policy.automatically_accept = [self boolForKey:@"accept_video_preference"];
|
||||
linphone_core_set_video_policy(LC, &policy);
|
||||
linphone_core_enable_self_view(LC, [self boolForKey:@"self_video_preference"]);
|
||||
BOOL preview_preference = IPAD && [self boolForKey:@"preview_preference"];
|
||||
[lm lpConfigSetInt:preview_preference forKey:@"preview_preference"];
|
||||
|
||||
NSString *videoPreset = [self stringForKey:@"video_preset_preference"];
|
||||
linphone_core_set_video_preset(LC, [videoPreset UTF8String]);
|
||||
MSVideoSize vsize;
|
||||
switch ([self integerForKey:@"video_preferred_size_preference"]) {
|
||||
case 0:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, 720P);
|
||||
break;
|
||||
case 1:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, VGA);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, QVGA);
|
||||
break;
|
||||
}
|
||||
linphone_core_set_preferred_video_size(LC, vsize);
|
||||
if (![videoPreset isEqualToString:@"custom"]) {
|
||||
[self setInteger:0 forKey:@"video_preferred_fps_preference"];
|
||||
[self setInteger:0 forKey:@"download_bandwidth_preference"];
|
||||
}
|
||||
linphone_core_set_preferred_framerate(LC, [self integerForKey:@"video_preferred_fps_preference"]);
|
||||
linphone_core_set_download_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
|
||||
linphone_core_set_upload_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
|
||||
NSString *videoPreset = [self stringForKey:@"video_preset_preference"];
|
||||
linphone_core_set_video_preset(LC, [videoPreset UTF8String]);
|
||||
MSVideoSize vsize;
|
||||
switch ([self integerForKey:@"video_preferred_size_preference"]) {
|
||||
case 0:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, 720P);
|
||||
break;
|
||||
case 1:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, VGA);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
MS_VIDEO_SIZE_ASSIGN(vsize, QVGA);
|
||||
break;
|
||||
}
|
||||
linphone_core_set_preferred_video_size(LC, vsize);
|
||||
if (![videoPreset isEqualToString:@"custom"]) {
|
||||
[self setInteger:0 forKey:@"video_preferred_fps_preference"];
|
||||
[self setInteger:0 forKey:@"download_bandwidth_preference"];
|
||||
}
|
||||
linphone_core_set_preferred_framerate(LC, [self integerForKey:@"video_preferred_fps_preference"]);
|
||||
linphone_core_set_download_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
|
||||
linphone_core_set_upload_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
|
||||
|
||||
// call section
|
||||
{
|
||||
linphone_core_set_use_rfc2833_for_dtmf(LC, [self boolForKey:@"rfc_dtmf_preference"]);
|
||||
linphone_core_set_use_info_for_dtmf(LC, [self boolForKey:@"sipinfo_dtmf_preference"]);
|
||||
linphone_core_set_inc_timeout(LC, [self integerForKey:@"incoming_call_timeout_preference"]);
|
||||
linphone_core_set_in_call_timeout(LC, [self integerForKey:@"in_call_timeout_preference"]);
|
||||
[lm lpConfigSetString:[self stringForKey:@"voice_mail_uri_preference"] forKey:@"voice_mail_uri"];
|
||||
[lm lpConfigSetBool:[self boolForKey:@"repeat_call_notification_preference"]
|
||||
forKey:@"repeat_call_notification"];
|
||||
}
|
||||
linphone_core_set_use_rfc2833_for_dtmf(LC, [self boolForKey:@"rfc_dtmf_preference"]);
|
||||
linphone_core_set_use_info_for_dtmf(LC, [self boolForKey:@"sipinfo_dtmf_preference"]);
|
||||
linphone_core_set_inc_timeout(LC, [self integerForKey:@"incoming_call_timeout_preference"]);
|
||||
linphone_core_set_in_call_timeout(LC, [self integerForKey:@"in_call_timeout_preference"]);
|
||||
[lm lpConfigSetString:[self stringForKey:@"voice_mail_uri_preference"] forKey:@"voice_mail_uri"];
|
||||
[lm lpConfigSetBool:[self boolForKey:@"repeat_call_notification_preference"] forKey:@"repeat_call_notification"];
|
||||
|
||||
// chat section
|
||||
{
|
||||
int val = [self integerForKey:@"use_lime_preference"];
|
||||
linphone_core_enable_lime(LC, val);
|
||||
if (val == LinphoneLimeMandatory &&
|
||||
(linphone_core_get_media_encryption(LC) != LinphoneMediaEncryptionZRTP)) {
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP);
|
||||
[self setCString:"ZRTP" forKey:@"media_encryption_preference"];
|
||||
UIAlertController *errView = [UIAlertController
|
||||
alertControllerWithTitle:NSLocalizedString(@"ZRTP activation", nil)
|
||||
message:
|
||||
NSLocalizedString(
|
||||
@"LIME requires ZRTP encryption.\n"
|
||||
@"By activating LIME you automatically activate ZRTP media encryption.",
|
||||
nil)
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
int val = [self integerForKey:@"use_lime_preference"];
|
||||
linphone_core_enable_lime(LC, val);
|
||||
if (val == LinphoneLimeMandatory && (linphone_core_get_media_encryption(LC) != LinphoneMediaEncryptionZRTP)) {
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP);
|
||||
[self setCString:"ZRTP" forKey:@"media_encryption_preference"];
|
||||
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"ZRTP activation", nil)
|
||||
message:NSLocalizedString(@"LIME requires ZRTP encryption.\n"
|
||||
@"By activating LIME you automatically activate ZRTP media encryption.",
|
||||
nil)
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action){
|
||||
}];
|
||||
[errView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
}
|
||||
linphone_core_set_file_transfer_server(
|
||||
LC, [[self stringForKey:@"file_transfer_server_url_preference"] UTF8String]);
|
||||
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action){}];
|
||||
[errView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
}
|
||||
linphone_core_set_file_transfer_server(LC, [self stringForKey:@"file_transfer_server_url_preference"].UTF8String);
|
||||
|
||||
// network section
|
||||
{
|
||||
BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
|
||||
[lm lpConfigSetInt:edgeOpt forKey:@"edge_opt_preference"];
|
||||
BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"];
|
||||
[lm lpConfigSetInt:edgeOpt forKey:@"edge_opt_preference"];
|
||||
|
||||
BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"];
|
||||
[lm lpConfigSetInt:wifiOnly forKey:@"wifi_only_preference"];
|
||||
if ([self valueChangedForKey:@"wifi_only_preference"]) {
|
||||
[LinphoneManager.instance setupNetworkReachabilityCallback];
|
||||
BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"];
|
||||
[lm lpConfigSetInt:wifiOnly forKey:@"wifi_only_preference"];
|
||||
if ([self valueChangedForKey:@"wifi_only_preference"])
|
||||
[LinphoneManager.instance setupNetworkReachabilityCallback];
|
||||
|
||||
LinphoneNatPolicy *LNP = linphone_core_get_nat_policy(LC);
|
||||
NSString *stun_server = [self stringForKey:@"stun_preference"];
|
||||
if ([stun_server length] > 0) {
|
||||
linphone_core_set_stun_server(LC, [stun_server UTF8String]);
|
||||
linphone_nat_policy_set_stun_server(LNP, [stun_server UTF8String]);
|
||||
BOOL ice_preference = [self boolForKey:@"ice_preference"];
|
||||
linphone_nat_policy_enable_ice(LNP, ice_preference);
|
||||
linphone_nat_policy_enable_turn(LNP, [self boolForKey:@"turn_preference"]);
|
||||
NSString *turn_username = [self stringForKey:@"turn_username"];
|
||||
NSString *turn_password = [self stringForKey:@"turn_password"];
|
||||
|
||||
if ([turn_username length] > 0) {
|
||||
const LinphoneAuthInfo *turnAuthInfo = nil;
|
||||
if ([turn_password length] > 0){
|
||||
turnAuthInfo = linphone_auth_info_new([turn_username UTF8String], NULL, [turn_password UTF8String], NULL, NULL, NULL);
|
||||
linphone_core_add_auth_info(LC, turnAuthInfo);
|
||||
} else
|
||||
turnAuthInfo = linphone_core_find_auth_info(LC, NULL, [turn_username UTF8String], NULL);
|
||||
|
||||
linphone_nat_policy_set_stun_server_username(LNP, [turn_username UTF8String]);
|
||||
}
|
||||
|
||||
LinphoneNatPolicy *LNP = linphone_core_get_nat_policy(LC);
|
||||
NSString *stun_server = [self stringForKey:@"stun_preference"];
|
||||
if ([stun_server length] > 0) {
|
||||
linphone_core_set_stun_server(LC, [stun_server UTF8String]);
|
||||
linphone_nat_policy_set_stun_server(LNP, [stun_server UTF8String]);
|
||||
BOOL ice_preference = [self boolForKey:@"ice_preference"];
|
||||
linphone_nat_policy_enable_ice(LNP, ice_preference);
|
||||
linphone_nat_policy_enable_turn(LNP, [self boolForKey:@"turn_preference"]);
|
||||
NSString *turn_username = [self stringForKey:@"turn_username"];
|
||||
NSString *turn_password = [self stringForKey:@"turn_password"];
|
||||
|
||||
if ([turn_username length] > 0) {
|
||||
const LinphoneAuthInfo *turnAuthInfo = nil;
|
||||
if ([turn_password length] > 0){
|
||||
turnAuthInfo = linphone_auth_info_new([turn_username UTF8String], NULL,
|
||||
[turn_password UTF8String], NULL, NULL, NULL);
|
||||
linphone_core_add_auth_info(LC, turnAuthInfo);
|
||||
}else{
|
||||
turnAuthInfo = linphone_core_find_auth_info(LC, NULL, [turn_username UTF8String], NULL);
|
||||
}
|
||||
linphone_nat_policy_set_stun_server_username(LNP, [turn_username UTF8String]);
|
||||
}
|
||||
} else {
|
||||
linphone_nat_policy_enable_stun(LNP, FALSE);
|
||||
linphone_nat_policy_set_stun_server(LNP, NULL);
|
||||
linphone_core_set_stun_server(LC, NULL);
|
||||
}
|
||||
linphone_core_set_nat_policy(LC, LNP);
|
||||
{
|
||||
NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"];
|
||||
int minPort, maxPort;
|
||||
[LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&minPort maxPort:&maxPort];
|
||||
linphone_core_set_audio_port_range(LC, minPort, maxPort);
|
||||
}
|
||||
{
|
||||
NSString *video_port_preference = [self stringForKey:@"video_port_preference"];
|
||||
int minPort, maxPort;
|
||||
[LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&minPort maxPort:&maxPort];
|
||||
|
||||
linphone_core_set_video_port_range(LC, minPort, maxPort);
|
||||
}
|
||||
|
||||
NSString *menc = [self stringForKey:@"media_encryption_preference"];
|
||||
if (menc && [menc compare:@"SRTP"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionSRTP);
|
||||
else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP);
|
||||
else if (menc && [menc compare:@"DTLS"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionDTLS);
|
||||
else
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionNone);
|
||||
|
||||
linphone_core_enable_adaptive_rate_control(LC, [self boolForKey:@"adaptive_rate_control_preference"]);
|
||||
} else {
|
||||
linphone_nat_policy_enable_stun(LNP, FALSE);
|
||||
linphone_nat_policy_set_stun_server(LNP, NULL);
|
||||
linphone_core_set_stun_server(LC, NULL);
|
||||
}
|
||||
linphone_core_set_nat_policy(LC, LNP);
|
||||
|
||||
NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"];
|
||||
int audioMinPort, audioMaxPort;
|
||||
[LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&audioMinPort maxPort:&audioMaxPort];
|
||||
linphone_core_set_audio_port_range(LC, audioMinPort, audioMaxPort);
|
||||
|
||||
NSString *video_port_preference = [self stringForKey:@"video_port_preference"];
|
||||
int videoMinPort, videoMaxPort;
|
||||
[LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&videoMinPort maxPort:&videoMaxPort];
|
||||
linphone_core_set_video_port_range(LC, videoMinPort, videoMaxPort);
|
||||
|
||||
NSString *menc = [self stringForKey:@"media_encryption_preference"];
|
||||
if (menc && [menc compare:@"SRTP"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionSRTP);
|
||||
else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP);
|
||||
else if (menc && [menc compare:@"DTLS"] == NSOrderedSame)
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionDTLS);
|
||||
else
|
||||
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionNone);
|
||||
|
||||
linphone_core_enable_adaptive_rate_control(LC, [self boolForKey:@"adaptive_rate_control_preference"]);
|
||||
|
||||
// tunnel section
|
||||
{
|
||||
if (linphone_core_tunnel_available()) {
|
||||
NSString *lTunnelPrefMode = [self stringForKey:@"tunnel_mode_preference"];
|
||||
NSString *lTunnelPrefAddress = [self stringForKey:@"tunnel_address_preference"];
|
||||
int lTunnelPrefPort = [self integerForKey:@"tunnel_port_preference"];
|
||||
LinphoneTunnel *tunnel = linphone_core_get_tunnel(LC);
|
||||
LinphoneTunnelMode mode = LinphoneTunnelModeDisable;
|
||||
int lTunnelPort = 443;
|
||||
if (lTunnelPrefPort) {
|
||||
lTunnelPort = lTunnelPrefPort;
|
||||
}
|
||||
if (linphone_core_tunnel_available()) {
|
||||
NSString *lTunnelPrefMode = [self stringForKey:@"tunnel_mode_preference"];
|
||||
NSString *lTunnelPrefAddress = [self stringForKey:@"tunnel_address_preference"];
|
||||
int lTunnelPrefPort = [self integerForKey:@"tunnel_port_preference"];
|
||||
LinphoneTunnel *tunnel = linphone_core_get_tunnel(LC);
|
||||
LinphoneTunnelMode mode = LinphoneTunnelModeDisable;
|
||||
int lTunnelPort = 443;
|
||||
if (lTunnelPrefPort)
|
||||
lTunnelPort = lTunnelPrefPort;
|
||||
|
||||
linphone_tunnel_clean_servers(tunnel);
|
||||
if (lTunnelPrefAddress && [lTunnelPrefAddress length]) {
|
||||
LinphoneTunnelConfig *ltc = linphone_tunnel_config_new();
|
||||
linphone_tunnel_config_set_host(ltc, [lTunnelPrefAddress UTF8String]);
|
||||
linphone_tunnel_config_set_port(ltc, lTunnelPort);
|
||||
linphone_tunnel_add_server(tunnel, ltc);
|
||||
linphone_tunnel_clean_servers(tunnel);
|
||||
if (lTunnelPrefAddress && [lTunnelPrefAddress length]) {
|
||||
LinphoneTunnelConfig *ltc = linphone_tunnel_config_new();
|
||||
linphone_tunnel_config_set_host(ltc, [lTunnelPrefAddress UTF8String]);
|
||||
linphone_tunnel_config_set_port(ltc, lTunnelPort);
|
||||
linphone_tunnel_add_server(tunnel, ltc);
|
||||
|
||||
if ([lTunnelPrefMode isEqualToString:@"off"]) {
|
||||
mode = LinphoneTunnelModeDisable;
|
||||
} else if ([lTunnelPrefMode isEqualToString:@"on"]) {
|
||||
mode = LinphoneTunnelModeEnable;
|
||||
} else if ([lTunnelPrefMode isEqualToString:@"auto"]) {
|
||||
mode = LinphoneTunnelModeAuto;
|
||||
} else {
|
||||
LOGE(@"Unexpected tunnel mode [%s]", [lTunnelPrefMode UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
[lm lpConfigSetString:lTunnelPrefMode forKey:@"tunnel_mode_preference"];
|
||||
linphone_tunnel_set_mode(tunnel, mode);
|
||||
if ([lTunnelPrefMode isEqualToString:@"off"])
|
||||
mode = LinphoneTunnelModeDisable;
|
||||
else if ([lTunnelPrefMode isEqualToString:@"on"])
|
||||
mode = LinphoneTunnelModeEnable;
|
||||
else if ([lTunnelPrefMode isEqualToString:@"auto"])
|
||||
mode = LinphoneTunnelModeAuto;
|
||||
else
|
||||
LOGE(@"Unexpected tunnel mode [%s]", [lTunnelPrefMode UTF8String]);
|
||||
}
|
||||
|
||||
[lm lpConfigSetString:lTunnelPrefMode forKey:@"tunnel_mode_preference"];
|
||||
linphone_tunnel_set_mode(tunnel, mode);
|
||||
}
|
||||
|
||||
// advanced section
|
||||
{
|
||||
BOOL animations = [self boolForKey:@"animations_preference"];
|
||||
[lm lpConfigSetInt:animations forKey:@"animations_preference"];
|
||||
BOOL animations = [self boolForKey:@"animations_preference"];
|
||||
[lm lpConfigSetInt:animations forKey:@"animations_preference"];
|
||||
|
||||
UIDevice *device = [UIDevice currentDevice];
|
||||
bool backgroundSupported =
|
||||
[device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported];
|
||||
BOOL isbackgroundModeEnabled = backgroundSupported && [self boolForKey:@"backgroundmode_preference"];
|
||||
[lm lpConfigSetInt:isbackgroundModeEnabled forKey:@"backgroundmode_preference"];
|
||||
UIDevice *device = [UIDevice currentDevice];
|
||||
BOOL backgroundSupported = [device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported];
|
||||
BOOL isbackgroundModeEnabled = backgroundSupported && [self boolForKey:@"backgroundmode_preference"];
|
||||
[lm lpConfigSetInt:isbackgroundModeEnabled forKey:@"backgroundmode_preference"];
|
||||
[lm lpConfigSetInt:[self integerForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"];
|
||||
[lm lpConfigSetInt:[self integerForKey:@"autoanswer_notif_preference"] forKey:@"autoanswer_notif_preference"];
|
||||
[lm lpConfigSetInt:[self integerForKey:@"show_msg_in_notif"] forKey:@"show_msg_in_notif"];
|
||||
|
||||
[lm lpConfigSetInt:[self integerForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"];
|
||||
[lm lpConfigSetInt:[self integerForKey:@"autoanswer_notif_preference"]
|
||||
forKey:@"autoanswer_notif_preference"];
|
||||
[lm lpConfigSetInt:[self integerForKey:@"show_msg_in_notif"] forKey:@"show_msg_in_notif"];
|
||||
|
||||
if ([self integerForKey:@"use_rls_presence"]) {
|
||||
[self setInteger:0 forKey:@"use_rls_presence"];
|
||||
NSString *rls_uri =
|
||||
[lm lpConfigStringForKey:@"rls_uri" inSection:@"sip" withDefault:@"sips:rls@sip.linphone.org"];
|
||||
LinphoneAddress *rls_addr = linphone_address_new(rls_uri.UTF8String);
|
||||
const char *rls_domain = linphone_address_get_domain(rls_addr);
|
||||
const MSList *proxies = linphone_core_get_proxy_config_list(LC);
|
||||
if (!proxies) {
|
||||
// Enable it if no proxy config for first launch of app
|
||||
[self setInteger:1 forKey:@"use_rls_presence"];
|
||||
} else {
|
||||
while (proxies) {
|
||||
const char *proxy_domain = linphone_proxy_config_get_domain(proxies->data);
|
||||
if (strcmp(rls_domain, proxy_domain) == 0) {
|
||||
[self setInteger:1 forKey:@"use_rls_presence"];
|
||||
break;
|
||||
}
|
||||
proxies = proxies->next;
|
||||
if ([self integerForKey:@"use_rls_presence"]) {
|
||||
[self setInteger:0 forKey:@"use_rls_presence"];
|
||||
NSString *rls_uri = [lm lpConfigStringForKey:@"rls_uri" inSection:@"sip" withDefault:@"sips:rls@sip.linphone.org"];
|
||||
LinphoneAddress *rls_addr = linphone_address_new(rls_uri.UTF8String);
|
||||
const char *rls_domain = linphone_address_get_domain(rls_addr);
|
||||
const MSList *proxies = linphone_core_get_proxy_config_list(LC);
|
||||
if (!proxies) // Enable it if no proxy config for first launch of app
|
||||
[self setInteger:1 forKey:@"use_rls_presence"];
|
||||
else {
|
||||
while (proxies) {
|
||||
const char *proxy_domain = linphone_proxy_config_get_domain(proxies->data);
|
||||
if (strcmp(rls_domain, proxy_domain) == 0) {
|
||||
[self setInteger:1 forKey:@"use_rls_presence"];
|
||||
break;
|
||||
}
|
||||
proxies = proxies->next;
|
||||
}
|
||||
linphone_address_unref(rls_addr);
|
||||
}
|
||||
[lm lpConfigSetInt:[self integerForKey:@"use_rls_presence"] forKey:@"use_rls_presence"];
|
||||
|
||||
const MSList *lists = linphone_core_get_friends_lists(LC);
|
||||
while (lists) {
|
||||
linphone_friend_list_enable_subscriptions(lists->data, [self integerForKey:@"use_rls_presence"]);
|
||||
lists = lists->next;
|
||||
}
|
||||
|
||||
BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
|
||||
[lm lpConfigSetInt:firstloginview forKey:@"enable_first_login_view_preference"];
|
||||
|
||||
NSString *displayname = [self stringForKey:@"primary_displayname_preference"];
|
||||
NSString *username = [self stringForKey:@"primary_username_preference"];
|
||||
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(LC);
|
||||
if (parsed != NULL) {
|
||||
linphone_address_set_display_name(parsed, [displayname UTF8String]);
|
||||
linphone_address_set_username(parsed, [username UTF8String]);
|
||||
char *contact = linphone_address_as_string(parsed);
|
||||
linphone_core_set_primary_contact(LC, contact);
|
||||
ms_free(contact);
|
||||
linphone_address_destroy(parsed);
|
||||
}
|
||||
|
||||
[lm lpConfigSetInt:[self integerForKey:@"account_mandatory_advanced_preference"]
|
||||
forKey:@"account_mandatory_advanced_preference"];
|
||||
linphone_address_unref(rls_addr);
|
||||
}
|
||||
|
||||
[lm lpConfigSetInt:[self integerForKey:@"use_rls_presence"] forKey:@"use_rls_presence"];
|
||||
const MSList *lists = linphone_core_get_friends_lists(LC);
|
||||
while (lists) {
|
||||
linphone_friend_list_enable_subscriptions(lists->data, [self integerForKey:@"use_rls_presence"]);
|
||||
lists = lists->next;
|
||||
}
|
||||
|
||||
BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"];
|
||||
[lm lpConfigSetInt:firstloginview forKey:@"enable_first_login_view_preference"];
|
||||
|
||||
NSString *displayname = [self stringForKey:@"primary_displayname_preference"];
|
||||
NSString *username = [self stringForKey:@"primary_username_preference"];
|
||||
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(LC);
|
||||
if (parsed != NULL) {
|
||||
linphone_address_set_display_name(parsed, [displayname UTF8String]);
|
||||
linphone_address_set_username(parsed, [username UTF8String]);
|
||||
char *contact = linphone_address_as_string(parsed);
|
||||
linphone_core_set_primary_contact(LC, contact);
|
||||
ms_free(contact);
|
||||
linphone_address_destroy(parsed);
|
||||
}
|
||||
[lm lpConfigSetInt:[self integerForKey:@"account_mandatory_advanced_preference"] forKey:@"account_mandatory_advanced_preference"];
|
||||
|
||||
changedDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Post event
|
||||
|
|
@ -958,11 +921,16 @@
|
|||
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneSettingsUpdate object:self userInfo:eventDic];
|
||||
|
||||
return YES;
|
||||
//} @catch (NSException *e) {
|
||||
// // may happen when application is terminated, since we are destroying the core
|
||||
// LOGI(@"Core probably already destroyed, cannot synchronize settings. Skipping. %@", [e callStackSymbols]);
|
||||
//}
|
||||
// return NO;
|
||||
} @catch (NSException *exception) {
|
||||
// may happen when application is terminated, since we are destroying the core
|
||||
if ([exception.name isEqualToString:@"LinphoneCoreException"]) {
|
||||
LOGE(@"Core already destroyed, settings not synchronized");
|
||||
return NO;
|
||||
}
|
||||
LOGE(@"Uncaught exception : %@", exception.description);
|
||||
abort();
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)removeAccount {
|
||||
|
|
|
|||
|
|
@ -734,25 +734,15 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
|
|||
|| linphone_call_log_get_status(UNlog) == LinphoneCallMissed
|
||||
|| linphone_call_log_get_status(UNlog) == LinphoneCallAborted
|
||||
|| linphone_call_log_get_status(UNlog) == LinphoneCallEarlyAborted)) {
|
||||
UNMutableNotificationContent *missed_content =
|
||||
[[UNMutableNotificationContent alloc] init];
|
||||
UNMutableNotificationContent *missed_content = [[UNMutableNotificationContent alloc] init];
|
||||
missed_content.title = NSLocalizedString(@"Missed call", nil);
|
||||
missed_content.body = address;
|
||||
UNNotificationRequest *missed_req = [UNNotificationRequest requestWithIdentifier:@"call_request"
|
||||
content:missed_content
|
||||
trigger:NULL];
|
||||
[[UNUserNotificationCenter currentNotificationCenter]
|
||||
addNotificationRequest:missed_req
|
||||
withCompletionHandler:^(
|
||||
NSError *_Nullable error) {
|
||||
// Enable or disable features based on
|
||||
// authorization.
|
||||
if (error) {
|
||||
LOGD(@"Error while adding "
|
||||
@"notification request :");
|
||||
LOGD(error.description);
|
||||
}
|
||||
}];
|
||||
[UNUserNotificationCenter.currentNotificationCenter addNotificationRequest:missed_req
|
||||
withCompletionHandler:^(NSError *_Nullable error)
|
||||
{if (error) LOGD(@"Error while adding notification request : %@", error.description);}];
|
||||
}
|
||||
linphone_core_set_network_reachable(LC, FALSE);
|
||||
LinphoneManager.instance.connectivity = none;
|
||||
|
|
@ -764,30 +754,25 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
|
|||
: @"";
|
||||
NSUUID *uuid = (NSUUID *)[self.providerDelegate.uuids objectForKey:callId2];
|
||||
if (uuid) {
|
||||
if (linphone_core_get_calls_nb(LC) > 0 && !_conf) {
|
||||
LinphoneCall *callKit_call = (LinphoneCall *)linphone_core_get_calls(LC)
|
||||
? linphone_core_get_calls(LC)->data
|
||||
: NULL;
|
||||
const char *callKit_callId = callKit_call
|
||||
? linphone_call_log_get_call_id(linphone_call_get_call_log(callKit_call))
|
||||
: NULL;
|
||||
if (callKit_callId && !_conf) {
|
||||
// Create a CallKit call because there's not !
|
||||
_conf = FALSE;
|
||||
LinphoneCall *callKit_call = (LinphoneCall *)linphone_core_get_calls(LC)->data;
|
||||
NSString *callKit_callId = [NSString stringWithUTF8String:
|
||||
linphone_call_log_get_call_id(linphone_call_get_call_log(callKit_call))];
|
||||
NSString *callKit_callIdNS = [NSString stringWithUTF8String:callKit_callId];
|
||||
NSUUID *callKit_uuid = [NSUUID UUID];
|
||||
[LinphoneManager.instance.providerDelegate.uuids setObject:callKit_uuid
|
||||
forKey:callKit_callId];
|
||||
[LinphoneManager.instance.providerDelegate.calls setObject:callKit_callId
|
||||
forKey:callKit_uuid];
|
||||
NSString *address = [FastAddressBook displayNameForAddress:
|
||||
linphone_call_get_remote_address(callKit_call)];
|
||||
CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric
|
||||
value:address];
|
||||
CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:callKit_uuid
|
||||
handle:handle];
|
||||
[LinphoneManager.instance.providerDelegate.uuids setObject:callKit_uuid forKey:callKit_callIdNS];
|
||||
[LinphoneManager.instance.providerDelegate.calls setObject:callKit_callIdNS forKey:callKit_uuid];
|
||||
NSString *address = [FastAddressBook displayNameForAddress:linphone_call_get_remote_address(callKit_call)];
|
||||
CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
|
||||
CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:callKit_uuid handle:handle];
|
||||
CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
|
||||
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr
|
||||
completion:^(NSError *err){}];
|
||||
[LinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid
|
||||
startedConnectingAtDate:nil];
|
||||
[LinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid
|
||||
connectedAtDate:nil];
|
||||
[LinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
|
||||
[LinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid startedConnectingAtDate:nil];
|
||||
[LinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid connectedAtDate:nil];
|
||||
}
|
||||
|
||||
CXEndCallAction *act = [[CXEndCallAction alloc] initWithCallUUID:uuid];
|
||||
|
|
@ -858,8 +843,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
|
|||
if (state == LinphoneCallConnected && !mCallCenter) {
|
||||
/*only register CT call center CB for connected call*/
|
||||
[self setupGSMInteraction];
|
||||
if (!_bluetoothEnabled)
|
||||
[self setSpeakerEnabled:FALSE];
|
||||
[[UIDevice currentDevice] setProximityMonitoringEnabled:!(_speakerEnabled || _bluetoothEnabled)];
|
||||
}
|
||||
|
||||
// Post event
|
||||
|
|
@ -1577,7 +1561,7 @@ static void networkReachabilityNotification(CFNotificationCenterRef center, void
|
|||
return;
|
||||
|
||||
|
||||
if (newSSID != Nil && newSSID.length > 0 && mgr.SSID != Nil && newSSID.length > 0){
|
||||
if (newSSID != Nil && newSSID.length > 0 && mgr.SSID != Nil && newSSID.length > 0) {
|
||||
if (SCNetworkReachabilityGetFlags([mgr getProxyReachability], &flags)) {
|
||||
LOGI(@"Wifi SSID changed, resesting transports.");
|
||||
mgr.connectivity=none; //this will trigger a connectivity change in networkReachabilityCallback.
|
||||
|
|
@ -1585,8 +1569,6 @@ static void networkReachabilityNotification(CFNotificationCenterRef center, void
|
|||
}
|
||||
}
|
||||
mgr.SSID = newSSID;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *nilCtx) {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ typedef enum {
|
|||
@interface ContactDisplay : NSObject
|
||||
+ (void)setDisplayNameLabel:(UILabel *)label forContact:(Contact *)contact;
|
||||
+ (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr;
|
||||
+ (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr withAddressLabel:(UILabel*)addressLabel;
|
||||
@end
|
||||
|
||||
#import <UIKit/UIColor.h>
|
||||
|
|
|
|||
|
|
@ -571,6 +571,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr withAddressLabel:(UILabel*)addressLabel{
|
||||
Contact *contact = [FastAddressBook getContactWithAddress:addr];
|
||||
if (contact) {
|
||||
[ContactDisplay setDisplayNameLabel:label forContact:contact];
|
||||
} else {
|
||||
label.text = [FastAddressBook displayNameForAddress:addr];
|
||||
}
|
||||
if([LinphoneManager.instance lpConfigStringForKey:@"display_phone_only" inSection:@"app"])
|
||||
addressLabel.text = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(addr)];
|
||||
else
|
||||
addressLabel.hidden = TRUE;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIImage (squareCrop)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ start_at_boot_preference=1
|
|||
stun_preference=stun.linphone.org
|
||||
voiceproc_preference=1
|
||||
repeat_call_notification=1
|
||||
display_phone_only=0
|
||||
|
||||
[in_app_purchase]
|
||||
#set to 1 if in-app purchases are to be shown in the application
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 798c9502ff56468674a7d0b7167188ea30f22a8a
|
||||
Subproject commit 3a39020f81be240c14aa21a1ac24d741ada86404
|
||||
Loading…
Add table
Reference in a new issue